Skip to main content

The problem

An AI agent with admin API access can make destructive, hard-to-reverse changes the moment it decides to. Deactivating the wrong user account, escalating permissions incorrectly, or deleting data silently can cause real harm before anyone notices.
There’s no approval gate, no notification, and no audit trail showing who authorized the action.

The SafeFetch solution

Wrap the admin call in safeFetch() with approve: true and a callback URL. The action is held as awaiting_approval until a human approves it. Your backend is notified when the action reaches a terminal status.

Full example

The action is stored immediately and returns with status: "awaiting_approval". Your admin API is not called until a reviewer approves.

What happens next

1

Reviewer receives email

If you passed notify.email, SafeFetch sends an email with one-click Approve and Reject buttons. Links are signed — no login required.
2

Reviewer approves

Clicking Approve moves the action to pending and dispatches the request to your admin API. The receipt page shows the full details: who approved, when, and what your API returned.
3

Your callback fires

SafeFetch POSTs to your callback URL when the action reaches a terminal status (completed, failed, or cancelled). Check action.status and action.response_code to confirm the outcome and update your records.

Handling the callback

Verify the result in your webhook handler and take follow-up action:

Checking status programmatically

Poll or inspect the action at any point using its ID:

Approving or rejecting via API

If you have your own internal approval UI, skip the magic-link email and handle approval programmatically:

Receipt page as audit trail

Every action has a receipt page in the dashboard. It shows the full audit trail: who approved it, when, what your API returned, and how long delivery took. Share the URL with your security or compliance team.
For sensitive operations, store the action ID in your own database alongside the event. You can always retrieve the full record via safeFetch.get(action.id) or the API.
approve: true cannot be combined with sync: true. Synchronous mode waits for immediate completion — that’s incompatible with an asynchronous human decision.