curl --request POST \
--url https://api.botshield.ai/operations/secured-accounts/revoke \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"platform_user_ref": "<string>",
"handle": "<string>"
}
'import requests
url = "https://api.botshield.ai/operations/secured-accounts/revoke"
payload = {
"platform_user_ref": "<string>",
"handle": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({platform_user_ref: '<string>', handle: '<string>'})
};
fetch('https://api.botshield.ai/operations/secured-accounts/revoke', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.botshield.ai/operations/secured-accounts/revoke",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'platform_user_ref' => '<string>',
'handle' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.botshield.ai/operations/secured-accounts/revoke"
payload := strings.NewReader("{\n \"platform_user_ref\": \"<string>\",\n \"handle\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.botshield.ai/operations/secured-accounts/revoke")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"platform_user_ref\": \"<string>\",\n \"handle\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.botshield.ai/operations/secured-accounts/revoke")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"platform_user_ref\": \"<string>\",\n \"handle\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"data": {
"success": true,
"revoked": true,
"handle": "<string>",
"unlinked_at": "2023-11-07T05:31:56Z",
"unlink_reason": "credential_changed"
},
"error": {
"message": "<string>",
"statusCode": 123,
"code": "<string>",
"min_ttl_seconds": 123,
"max_ttl_seconds": 123,
"retryable": true,
"next_step": "<string>",
"violations": [
{
"source": "<string>",
"type": "<string>",
"path": "<string>",
"severity": "<string>",
"value": "<unknown>",
"explanation": "<string>",
"fix": "<string>"
}
],
"reason": "rate",
"bucket": "<string>",
"retry_in": 123,
"limits": {},
"upgrade_url": "<string>"
}
}
}{
"message": "Invalid input provided",
"input": {},
"errors": [
{
"propertyPath": "<string>",
"invalidValue": "<unknown>",
"message": "<string>"
}
]
}{
"error": {
"message": "<string>",
"statusCode": 123
}
}Revoke a Secured Account
End a Secured Account from your server. Send reason: 'credential_changed' when a primary sign-in detail changed on your side (password reset, email change, …) — the Secured Accounts spec requires it; the person’s app then shows the account as Unlinked with a Re-link action. Your company’s agents for that person are revoked with it, account.unlinked { handle, by: 'platform', unlinked_at, reason, surface_id } is sent to your webhook endpoints, live widgets for the account update at once, and the person is told. The next passkey ceremony on that account secures it again from scratch. Idempotent: an account that is not secured (or already unlinked) returns revoked: false. Select it by platform_user_ref or by handle — exactly one. The environment is your API key’s: a bs_dev_… key sees and changes development Secured Accounts only, a bs_prod_… key production only. Server API keys only — site keys (pk_…) are refused.
curl --request POST \
--url https://api.botshield.ai/operations/secured-accounts/revoke \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"platform_user_ref": "<string>",
"handle": "<string>"
}
'import requests
url = "https://api.botshield.ai/operations/secured-accounts/revoke"
payload = {
"platform_user_ref": "<string>",
"handle": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({platform_user_ref: '<string>', handle: '<string>'})
};
fetch('https://api.botshield.ai/operations/secured-accounts/revoke', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.botshield.ai/operations/secured-accounts/revoke",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'platform_user_ref' => '<string>',
'handle' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.botshield.ai/operations/secured-accounts/revoke"
payload := strings.NewReader("{\n \"platform_user_ref\": \"<string>\",\n \"handle\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.botshield.ai/operations/secured-accounts/revoke")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"platform_user_ref\": \"<string>\",\n \"handle\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.botshield.ai/operations/secured-accounts/revoke")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"platform_user_ref\": \"<string>\",\n \"handle\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"data": {
"success": true,
"revoked": true,
"handle": "<string>",
"unlinked_at": "2023-11-07T05:31:56Z",
"unlink_reason": "credential_changed"
},
"error": {
"message": "<string>",
"statusCode": 123,
"code": "<string>",
"min_ttl_seconds": 123,
"max_ttl_seconds": 123,
"retryable": true,
"next_step": "<string>",
"violations": [
{
"source": "<string>",
"type": "<string>",
"path": "<string>",
"severity": "<string>",
"value": "<unknown>",
"explanation": "<string>",
"fix": "<string>"
}
],
"reason": "rate",
"bucket": "<string>",
"retry_in": 123,
"limits": {},
"upgrade_url": "<string>"
}
}
}{
"message": "Invalid input provided",
"input": {},
"errors": [
{
"propertyPath": "<string>",
"invalidValue": "<unknown>",
"message": "<string>"
}
]
}{
"error": {
"message": "<string>",
"statusCode": 123
}
}Authorizations
Your secret API key (bs_dev_… for development, bs_production_… for production), or a site key (pk_test_… / pk_live_…) when calling from an allowed origin. Create keys in the Console under Settings → Developer Tools.
Body
Your stable user id for the account (the same platform_user_ref you passed when it was secured). Hashed server-side; never stored or returned. Send this OR handle.
512The Secured Account handle — your per-platform reference for the person, the same value carried on account.secured / account.unlinked. Send this OR platform_user_ref.
^OP_[A-Za-z0-9]{12}$Default platform.
platform, credential_changed Response
Result. NOTE: handler errors also arrive here (HTTP 200) as data.error — codes: api_key_required / invalid_api_key (401), partner_not_found (403), ref_or_handle_required / invalid_platform_user_ref / invalid_handle / invalid_reason (400), revoke_failed (500).
Show child attributes
Show child attributes
