Confirmations and four eyes
Some steps are a person's decision. The API keeps them that way.
Signing off rules
Compliance rules and workflow rules are signed off by a person: a token from the authorization code flow or a personal access token, never client credentials (user_token_required). The sign-off is two calls:
# 1. the preview: what you are about to sign, with a confirmation token bound to this exact definition
curl https://vestoris.com/api/v1/compliance/rules/42/sign-off -H "Authorization: Bearer $VESTORIS_TOKEN"
# 2. the sign-off, quoting that token
curl -X POST https://vestoris.com/api/v1/compliance/rules/42/sign-off \
-H "Authorization: Bearer $VESTORIS_TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" -H "X-Vestoris-Confirm: vcf_..." \
-d '{"reason":"Reviewed the restatement and the 5-day test bench","effective":"now"}'If the rule, its definition or its test bench changed after the preview, the token no longer matches and nothing is signed (confirmation_required). Four eyes applies: the author never signs off their own rule (unless the firm allows a single Compliance user, which the register then shows).
Natural-language commands
POST /api/v1/commands/{screen} plans a command (the AI or the built-in parser) and previews it: nothing runs. The answer carries a confirm_token (the preview's fingerprint). Executing it is a separate call:
curl -X POST https://vestoris.com/api/v1/commands/91/execute \
-H "Authorization: Bearer $VESTORIS_TOKEN" -H "Idempotency-Key: $(uuidgen)" \
-H 'X-Vestoris-Confirm: <confirm_token>'Large or destructive plans also need the typed phrase the preview shows, in the same header: X-Vestoris-Confirm: <confirm_token>; typed="CONFIRM 12". If the data changed since the preview, nothing runs: you get 412 with the new preview to check.
Approvals
Approving orders and overrides follows the same four-eyes rules as the blotter: never what you entered yourself. A service account approves only if an Admin allowed it on its client (shown with a warning, and in the event log).
AI over the API
The copilot answers only from data the identity may see; natural-language plans are proposals until confirmed. Every AI call is in the AI log with the client it came through (client_id, or pat:<id> for a personal token).