Skip to main content
Sometimes the act happens when the person is not on your page: your agent has found the ticket, the hold or the offer, and the person has to say yes. From your server, you ask BotShield to put one action in front of that person as a card in their BotShield app, naming the agent that asked. The person approves with their passkey, and you collect the same token a tap on your page gives you, with your act string in claims.act. This works only for a person already linked to your company: a Secured Account. Nothing in this flow links anyone. To ask someone who is not linked yet, use the widget or create-verification-link while they are with you.

Before you start

You need three things, all in the same environment: The environment comes from the API key. A bs_dev_ key finds Development actions and agents, and reaches people linked in Development.

Flow

1

Ask

POST /gates-api/actions/request with your own request_id, a UUID you generate and store against this ask.
The person gets a notification, and the card waits in the BotShield app until expires_at. The call is safe to repeat: the same agent and request_id answer with the card already queued and its current status. Reusing a request_id for a different act is refused with request_id_reused.
2

The person approves

The card shows your agent’s display name, act_label and requested_by. Approving an action card always takes the person’s passkey: the passkey signs the act itself. If you turn the action off before they approve, the approval is refused and nothing is confirmed.
3

Collect the token

GET /gates-api/actions/request-status with the request_id. Send wait_seconds (up to 25) to hold the call open until the status changes, instead of polling in a tight loop.
curl
You can collect the token for 10 minutes after resolved_at. token_expires_in says how many seconds are left. After that the status stays approved, with token: null and token_expires_in: 0.
4

Verify the token once

Check the token with POST /sdk/verify-token, exactly as for a tap on your page. See Verify the token once. Accept the act only when:
  1. valid is true.
  2. claims.request_id is the request_id you sent.
  3. claims.act is exactly the act string you expect, rebuilt from your own records.
The token carries request_id, verified, organization_id, audience, timestamp, nonce, issued_at, expires_at and act. It carries trusted: false: it is a confirmation of one act, not an account check. It lives until the collection window closes, not 120 seconds.Every copy of the token you collect for one card shares one nonce, so verify-token answers valid: true once per card, however many times you call request-status. Check it in one place and keep the first answer.

Webhooks

When the person approves or declines the card, BotShield sends agents_ask.resolution.confirmed or agents_ask.resolution.denied, with your request_id. See Webhook events. The webhook tells you it happened. The action token comes only from request-status; the webhook’s proof_token is the Agents Ask resolution, not the action token.

Error codes

Errors arrive as data.error with HTTP 200. A body that fails input validation, for example a request_id that is not a UUID or a ttl_seconds out of range, is rejected with HTTP 400 before the operation runs.

Next steps

BotShield Actions

Place an action, the act string and binding the terms.

Secured Accounts

How a person links to your company.

Register an agent

The agent name and the display name on the card.

Gates API

Authentication and the shared error codes.