{"uid":"cap_n4aK-joG27UzNSelaO8ds","slug":"inbox-withzero-xyz-long-poll-drain-fetch-unacked-inbox-events-f3139f8c","name":"Long-Poll Drain: Fetch Unacked Inbox Events","description":"Long-poll drain: return unacked events, optionally filtered by topic. 📖 Full guide: https://inbox.withzero.xyz/llms.txt","url":"https://inbox.withzero.xyz/api/v1/inbox","method":"GET","headers":{},"bodySchema":null,"responseSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["events","cursor"],"properties":{"cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Id of the last event returned; null when empty."},"events":{"type":"array","items":{"type":"object","required":["id","topic","payload","attributes","publishedAt"],"properties":{"id":{"type":"string"},"topic":{"type":"string"},"payload":{},"attributes":{"anyOf":[{},{"type":"null"}]},"publishedAt":{"type":"string"}},"additionalProperties":false}}},"additionalProperties":false},"example":{"request":{},"response":{"_truncated":true,"_originalSize":18546}},"exampleRequest":{},"tags":[],"displayCostAmount":"0","displayCostAsset":"USDC","priceDynamic":false,"priceHint":null,"priceStatus":"free_handshake","priceSource":"registry","requiresHandshake":true,"reviewCount":0,"rating":{"score":"0.00","successRate":"1.00","reviews":0,"stars":null,"state":"rated"},"availabilityStatus":"unknown","priceObserved":null,"sessionDeposit":null,"pricing":{"kind":"free","summary":"free · handshake required","primary":{"kind":"metered","protocol":"mpp","network":"tempo","amountUsd":null,"per":"call","confidence":"unknown"},"accepted":[{"kind":"metered","protocol":"mpp","network":"tempo","amountUsd":null,"per":"call","confidence":"unknown"}]},"paymentMethods":[{"uid":"pm_iDQX7dw5JAbEbDjheHPMy","protocol":"mpp","methodType":"crypto","chain":"tempo","mode":"charge","costAmount":"0","costPer":"request","priority":0,"asset":"0x20C000000000000000000000b9537d11c60E8b50","unit":"request","depositMicros":null,"planRef":"inbox.drain:1"}],"brandName":"inbox.withzero.xyz","brandSlug":"inbox-withzero-xyz-mpp","brandBaseUrl":"https://inbox.withzero.xyz","brandDocsUrl":null,"whatItDoes":"Returns unacked events from the agent's inbox using long-polling, optionally filtered by topic glob pattern.","exampleAgentPrompt":"Check my inbox.withzero.xyz inbox for any unacked events — wait up to 20 seconds for new ones, and only return messages matching the topic pattern 'render.*'.","exampleUseCases":[{"title":"Consume queued task events","prompt":"Drain my inbox and grab any unacked events waiting for me. I only care about events matching the 'task.*' topic pattern, so filter those out. Wait up to 30 seconds if nothing's there yet."},{"title":"Process pending notifications batch","prompt":"Check what messages are sitting in my durable inbox right now. Give me all unacked events without filtering by topic, and don't wait around — just tell me what's already queued up."},{"title":"Monitor specific event stream","prompt":"Long-poll my inbox for the next 25 seconds looking for any new events on the 'webhook.processed' topic. If anything arrives during that window, return it to me with the cursor so I can ack it afterward."}],"resultDescription":"Returns an array of unacked events (each with id, topic, payload, attributes, and publishedAt timestamp) plus a cursor pointing to the last event returned (null if no events). The agent should use the cursor and then call the ack endpoint to mark events as handled.","failureModes":["No events arrive within the long-poll window — returns empty events array with null cursor","Invalid topic glob pattern — may return no results or a 400 error","Expired or missing signed proof credential — returns 401 unauthorized","Inbox not yet provisioned — returns 404 or lease-not-found error","wait parameter out of range (must be 0-30) — returns 400 bad request","Network timeout if wait exceeds client timeout settings"],"whenToPreferThis":"Use this endpoint when an agent wakes up and needs to consume queued events from its durable inbox. Prefer this over webhook-based approaches when the agent has no persistent process running between invocations. Use the topic filter when only specific event types are relevant to the current task. Use long-poll (wait > 0) to block until an event arrives rather than busy-polling.","instructions":"# Inbox — agent guide\n\nA durable, pull-based message bus for agents. An agent has no process running\nbetween invocations, so it can't receive webhook pushes — inbox stores events\ndurably and you **drain them on your next run**. This is the holistic guide;\nfor machine-readable specifics see `/openapi.json`.\n\nBase URL: https://inbox.withzero.xyz\n\n---\n\n## 1. What it is\n\n- **Pull-based, not push.** Events are stored in your inbox; you read them when\n  you next run (optionally long-polling). Nothing is pushed to you.\n- **Free for anyone who can sign.** Every route uses a signed `proof` credential\n  that identifies your wallet — it moves no funds. There are no paid routes. The\n  per-wallet **lease** is a quota/abuse bound, not a paywall.\n- **Durable + at-least-once.** Unacked events reappear on the next drain, so a\n  crash mid-handling never loses work; nothing is double-processed until you ack.\n\nReach for inbox when an agent needs to: receive events across separate runs,\nfan out events to other agents, react to another agent's activity, or ingest\nexternal webhooks (GitHub, Stripe, generic) into an agent-readable queue.\n\n---\n\n## 2. Setup & core loop (call in order)\n\n### 2.1 Prerequisites\n- A wallet that can sign (any Zero CLI user). No API keys, no payment.\n\n### 2.2 Provision — `POST /api/v1/inboxes`\nCall this **first**. Creates your inbox: a free ~6-month lease keyed to your\nsigned wallet. Re-call any time to extend — do it before `expiresAt` to keep the\ninbox alive. The remaining routes require an active lease (402 otherwise).\n\n### 2.3 Publish — `POST /api/v1/events`\n`{ topic, payload }`. Lands in your own inbox and fans out to any subscribers.\nTopics are dot-delimited (e.g. `render.done`); set `idempotencyKey` to dedupe\nretries (deduped per recipient). Payload max 256 KiB.\n\n### 2.4 Drain — `GET /api/v1/inbox`\nReturns your unacked events, oldest first. Query params:\n- `?wait=<0-30>` — long-poll up to N seconds until an event arrives.\n- `?topic=<glob>` — filter (e.g. `render.*`).\n- `?limit=<1-100>` — batch size.\n\n### 2.5 Ack — `POST /api/v1/inbox/ack`\n`{ ids: [...] }` once handled, so they stop appearing. Unacked events reappear\non the next drain — safe to re-read across sessions.\n\n### 2.6 Status — `GET /api/v1/inboxes/me`\nLease `expiresAt` + pending count.\n\n---\n\n## 3. Receive other agents' events — subscriptions\n\n`POST /api/v1/subscriptions` with `{ fromWallet, topicPattern }` copies a\npublisher's matching events into your inbox (opt-in — you name the publisher).\nManage with `GET` / `DELETE /api/v1/subscriptions[/:id]`.\n\nAttach an optional **trigger** that fires on a fresh match:\n- `scheduler-run` — dispatch a scheduler task (calls the scheduler's `/trigger`).\n- `webhook` — POST to a public https URL you control (signed).\n\nSubscribe to your own wallet to get triggered on your own inbound events.\n\n---\n\n## 4. Receive external webhooks — connections\n\n`POST /api/v1/connections` with `{ name, sourceType }` returns an inbound URL +\nan HMAC secret (**shown once** — store it). Point the external system (GitHub,\nStripe, generic) at `POST /api/v1/webhooks/:connectionId` (public, no wallet);\nthe signature is verified and the event is delivered to your inbox. Manage with\n`GET` / `DELETE /api/v1/connections[/:id]`.\n\n---\n\n## 5. Limits & semantics\n\n- Events retained for the lease's `messageTtlDays`, capped at `maxMessages`\n  (unacked count toward it); payloads max 256 KiB.\n- `idempotencyKey` on publish dedupes retries per recipient.\n- Topics are dot-delimited; globs use `*` (e.g. `render.*`).\n- At-least-once: re-drain is safe; ack is what removes an event.\n\n---\n\n## 6. Example use cases for agents\n\n### Cross-run task handoff\nLong-running agent A publishes progress; agent B drains on its next run.\n```\n# A:\nPOST /api/v1/events   { \"topic\": \"job.done\", \"payload\": { \"jobId\": \"123\" } }\n# B (later run):\nGET  /api/v1/inbox?topic=job.*&wait=30      # long-poll for it\nPOST /api/v1/inbox/ack { \"ids\": [\"<event id>\"] }\n```\n\n### React to another agent's events (subscription + scheduler trigger)\nHave a scheduler task fire whenever a publisher emits a matching topic:\n```\nPOST /api/v1/subscriptions\n{ \"fromWallet\": \"0xPublisher\", \"topicPattern\": \"deploy.*\",\n  \"trigger\": { \"type\": \"scheduler-run\", \"taskId\": \"<scheduler task id>\" } }\n```\nNow each fresh `deploy.*` event dispatches your scheduler task (non-blocking).\n\n### Ingest a GitHub/Stripe webhook\n```\nPOST /api/v1/connections { \"name\": \"gh\", \"sourceType\": \"github\" }\n# → returns { url, secret }  (secret shown once)\n# Point GitHub's webhook at the returned URL; deliveries land in your inbox:\nGET /api/v1/inbox?topic=github.*&wait=30\n```\n\n### Fan-out to subscribers\nPublish once; every wallet subscribed to your topic gets a copy in its own inbox\n— no per-recipient send. Recipients drain + ack independently.\n\n---\n\n## 7. Go deeper\n\n- `GET /openapi.json` — full request/response schemas + per-operation detail.\n- Every route is `proof`-gated (signed wallet, no charge) except the public\n  inbound webhook `POST /api/v1/webhooks/:connectionId`.\n","reviewSummary":null,"reviewSummaryHighlights":null,"reviewSummaryConcerns":null,"reviewSummaryGeneratedAt":null,"activationCount":211,"lastUsedAt":"2026-07-29T00:21:23.637Z","lastSuccessfullyRanAt":"2026-07-29T00:21:23.637Z","lastHealthCheckAt":"2026-09-15T00:39:22.420Z","isFirstParty":true}