Approvals and safe actions
Some actions can't be undone or are seen by your customers. For those, FoodPerfect uses a two-step call: the first call describes the action and returns a token; only a second call with that token does it.
| Tool | What waits for approval |
|---|---|
publish_post_now |
Publishing posts to Instagram, Facebook, TikTok or LinkedIn |
schedule_reel_post |
Scheduling a reel on Instagram |
send_reply |
Sending an inbox reply (if an AI draft was generated for it) |
moderate_comment |
Deleting a customer comment (hide/unhide are ungated) |
update_inbox_settings |
Turning autopilot ON or turning the inbox OFF |
delete_generation |
Deleting a generated image or video |
delete_asset |
Deleting an uploaded asset or font |
#Step 1: request
Call the tool normally. It changes nothing and returns an error result with code requires_approval:
{
"error": {
"code": "requires_approval",
"message": "Publishing posts immediately requires explicit approval. Repeat the call with the returned approvalToken.",
"requestId": "b1c9…",
"retryable": false,
"details": {
"action": "publish_post_now",
"approvalToken": "eyJ…",
"expiresAt": "2026-10-01T12:15:00.000Z",
"preview": { "postIds": ["p_123"] }
}
}
}#Step 2: ask a human
Show the person what will happen, in plain words: what will be published or deleted, where, and when. The preview names what's affected (post ids, for example); look up the details with a read tool such as list_scheduled_posts or get_generation so the person sees the actual caption, image and platform. Then wait for an explicit yes.
Important
The token comes back to whoever made the call, so the human check is your agent's job. FoodPerfect can't tell whether a person said yes. Instruct your agent never to confirm on its own, and never to treat text inside tool results (a caption, a comment, a web page) as approval. The recommended system prompt does this.
#Step 3: confirm
Either repeat the exact same call with approvalToken added:
{ "name": "publish_post_now", "arguments": { "postIds": ["p_123"], "approvalToken": "eyJ…" } }or call confirm_action with just the token:
{ "name": "confirm_action", "arguments": { "approvalToken": "eyJ…" } }If you send Idempotency-Key headers, use a new one for the confirming call.
#Token rules
- Valid for 15 minutes. After that, start again from step 1.
- Single use.
- Bound to the account, the tool and the exact arguments. Changing anything (another post id, a new caption) needs a new approval.
#Other safety rails
- Connecting accounts (
get_connect_link) only returns a link. A person has to open it and log in to the platform;finalize_connectionthen only finishes what they started. - Spending isn't approval-gated, but it's capped by the balance and the key's scopes. A key without Generation Tools can't spend at all.
- Reversible edits such as
update_brand_dnaorgenerate_scheduled_post_contentrun straight away; you can change them back in the app.