FoodPerfect Docs

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:

Tool result (isError: true)
{
  "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:

tools/call params
{ "name": "publish_post_now", "arguments": { "postIds": ["p_123"], "approvalToken": "eyJ…" } }

or call confirm_action with just the token:

tools/call params
{ "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_connection then 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_dna or generate_scheduled_post_content run straight away; you can change them back in the app.