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
}
}Unlink (revoke) a Verified Account
End a Verified Account from your server. Send reason: 'credential_changed' when a primary sign-in detail changed on your side (password reset, email change, …) — the Verified 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 Verified 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. The Verified Accounts operations take the secret API key only and refuse site keys. Create keys in the Console under Settings → Developer Tools.
Body
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).
