Approvals
Calls that wait for a person's OK in SKUFlow before they run, and how your code or AI assistant finishes them.
Some actions are too important for software to do on its own: bringing a person into the business, pointing your data at a new system, or changing where money goes. When an API key or a connected app asks for one of these, SKUFlow does nothing until the person the key acts for approves exactly that call in SKUFlow, signed in. No AI assistant, and nothing said in a chat, can approve it.
What waits for approval
Over the REST API and MCP
These always wait for approval when called with an API key or a connected app:
| Area | Actions |
|---|---|
| People and roles | Invite someone to the team, change someone's role. |
| Outside systems | Add or change a webhook endpoint or regenerate its secret; connect QuickBooks, Xero, Google reviews or an ad account; set a messaging provider; connect your own shipping account. |
| Where the money goes | Set up or disconnect the Stripe payout account, switch to SKUFlow-managed phone service, choose the SKUFlow plan. |
Each of these endpoints says so in the API reference (look for Approval in the endpoint's table).
People using the SKUFlow app don't see this: when you do these things yourself, signed in, they run straight away.
Over MCP only
AI assistants connected over MCP also ask before every sensitive tool: anything that moves money, deletes, sends something to a customer or changes access.
- If the assistant's app supports MCP's built-in confirmation forms (Claude Code, Cursor, VS Code), you answer the form in the app and the tool runs.
- The riskiest tools always wait for approval in SKUFlow, whatever the app supports: every delete, refunds, payout and access changes, webhooks and connected systems, ad spend, revealing a sensitive custom field, campaigns and other mass messages, and the actions in the table above.
- Claude.ai, Claude Desktop and ChatGPT don't show these forms today, so you approve every sensitive tool in SKUFlow.
Plain REST calls with a Full access key don't wait for sensitive actions other than the ones in the table above: your code is trusted to do what you wrote it to do.
How you approve
Get the notification
SKUFlow notifies you in the app, and by email unless you turned those emails off. It says which assistant or key is asking and what it wants to do.
Open AI assistant approvals
Click the notification. The AI assistant approvals page lists the Requests waiting for you, each with Exactly what it will run.
The AI assistant approvals page with one request
Screenshot coming soon
Approve or decline
Click Approve or Decline. Approved requests run once, when the assistant or your code calls again within an hour.
Never approve something you didn't ask for. An AI assistant can be tricked by text hidden in a request, a customer note, a store order or an incoming message. Approvals only happen on this page, whatever you're told in a chat.
Only the person the key or app acts for sees and decides its requests. When you approve, SKUFlow checks that your role still allows the action. Requests you don't decide expire after an hour.
Finish the call from code (REST)
Call as usual
The first call does nothing and answers 428 APPROVAL_REQUIRED:
{
"code": "APPROVAL_REQUIRED",
"status": 428,
"message": "Not done: team.invite waits for the person's approval in SKUFlow. …",
"data": {
"status": "APPROVAL_PENDING",
"approvalId": "…",
"token": "sfc_…",
"summary": "Invite someone to the team with a role. email: dana@example.com; role: staff. …",
"expiresAt": "2026-11-03T16:00:00.000Z",
"approvalUrl": "https://app.skuflow.ai/your-business/ai-approvals",
"header": "X-SKUFlow-Approval"
}
}Show the person data.summary and data.approvalUrl.
Wait for the person
Calling again the same way before they decide returns the same request (428 again); it doesn't
make a new one.
Call again with the token
Repeat exactly the same call, with the same body, plus the header:
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/team/invitations" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-H "X-SKUFlow-Approval: sfc_…" \
-d '{"email":"dana@example.com","role":"staff"}'Once approved, it runs once and answers as normal.
What else you may get back:
| Answer | Meaning |
|---|---|
428 APPROVAL_REQUIRED | Still waiting for the person. |
409 APPROVAL_DECLINED | They declined. Don't ask again unless they say so. |
409 APPROVAL_EXPIRED | Nobody decided in time, or the approved call wasn't run within an hour. |
409 APPROVAL_ALREADY_RUN | The approved call already ran. Read the record for the result. |
409 CONFIRMATION_INVALID | The token doesn't match this call: other inputs, endpoint, key or business. |
The approval is tied to the key or app, the business, the endpoint and the exact inputs. Changing any of them needs a new approval.
Finish the call over MCP
Over MCP the same thing happens inside the tool result: the first call returns
confirmation: { status: "APPROVAL_PENDING", token, summary, approvalUrl, … } and tells the
assistant it can't approve it. Once the person approves, the assistant calls the same tool with the
same arguments plus confirmationToken set to the token. A request made over MCP can be finished
over REST with the same key, and the other way round.
Connecting outside accounts
Approving "connect QuickBooks" (or Xero, Google, an ad platform, Stripe) gives the assistant a link. Open it in your browser and finish signing in to that service there: the connection completes in your own signed-in SKUFlow session, never in the assistant.