Overview
The Inbox API lets your agent ask for something and wait — instead of hoping the user is in the conversation right now.User.Inbox.push() puts a card on the user’s desk: an approval to click, a notice to read, or a broken integration to reconnect. You get a receipt back immediately; the user deals with the card whenever they next open their inbox.
This is the counterpart to Channels.
Channels.* sends a message into a conversation and expects the user to read it there. Inbox.push files a task that survives being ignored — it stays on the desk until it is acted on or expires.Approval
Options the user resolves in one click
Notice
A finished-work or heads-up card
Connection fix
An integration the agent needs reconnected
Where you can call it
User.Inbox.push() takes no recipient — the card always goes to the user of the current execution context. That makes it available exactly where your code already has an ambient user.
push(input)
Parameters
string
required
The card’s first line. Trimmed and capped at 140 characters.
string
required
The human explanation — the card’s context line, and the prose in the detail pane. Capped at 1000 characters.
string
Longer text shown only when the user opens the card. Capped at 4000 characters.
string
A source link for the card — an issue URL, a document permalink. Must be
http:// or https://. Rendered as a link the user can follow; never opened automatically.'urgent' | 'high' | 'normal' | 'low'
How loudly the card announces itself.
urgent is rate-limited — see Limits.('approve' | 'redirect' | 'fix')[]
What the card offers.
'approve' gives the user a decision to make; 'fix' requires connection. See Card kinds for how this maps to what the user sees.{ label: string; description?: string }[]
Two to four one-click answers. Labels are capped at 60 characters, descriptions at 200. Anything past the fourth option is dropped.
{ type: string; name: string }
Required with
actions: ['fix']. type is the integration’s catalog slug ('google-calendar'), name is what the user should recognise ('Google Calendar').string
Your idempotency and revision handle. 1–120 characters of
A–Z, a–z, 0–9, ., _, :, -. Push the same key again and you land on the existing card instead of knocking a second time. Omit it for one-shot cards.string
The conversation the card should hand off into when the user acts on it. Defaults to the current conversation.
Returns
'deposited' | 'updated' | 'exists' | 'capped'
deposited — a new card is on the desk.
updated — an existing card with this key was revised in place.
exists — a card with this identity was already there, unchanged.
capped — the push was refused and nothing was filed: the daily limit is spent, or the user’s organization has turned agent pushes off. reason says which.'input_request' | 'connection_fix' | 'agent_notice'
Which card kind the push routed to — echoed even on
capped, where it reports the kind that would have been filed.string
The key the card is filed under — your
key if you supplied one, otherwise the generated one. Reuse it to revise the card later.string
Only present on
capped. A short explanation you can surface to the agent author.Card kinds
You don’t pick the kind directly — it follows from what you ask for, in this order:1
Two or more options → a question card
Supplying
options (2–4) files an input_request. So does actions: ['approve'] without options — the Approve/Decline pair is synthesized for you, so the card still resolves in one click.2
A fix action → a connection card
actions: ['fix'] with connection: { type, name } files a connection_fix — the card that walks the user through reconnecting the integration your agent is blocked on.3
Everything else → a notice
Anything with no options and no fix — including
actions: ['redirect'] — files an agent_notice: work you finished, something the user should know about.If you supply both
options and actions: ['fix'], the options win — the question card is checked first.Limits
Inbox pushes are budgeted so an agent cannot train its user to ignore the inbox. The numbers below are platform defaults and may be tuned; the behaviors — resolve tocapped, demote, never throw — are the contract.
Budgets are shared with the agent’s other inbox activity of the same class, so a question pushed from code spends the same allowance as a question the agent asks on its own.
Notifications and quiet hours
A fresh card (outcome: 'deposited') notifies the user’s devices; urgent cards also send an email. The email rule applies after the daily urgent clamp — a push demoted to high sends no email. Delivery is best-effort: a notification can be lost — no registered devices, an offline phone, a delivery hiccup — without affecting the card, and the receipt doesn’t report delivery. Revisions (updated), duplicates (exists), and capped pushes never notify — a revision updates the card quietly.
Quiet hours are honored fail-open: if the platform can’t read the user’s preference, it delivers rather than risk silently suppressing every notification. So quiet hours are a strong promise to the user, not an absolute guarantee to your code — one more reason the card, not the notification, is the contract.
Revising a card
Give a card akey and later pushes with that same key revise it in place rather than filing a second one. The user is not notified again for an unchanged card.
Errors
A full inbox resolves tocapped. Everything else throws, with a code you can branch on:
Examples
Ask for an approval before acting
Report finished work from a recurring job
Dynamic jobs carry the user who created them, so a push inside one lands on that user’s desk:key is stable, tomorrow’s run revises today’s card instead of stacking a second one.
Ask the user to reconnect an integration
Best Practices
Use a stable key for anything recurring
Use a stable key for anything recurring
A digest, a review, a status card — anything your agent produces on a schedule should carry the same
key every run. Without one, each run files a new card and the inbox becomes a log.Reserve urgent for things that are actually urgent
Reserve urgent for things that are actually urgent
Only two urgent cards per user per day survive at that priority; the rest are demoted. Spending the allowance on routine cards means the genuinely urgent one arrives looking ordinary.
Give options when you want a decision
Give options when you want a decision
A notice asking “let me know if this is okay” needs the user to open a conversation and type. Two to four
options turn the same ask into one click, and the answer comes back into the thread.Handle capped, never retry it
Handle capped, never retry it
capped means the budget is spent for the day, so an immediate retry fails identically. Put the information in your return value instead — the user still gets it, through the conversation.Write the title as the whole message
Write the title as the whole message
Users scan the first line.
Approve the Q3 renewal quote is actionable at a glance; Action required is not.TypeScript Support
The input and receipt are fully typed at the call site, soreceipt.outcome narrows correctly without any annotation. If you need the shapes as named types, derive them from the method:
Next Steps
User API
Read and write the user data behind the card
Channels API
Send a message into the conversation instead
Jobs
Schedule the work that files the card
Spaces
Multi-agent delegation
See also
- Proactive Inbox recipe — a full monitoring skill: notices that revise in place, approvals, connection fixes, and
cappedhandled gracefully - User API — profile, storage, and
user.send()for in-conversation messages

