Skip to main content
A BotShield Action asks for a passkey tap on one act on your platform: accepting a trade, claiming an offer, posting a listing. The person confirms on their phone, and your server receives a signed token that carries your own string for the act, as claims.act. An action is not a gate. It has no schedule, no queue and no Who may pass levers. It always stands on an account: every tap links the person to the account you name, in the same confirmation, like a link: required gate. So every action request needs your user ref. There are two ways to ask for a tap:
  • On your page or from your server, while the person is with you: the widget or create-verification-link with an act. This page covers it.
  • Through your agent, when the person is elsewhere: your server puts the action in front of a person already linked to you, as a card in their BotShield app. See Ask through an agent.
Both give you the same token, with claims.act.

Place an action

You place an action once, under a short act key such as trade. An action is live as soon as it is placed, and you can turn it off at any time.
In the BotShield Console, select Verified Accounts in the sidebar, open the BotShield Actions tab and select Place an action. The list shows the actions placed in the environment selected in the header.Select Place action. In Production, placing an action is confirmed with your Developer passkey.To stop an action, select Turn off on its row. Turning off takes effect at once and never asks for a passkey. Turn on in Production is confirmed with your Developer passkey. Only organization admins place and turn actions on or off.

Place an action with the API

An act key is unique within one environment. Turning an action off takes effect at once and is safe to repeat:
curl

The act string

Each request names the act with an act string. The part before the first : is the act key of a placed, live action. Everything after it is yours. BotShield never reads it. It signs the whole string into the token, and verify-token returns it exactly as you sent it, as claims.act.

Bind the terms

The token proves that a person confirmed this act string. Make the string specific enough that it can only mean one thing. When the person is agreeing to terms, put a hash of the terms in the act:
  1. Your server builds the terms from its own records: who, what, how much.
  2. It hashes them, for example SHA-256 over a fixed serialization, and puts the hash in the act.
  3. When the token comes back, your server rebuilds the terms from its records, hashes them again, and compares the result with claims.act.
If the terms changed between the request and the tap, the hashes differ and you refuse the act.
Never trust a client-side event. The widget’s botshield:success event and anything your page sends are claims made in the browser. Decide on your server, from the token, after verify-token answers valid (see Server flow).

The label

act_label is what the person reads on the card in the BotShield app before they confirm, for example “Buy 2 GA for Dec 4 from sam_k for $180”. The action’s Name is the card’s title.
  • 1 to 90 characters.
  • Sent only with an act. A label without an act is refused with act_label_without_act.
  • Display only. It is not in the token. Bind the terms through the act, never through the label.

Server flow

1

Create a session

Call POST /sdk/create-session with your API key, as for a gate. See Verify on your server.
curl
2

Create the request with the act

Call POST /sdk/create-verification-link with the bss_ grant token. Send act, act_label and partner_user_ref. Do not send gate or scope: an action is not a gate.
notarize: true says the tap runs the linking confirmation. trusted: true says the user ref is already linked. When pushed_to_devices is greater than 0, the request went to the person’s phone as a push notification.
3

Show the link and wait

Show web_url as a QR code or a link, as for a gate. A request lives 5 minutes. When the person confirms, you get the token either way: the return_url receives ?token=…&request_id=…, or poll GET /verification/status?request_id=… until status is completed and read verification_token. The gate.human_verified webhook also fires for an action tap; it carries request_id, act (exactly as you sent it) and, once linked, the person’s handle. The webhook tells you it happened — still check the token with verify-token before you act on it.
4

Verify the token once

Call POST /sdk/verify-token. It answers valid: true once per token. See Single use.
curl
5

Compare the act

Accept the act only when all of these hold:
  1. valid is true.
  2. claims.request_id is the request you created for this person and this act.
  3. claims.act is exactly the act string you expect, rebuilt from your own records.

Widget

Put the act on <botshield-verify> instead of a gate. The widget sends act and act-label in place of scope, so leave scope off.
Load widget 3.0.15 or later (/sdk.js serves it). On success, send detail.token to your server and run steps 4 and 5 above. When BotShield refuses the request, botshield:failure carries the reason, the code and the message:
reason is mobile_create_failed on a phone. The act and act-label attributes, and code and message on failures, need widget 3.0.15 or later. Earlier versions ignore act and send the request without it. See Widget versions.

Error codes

When you create the request, errors arrive as data.error with HTTP 200: An act longer than 128 characters, or an act_label that is empty or longer than 90, fails input validation with HTTP 400 before the operation runs. BotShield checks the action again when the person confirms. If the action was turned off during the tap, the request ends failed with reason: "action_off", and no token is issued. The gate.unavailable webhook then carries failure_code: "action_off" and the act. The Gates API action operations return invalid_key, gates_scope_required, org_not_found and internal as described in Gates API, plus action_key_taken (409) from actions/create and action_not_found (404) from actions/set-state.

Example: a two-party trade

A ticket marketplace lets fans trade tickets. sam_k (usr_20417) offers 2 GA tickets for the December 4 show to river_j (usr_48121) for $180. The trade goes through only when both people confirm the same terms with a passkey.
1

Place the action once

Place an action named “Confirm trade” with the act key trade.
2

Build the act from the terms

Your server records the trade as trd_7f3a and hashes its terms:
3

Ask each party

Create one request per person, with the same act, each person’s own user ref, and a label written for them:Store each request_id against the party it was created for.
4

Check each token once

For each completed request, call verify-token and keep the result:
5

Settle

Settle the trade when both the seller and the buyer are confirmed. If either party’s token fails a check, or the terms changed after the request, refuse the trade and ask both again with a new act.

Next steps

Verify on your server

Token claims and single use.

Secured Accounts

What the account link gives you.

Gates API

Place gates and actions from your server.

Web component

Every widget attribute and event.