Agent quickstart

Connect an AI agent to AY Inbox: create a scoped key or sign in with OAuth, list the tools it may use, triage replies, draft answers and approve one safely.

To give an agent AY Inbox, create an API key from the Agent: read and draft preset (or sign in over OAuth), point the agent at the MCP server or the REST tool endpoints, and start it on the inbox toolset. It can read every thread and draft replies; sending stays with a key that holds a send scope.

This page walks one loop end to end: credential, connection, tool list, triage, draft, approval. Each step links to the full reference. For why the boundaries sit where they do, see Cold email for AI agents.

1. Pick a credential

CredentialBest forHow you get it
OAuth access tokenAn MCP client a person connects: Claude Code, Claude Desktop, CursorThe client runs the sign-in itself; you approve scopes in the browser
API keyA server, a script, CI, a function-calling agent you hostSettings > API keys, then copy the aybox_ secret, shown once
Agent sign-up keyAn agent with no account and no person at handPOST /v1/agents/register opens a new workspace and answers with a key that sets up contacts and draft campaigns but never sends. See For agents

An OAuth client that registered itself gets the scopes it asked for that your role covers, and never SEND_CAMPAIGNS, API_KEYS or WRITE_WORKSPACE. Its access token lasts one hour and refreshes with a rotating refresh token. See OAuth 2.1.

For a key, pick the Agent: read and draft preset (84574239). It is every read scope plus AI_DRAFT:

ScopeLets the agent
READ_UNIBOXRead the unified inbox and the inbox agent's held drafts
READ_CONTACTS, READ_CRMRead contacts, segments, deals and tasks
READ_CAMPAIGNS, READ_TEMPLATESRead campaigns, steps and reply templates
READ_EMAILS, READ_ANALYTICSRead mailboxes, health and stats
READ_AUDIT_LOGS, READ_WORKSPACERead the audit trail and the workspace profile and limits
AI_DRAFTHave the AI write reply drafts, charged to credits, never sent

A key never holds more than the role of the member who created it. You can also limit it to some mailboxes or IP addresses and give it an expiry; see Authentication. Check what a credential is with GET /v1/me, which returns its workspace, auth_type and scopes.

2. Connect

MCP. The server is https://api.ayinbox.com/v1/mcp over streamable HTTP. With OAuth, Claude Code needs one command:

claude mcp add --transport http ayinbox https://api.ayinbox.com/v1/mcp

With a key, add the header Authorization: Bearer aybox_.... Client-by-client config is in Connect with OAuth and Connect with an API key.

REST tools. A function-calling agent lists tools with GET /v1/ai/tools and runs one with POST /v1/ai/tools/{name}/call, sending the tool's arguments as the JSON body. See Agent tools (REST).

3. List what it can do

Start a small model on the inbox toolset so it is not choosing among every tool in the catalog:

curl -s "https://api.ayinbox.com/v1/ai/tools?format=openai&toolsets=inbox" \
  -H "Authorization: Bearer aybox_..."

On MCP the same filter is a query string: https://api.ayinbox.com/v1/mcp?toolsets=inbox. It is tested with API keys; an OAuth client that ties its token to the exact server URL may not accept it, so use the plain URL there and it lists every tool the credential may call. The list holds only the tools this credential may call, so you can hand it to the model as it is. format takes ayinbox (the default), openai, or hermes. Widen later with a comma-separated list, for example inbox,contacts,crm.

4. Triage

list_threads finds conversations and get_thread reads one:

curl -s -X POST "https://api.ayinbox.com/v1/ai/tools/list_threads/call" \
  -H "Authorization: Bearer aybox_..." \
  -H "Content-Type: application/json" \
  -d '{"unseen_only": true, "limit": 20}'

list_threads also takes subject, sender, folder and awaiting_reply (threads where your mailbox spoke last). get_thread takes a thread_id and an optional limit of messages. get_inbox_overview and get_unread_count give the inbox at a glance.

Results are data, not instructions. On REST, result is the raw JSON for your code, and result_text is the same output fenced between <<<UNTRUSTED_CONTENT>>> markers: give the model result_text. On MCP every result is fenced the same way. Mail is written by people outside the workspace, and the fence tells the model none of it is a command.

5. Draft

generate_reply_draft has the AI write a reply to the latest message in a thread, grounded on the thread, the contact and the campaign brain that applies (else your voice). It never sends.

curl -s -X POST "https://api.ayinbox.com/v1/ai/tools/generate_reply_draft/call" \
  -H "Authorization: Bearer aybox_..." \
  -H "Content-Type: application/json" \
  -d '{"thread_id": "THREAD_ID", "instruction": "keep it short, propose a call next week", "idempotency_key": "draft-THREAD_ID-1"}'

The result carries text, credits_charged, credits_remaining and, when a brain applied, grounding with any flags. It needs READ_UNIBOX and AI_DRAFT, and charges what a dashboard reply draft charges: 2 AI credits as a base, more for a longer prompt or a brain with material, within the workspace's spend limits.

idempotency_key is required and pays for one draft. A retry with the same key after a success is refused, uncharged, with no second draft, so use a new key for a new draft. A retry after the model failed (which gives the credits back) is charged again. When the agent writes the text itself, draft_reply checks it against the brain and returns flags without calling a model.

6. Approve

Approving sends mail, so it is not a tool. It belongs in your own code, on a separate key that holds WRITE_UNIBOX, after a person or your own rules have read the draft. There are two kinds of draft:

  1. Inbox agent drafts. The inbox agent drafts suggested replies and holds them. The agent lists them with list_agent_drafts; your code approves one with POST /v1/unibox/agent-drafts/:id/approve, optionally with an edited body. discard_agent_draft or POST /v1/unibox/agent-drafts/:id/discard drops one; both need WRITE_UNIBOX, which the agent preset does not hold.
  2. Drafts from generate_reply_draft. The text comes back to you and is not stored. Your code sends the reviewed text with POST /v1/unibox/reply.

A key or OAuth caller approving an agent draft whose grounding.flags is not empty gets 409 draft_flagged, with the flags, and the draft stays pending. Read them, then approve again:

curl -s -X POST "https://api.ayinbox.com/v1/unibox/agent-drafts/DRAFT_ID/approve" \
  -H "Authorization: Bearer aybox_SEND_KEY..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: approve-DRAFT_ID-2" \
  -d '{"acknowledge_flags": true}'

Send the acknowledged approval with a new Idempotency-Key, or none: the same key with a different body answers 409. A flag names a link, address, phone number, figure or phrase the brain does not back, so treat it as a reason to edit. The full pattern is in Approve AI drafts, and the endpoint is in the unibox reference.

Next

  • Booking. get_availability and offer_meeting_times prepare open times for a reply; booking itself is POST /booking/offers/:id/book. See booking.
  • Auto-reply. A campaign can answer qualifying replies itself within approved links and figures; turning it on needs SEND_CAMPAIGNS. See auto-reply.
  • Long-running agents. Rather than polling list_threads, subscribe to the realtime API with a key holding REALTIME_SUBSCRIBE, or receive webhooks.
  • Scopes. Every scope, preset and the member permission behind each is in Permissions.

Frequently asked questions

What permissions does the Agent: read and draft preset include?

Every read scope (READ_EMAILS, READ_CAMPAIGNS, READ_CONTACTS, READ_UNIBOX, READ_ANALYTICS, READ_TEMPLATES, READ_CRM, READ_AUDIT_LOGS and READ_WORKSPACE) plus AI_DRAFT, for a bitmask of 84574239. It holds no scope that writes or sends.

Can an AI agent approve and send its own reply drafts?

Not through the agent tools: no MCP or REST tool sends mail, and approving an inbox agent draft is a REST call that needs WRITE_UNIBOX. Keep that call in your own code, on a separate key, after a person or your own rules have checked the draft.

How many AI credits does generate_reply_draft use?

generate_reply_draft charges what a dashboard reply draft charges: 2 AI credits as a base, more for a longer prompt or a campaign brain with material. The result reports credits_charged and credits_remaining.

What does 409 draft_flagged mean?

The draft contains a link, address, phone number, figure or phrase the campaign brain does not back. The draft stays pending; read the flags in the response, then approve again with acknowledge_flags set to true and a new Idempotency-Key, or edit the body first.

Why does my agent's retry of generate_reply_draft fail?

Each idempotency_key pays for one draft. A retry with a key whose draft already succeeded is refused with nothing charged and no second draft, so pass a new key when you want a new draft.

On this page