AGNTDocs

Work

Approvals

Actions the assistant staged for a person to review before they go out. The API calls a batch of staged actions a cart. Show the approval to the user, then approve it with its `contentHash` so exactly what they saw is sent.

GET/portal/carts

List approvals

Returns the approvals waiting on the user, newest first, up to 50. Filter with `status`.

Query parameters

statusstringComma-separated subset of pending_approval, time_boxed. Default: both.

Responses

200Approvals
ok reqboolean
carts reqobject[]
id reqstringThe approval (cart) id.
taskIdstring | null
taskTitlestring
assistantNamestring | null
status reqenumopen: the assistant is still adding actions. submitted: handed over, approval mode being decided. pending_approval: waiting for the user. time_boxed: runs when the window ends unless stopped. approved: approved and queued. executing: being sent. executed: done. cancelled: cancelled by a person with the cancel endpoint or by a time-boxed window set to cancel. rejected: declined from an approval link, such as the Reject link in an approval email. failed: could not be sent.opensubmittedpending_approvaltime_boxedapprovedexecutingexecutedcancelledrejectedfailed
resolvedApprovalModeenumautotime-boxedmanual
timeBoxedExpiresAtstring | nullFor time_boxed: when the window ends.
timeBoxedExpiryenumWhat happens when a time-boxed window ends.executecancel
dispatches reqobject[]
indexintegerPosition in the approval; use it in the dispatch paths.
typestringKind of action, such as a message sent as the assistant or a calendar change.
platformstring | nullChannel, such as email or sms.
fromstring
tostring[]
ccstring[]
bccstring[]
subjectstring
bodystring
descriptionstringPlain description of the action.
payloadobject | nullAction-specific detail, such as the full event for a calendar change.
filesobject[]Attachments that go out with the action.
filenamestring | null
mimeTypestring | null
sizenumber | null
fileIdstring | null
editedByUserbooleanTrue when the text shown is the user's own edit; it is sent exactly as written.
currentVersionIdstring | null
validUntilstring | nullWhen the content stops being true; null with evergreen false means none declared.
evergreenboolean
contentHash reqstringHash of exactly the content shown. Send it back on approve.
createdAtstring
updatedAtstring
400status names no valid value.
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.

Request

curl 'https://api.agnt.ai/portal/carts' \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]"

Response

{
  "ok": true,
  "carts": [
    {
      "id": "6660c4a1f2e3b7d8a9c01234",
      "status": "pending_approval",
      "dispatches": [
        {
          "index": null,
          "type": null,
          "platform": null,
          "from": null
        }
      ],
      "contentHash": "9f2c1b7e4a"
    }
  ]
}
GET/portal/carts/{cartId}

Retrieve an approval

Retrieves an approval with its staged actions and the `contentHash` to approve it with.

Path parameters

cartId reqstring

Responses

200Approval
ok reqboolean
cart reqobject
id reqstringThe approval (cart) id.
taskIdstring | null
taskTitlestring
assistantNamestring | null
status reqenumopen: the assistant is still adding actions. submitted: handed over, approval mode being decided. pending_approval: waiting for the user. time_boxed: runs when the window ends unless stopped. approved: approved and queued. executing: being sent. executed: done. cancelled: cancelled by a person with the cancel endpoint or by a time-boxed window set to cancel. rejected: declined from an approval link, such as the Reject link in an approval email. failed: could not be sent.opensubmittedpending_approvaltime_boxedapprovedexecutingexecutedcancelledrejectedfailed
resolvedApprovalModeenumautotime-boxedmanual
timeBoxedExpiresAtstring | nullFor time_boxed: when the window ends.
timeBoxedExpiryenumWhat happens when a time-boxed window ends.executecancel
dispatches reqobject[]
indexintegerPosition in the approval; use it in the dispatch paths.
typestringKind of action, such as a message sent as the assistant or a calendar change.
platformstring | nullChannel, such as email or sms.
fromstring
tostring[]
ccstring[]
bccstring[]
subjectstring
bodystring
descriptionstringPlain description of the action.
payloadobject | nullAction-specific detail, such as the full event for a calendar change.
filesobject[]Attachments that go out with the action.
filenamestring | null
mimeTypestring | null
sizenumber | null
fileIdstring | null
editedByUserbooleanTrue when the text shown is the user's own edit; it is sent exactly as written.
currentVersionIdstring | null
validUntilstring | nullWhen the content stops being true; null with evergreen false means none declared.
evergreenboolean
contentHash reqstringHash of exactly the content shown. Send it back on approve.
createdAtstring
updatedAtstring
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.
404No such approval for this user.

Request

curl 'https://api.agnt.ai/portal/carts/<cartId>' \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]"

Response

{
  "ok": true,
  "cart": {
    "id": "6660c4a1f2e3b7d8a9c01234",
    "status": "pending_approval",
    "dispatches": [
      {
        "index": 1,
        "type": "type",
        "platform": "platform",
        "from": "from"
      }
    ],
    "contentHash": "9f2c1b7e4a"
  }
}
POST/portal/carts/{cartId}/approve

Approve an approval

Approves the staged actions exactly as the user saw them and queues them to run, with no further model step. Pass the `contentHash` from the read you showed the user. If the content changed since then, the call returns `409` and nothing is sent. Call it only on the user's explicit decision.

Path parameters

cartId reqstring

Request body

contentHash reqstringThe contentHash from the latest read of this approval.
reasonstringOptional note.

Responses

200Approved and queued
okboolean
cartIdstring
statusenumapproved
400content_hash_required, cart_already_resolved (not awaiting approval) or cart_task_closed (the task closed and the draft was withdrawn).
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.
404No such approval for this user.
409cart_content_changed: the content changed since it was read. Read it again and show the user before approving.
500Queuing failed; the approval is left as it was. Retry.

Request

curl 'https://api.agnt.ai/portal/carts/<cartId>/approve' \
  -X POST \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]" \
  -H "Content-Type: application/json" \
  -d '{
  "contentHash": "9f2c1b7e4a"
}'

Response

{
  "ok": true,
  "cartId": "6660c4a1f2e3b7d8a9c01234",
  "status": "approved"
}
POST/portal/carts/{cartId}/cancel

Cancel an approval

Cancels the staged actions and sets the status to `cancelled`. Nothing is sent. The assistant receives the optional `reason` and adjusts.

Path parameters

cartId reqstring

Request body

reasonstringOptional reason passed to the assistant.

Responses

200Cancelled
okboolean
cartIdstring
statusenumcancelled
400Already executed, cancelled or rejected.
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.
404No such approval for this user.

Request

curl 'https://api.agnt.ai/portal/carts/<cartId>/cancel' \
  -X POST \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "Approved by Jane"
}'

Response

{
  "ok": true,
  "cartId": "6660c4a1f2e3b7d8a9c01234",
  "status": "cancelled"
}
PATCH/portal/carts/{cartId}/dispatches/{index}/edit

Edit a staged action

Changes the subject or body of one staged action, or how long its content stays valid. The edit is kept as a new version and changes the `contentHash`. Recipients and payload cannot be changed with this call.

Path parameters

cartId reqstring
index reqstring

Request body

subjectstring
bodystring
validUntilstringISO 8601 time with offset, in the future. Replaces the declared validity.
evergreenbooleantrue: the content never goes stale. Replaces the declared validity.

Responses

200Updated approval
ok reqboolean
cart reqobject
id reqstringThe approval (cart) id.
taskIdstring | null
taskTitlestring
assistantNamestring | null
status reqenumopenpending_approvaltime_boxedapprovedexecutingexecutedcancelledrejectedfailed
resolvedApprovalModeenumautotime-boxedmanual
timeBoxedExpiresAtstring | nullFor time_boxed: when the window ends.
timeBoxedExpiryenumWhat happens when a time-boxed window ends.executecancel
dispatches reqobject[]
indexintegerPosition in the approval; use it in the dispatch paths.
typestringKind of action, such as a message sent as the assistant or a calendar change.
platformstring | nullChannel, such as email or sms.
fromstring
tostring[]
ccstring[]
bccstring[]
subjectstring
bodystring
descriptionstringPlain description of the action.
payloadobject | nullAction-specific detail, such as the full event for a calendar change.
filesobject[]Attachments that go out with the action.
filenamestring | null
mimeTypestring | null
sizenumber | null
fileIdstring | null
editedByUserbooleanTrue when the text shown is the user's own edit; it is sent exactly as written.
currentVersionIdstring | null
validUntilstring | nullWhen the content stops being true; null with evergreen false means none declared.
evergreenboolean
contentHash reqstringHash of exactly the content shown. Send it back on approve.
createdAtstring
updatedAtstring
400Invalid or empty edit, a change to to, cc, bcc or payload, or an action type that cannot be edited (edit_not_supported)
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.
404Approval or action not found.
409cart_not_editable: the approval is no longer pending_approval or time_boxed.

Request

curl 'https://api.agnt.ai/portal/carts/<cartId>/dispatches/<index>/edit' \
  -X PATCH \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]" \
  -H "Content-Type: application/json" \
  -d '{
  "subject": "subject",
  "body": "Prefers morning meetings.",
  "validUntil": "2026-10-15T14:30:00Z",
  "evergreen": true
}'

Response

{
  "ok": true,
  "cart": {
    "id": "6660c4a1f2e3b7d8a9c01234",
    "status": "pending_approval",
    "dispatches": [
      {
        "index": 1,
        "type": "type",
        "platform": "platform",
        "from": "from"
      }
    ],
    "contentHash": "9f2c1b7e4a"
  }
}
PATCH/portal/carts/{cartId}/dispatches/{index}

Update a staged action

Updates one staged action, including its recipients and payload. Only the fields you send change, and the `contentHash` changes.

Path parameters

cartId reqstring
index reqstring

Request body

subjectstring
bodystring
tostring[]
ccstring[]
bccstring[]
payloadobjectAction-specific fields to change.

Responses

200Updated approval
ok reqboolean
cart reqobject
id reqstringThe approval (cart) id.
taskIdstring | null
taskTitlestring
assistantNamestring | null
status reqenumopenpending_approvaltime_boxedapprovedexecutingexecutedcancelledrejectedfailed
resolvedApprovalModeenumautotime-boxedmanual
timeBoxedExpiresAtstring | nullFor time_boxed: when the window ends.
timeBoxedExpiryenumWhat happens when a time-boxed window ends.executecancel
dispatches reqobject[]
indexintegerPosition in the approval; use it in the dispatch paths.
typestringKind of action, such as a message sent as the assistant or a calendar change.
platformstring | nullChannel, such as email or sms.
fromstring
tostring[]
ccstring[]
bccstring[]
subjectstring
bodystring
descriptionstringPlain description of the action.
payloadobject | nullAction-specific detail, such as the full event for a calendar change.
filesobject[]Attachments that go out with the action.
filenamestring | null
mimeTypestring | null
sizenumber | null
fileIdstring | null
editedByUserbooleanTrue when the text shown is the user's own edit; it is sent exactly as written.
currentVersionIdstring | null
validUntilstring | nullWhen the content stops being true; null with evergreen false means none declared.
evergreenboolean
contentHash reqstringHash of exactly the content shown. Send it back on approve.
createdAtstring
updatedAtstring
400Invalid or empty patch.
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.
404Approval or action not found.
409cart_not_editable: the approval is no longer pending_approval or time_boxed.

Request

curl 'https://api.agnt.ai/portal/carts/<cartId>/dispatches/<index>' \
  -X PATCH \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]" \
  -H "Content-Type: application/json" \
  -d '{
  "subject": "subject",
  "body": "Prefers morning meetings.",
  "to": [
    "to"
  ],
  "cc": [
    "cc"
  ]
}'

Response

{
  "ok": true,
  "cart": {
    "id": "6660c4a1f2e3b7d8a9c01234",
    "status": "pending_approval",
    "dispatches": [
      {
        "index": 1,
        "type": "type",
        "platform": "platform",
        "from": "from"
      }
    ],
    "contentHash": "9f2c1b7e4a"
  }
}
DELETE/portal/carts/{cartId}/dispatches/{index}

Remove a staged action

Removes one action from a pending approval. An approval with no actions left stays pending until you cancel it.

Path parameters

cartId reqstring
index reqstring

Responses

200Updated approval
ok reqboolean
cart reqobject
id reqstringThe approval (cart) id.
taskIdstring | null
taskTitlestring
assistantNamestring | null
status reqenumopenpending_approvaltime_boxedapprovedexecutingexecutedcancelledrejectedfailed
resolvedApprovalModeenumautotime-boxedmanual
timeBoxedExpiresAtstring | nullFor time_boxed: when the window ends.
timeBoxedExpiryenumWhat happens when a time-boxed window ends.executecancel
dispatches reqobject[]
indexintegerPosition in the approval; use it in the dispatch paths.
typestringKind of action, such as a message sent as the assistant or a calendar change.
platformstring | nullChannel, such as email or sms.
fromstring
tostring[]
ccstring[]
bccstring[]
subjectstring
bodystring
descriptionstringPlain description of the action.
payloadobject | nullAction-specific detail, such as the full event for a calendar change.
filesobject[]Attachments that go out with the action.
filenamestring | null
mimeTypestring | null
sizenumber | null
fileIdstring | null
editedByUserbooleanTrue when the text shown is the user's own edit; it is sent exactly as written.
currentVersionIdstring | null
validUntilstring | nullWhen the content stops being true; null with evergreen false means none declared.
evergreenboolean
contentHash reqstringHash of exactly the content shown. Send it back on approve.
createdAtstring
updatedAtstring
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.
404Approval or action not found.
409cart_not_editable: the approval is no longer pending_approval or time_boxed.

Request

curl 'https://api.agnt.ai/portal/carts/<cartId>/dispatches/<index>' \
  -X DELETE \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]"

Response

{
  "ok": true,
  "cart": {
    "id": "6660c4a1f2e3b7d8a9c01234",
    "status": "pending_approval",
    "dispatches": [
      {
        "index": 1,
        "type": "type",
        "platform": "platform",
        "from": "from"
      }
    ],
    "contentHash": "9f2c1b7e4a"
  }
}
GET/portal/carts/{cartId}/snapshots

List undoable actions

Returns one entry per action that ran, with whether it can still be undone and until when.

Path parameters

cartId reqstring

Responses

200Snapshots
cartIdstring
countinteger
snapshotsobject[]
dispatchIndexinteger
dispatchTypestring
resourceTypestring
reversiblebooleanWhether the action can be reverted after it ran. A non-reversible action can only be stopped while it waits to send.
undoStatusenumavailableundoneexpirednot_applicable
undoExpiresAtstring | null
undoneAtstring | null
undoAvailableboolean
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.
404No such approval for this user.

Request

curl 'https://api.agnt.ai/portal/carts/<cartId>/snapshots' \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]"

Response

{
  "cartId": "6660c4a1f2e3b7d8a9c01234",
  "count": 42,
  "snapshots": [
    {
      "dispatchIndex": 1,
      "dispatchType": "dispatchtype",
      "resourceType": "resourcetype",
      "reversible": true
    }
  ]
}
POST/portal/carts/{cartId}/dispatches/{index}/undo

Undo an action

Reverts one action that ran, or stops one that is still waiting to send. Available until the action's undo window closes.

Path parameters

cartId reqstring
index reqstring

Responses

200Undone
okboolean
undoneboolean
typeenumreversedcancelled_during_delay
dispatchTypestring
resultobject
400Not available to undo, window expired, or undo_not_supported for this action type.
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.
404Approval or snapshot not found.
409The target changed since and cannot be reverted safely.
410The target no longer exists.

Request

curl 'https://api.agnt.ai/portal/carts/<cartId>/dispatches/<index>/undo' \
  -X POST \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]"

Response

{
  "ok": true,
  "undone": true,
  "type": "reversed",
  "dispatchType": "dispatchtype"
}
POST/portal/carts/{cartId}/undo

Undo all actions

Reverts every reversible action in the approval, in reverse order, and reports the result for each.

Path parameters

cartId reqstring

Responses

200Result per action
okboolean
cartIdstring
undoneinteger
skippedinteger
expiredinteger
failedinteger
detailsobject[]
403The caller is not acting as a user: send X-User-Email with an account key, or use a user-scoped key. Certificate tokens and AGNT console sessions are refused.
404No such approval for this user.

Request

curl 'https://api.agnt.ai/portal/carts/<cartId>/undo' \
  -X POST \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-User-Email: [email protected]"

Response

{
  "ok": true,
  "cartId": "6660c4a1f2e3b7d8a9c01234",
  "undone": 1,
  "skipped": 1
}
GET/portal/account/kill-switch

Retrieve the kill switch

Returns whether outbound actions are frozen for the whole account. While the account is frozen, creating and running tasks returns `423` with `error_code: "KILL_SWITCH_ENGAGED"`. Only a person signed in to your hosted app can freeze or release the account; API keys and tokens cannot. To stop one task, stop the task instead.

Responses

200State
stateenumfrozen blocks every outbound action, reply and inbound processing for the account; active is normal operation.activefrozen
engagedAtstring | nullWhen the current freeze started; null while active
engagedByobject | nullWho engaged the current freeze: actor is their email
actorstring | null
sourcestring | null
reasonstring | null

Request

curl 'https://api.agnt.ai/portal/account/kill-switch' \
  -H "Authorization: Bearer ak_live_..."

Response

{
  "state": "active",
  "engagedAt": "2026-10-15T14:30:00Z",
  "engagedBy": {
    "actor": "actor",
    "source": "source"
  },
  "reason": "Approved by Jane"
}