Actions
Actions are the things an agent may do through your API. Connect your API once, then switch on individual actions in Product agent → What may it do in your app? and choose Save allowed actions. Until at least one action is allowed, the agent can only answer questions.
Connecting your API
Connect it in one of three ways. The agent can't tell the difference, and neither can the rules about what it may do.
| Option | Use when | Can it drift from your API? |
|---|---|---|
| From your repository | You installed with Connect GitHub, or connected the repository on Install after installing another way | The install commits an OpenAPI draft, and Frankie offers updates when your routes change. See Keeping your API current. Without GitHub, give Frankie your spec's URL (re-read at least every 30 seconds), or paste or upload the file (for example public/frankie.openapi.json) under Product agent → Connect your API and paste the new version when your API changes. |
| An OpenAPI URL or file | You already publish a spec, or installed without GitHub | No, when it's a URL: Frankie re-reads it at least every 30 seconds. Under Product agent → Connect your API, give the URL or choose Paste JSON instead. |
| An MCP server | You already run one | No: its tools are re-listed at least every minute. |
A workspace with no actions is still useful: the agent answers questions from what it learns from and takes no actions.
Calling your API as the user
Under How Frankie calls this API, choose who makes the request.
| Who calls | How the user is signed in | Use it for |
|---|---|---|
| User's browser (default for new connections) | The page's own session: cookies, or the token the install adds for Supabase-style apps | Your own app's API. Works however your app signs people in, and Frankie never holds a credential. |
| Frankie's server | The user's Frankie token in a header you name (usually Authorization), or the API's own key | A separate public API that accepts a bearer token. A cookie sign-in can't reach it. |
In the browser, each call goes to the connection's API base URL if set, else the spec's absolute servers[0], else the site the user is on, with the same credentials as a request from your own frontend, so your API checks it exactly as it would that user's own request. The install wires this up (the SDK's api option); a hand-written setup needs it too, see Provider.
Send the user's sign-in in this header applies only to Frankie's server. In the browser, your page sends the user's sign-in itself. For a frontend and a separate API, see Setup requirements by architecture.
Server calls also carry x-frankie-user-id, x-frankie-session-id and x-frankie-tenant-id, so your logs can tell agent calls apart.
The user approves every change
Reads run straight away. Anything that changes data (a create, update or delete, or an MCP tool not marked read-only) pauses first. The chat shows the action on an amber card with its route and the exact inputs, and Approve and Cancel. It runs only on Approve, with exactly those inputs: the agent can't change them in between, and text on a page or in a tool result can't approve it.
When one reply needs several changes, they show together on one card, in the order they'll run, each with its own Approve and Decline, plus Approve all. Once every one is answered, the approved ones run in that order and the agent replies once with every outcome. A declined one doesn't run, and the agent is told so.
Typing an answer works too, and is matched by Frankie, not guessed by the model. "Go ahead", "yes", "approve" or "do it" approve every action waiting; "no" or "cancel" decline them. Anything else ("yes, but use 628") is a new instruction: the waiting actions are dropped and the agent proposes again.
An unanswered action expires after 15 minutes, or as soon as the user sends something else.
Running without asking
In Product agent → Actions it may take → Before it changes data, an owner or admin picks one:
| Setting | What happens |
|---|---|
| Ask before changes (default) | Every change shows a card first. |
| Run without asking | Changes run at once. A delete still asks. |
| Run without asking, including deletes | Nothing asks. |
In config this is agent.approvals: "ask", "auto" or "auto_including_deletes". A delete is an HTTP DELETE, or a tool named for deleting or removing (deleteAgent, remove_member). Deletes keep asking in auto mode because they can't be undone.
A developer can override the workspace for one chat with the SDK's approvals prop ("ask" or "auto"), see Provider. A user can tick Don't ask again this conversation on a card. Neither one makes a delete run without asking.
agent.confirmWrites: false still turns asking off completely, deletes included.
Switching actions on
New actions are always off. In Product agent → What may it do in your app?, switch on the ones the agent may use (Allow shown and Clear shown act on everything in the current list), then choose Save allowed actions. Write actions (create, update, delete) need to be switched on deliberately, one by one.
An action that changes data but would run with a shared key instead of the user's own sign-in is flagged, so you can fix that before switching it on.
Reports and multi-step jobs
Because the agent calls your API, it can do more than one thing per message:
- Reports. "Calls and bookings by location this week" makes it read with your list endpoints. It answers with a short summary and a table, for the signed-in user only. Every number comes from your API; it never fills gaps with guesses. Tables need
@frankieai/react0.2.23 or later. Older widgets get the same answer without the table. - Workflows. "Set up a voice receptionist for our Austin clinic" can become five calls in a row: create, configure, connect, assign, test. Each call that changes data shows the user an approval card first. Allow the operations the job needs, and add a skill if the steps have to happen in a particular order.
When an action fails
If an endpoint has moved, refuses the user, or errors, the agent is told and says it couldn't do it, rather than pretending it worked. The conversation's steps show exactly which call failed and why.