{"uid":"cap_DOQQUsczQIuxnQjkfDurH","slug":"inbox-withzero-xyz-register-external-webhook-source-inbox-withzero-xyz-adfc4c4e","name":"Register External Webhook Source (inbox.withzero.xyz)","description":"Register an external webhook source; returns its inbound URL + secret. 📖 Full guide: https://inbox.withzero.xyz/llms.txt","url":"https://inbox.withzero.xyz/api/v1/connections","method":"POST","headers":{},"bodySchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["name","sourceType"],"properties":{"name":{"type":"string","maxLength":128,"minLength":1,"description":"Human label for this source."},"secret":{"type":"string","maxLength":256,"minLength":8,"description":"HMAC secret. For github/stripe paste the provider secret; omit for generic to auto-generate."},"sourceType":{"enum":["github","stripe","generic"],"type":"string","description":"Signature scheme + payload normalizer."}},"additionalProperties":false},"responseSchema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["id","name","sourceType","url","secret","createdAt"],"properties":{"id":{"type":"string"},"url":{"type":"string","description":"Inbound webhook URL to configure in the external system."},"name":{"type":"string"},"secret":{"type":"string","description":"HMAC secret (shown once). Configure the external system to sign with it."},"createdAt":{"type":"string"},"sourceType":{"type":"string"}},"additionalProperties":false},"example":{"request":{"name":"test-generic-webhook","sourceType":"generic"},"response":{"id":"4d03ce0e-f93c-49a5-bc7a-c0de7ca139df","url":"https://inbox.withzero.xyz/api/v1/webhooks/4d03ce0e-f93c-49a5-bc7a-c0de7ca139df","name":"test-generic-webhook","secret":"2af18b68cc1920b06ab786653ab451a5568481d304aa0b79","createdAt":"2026-06-03T22:46:26.712Z","sourceType":"generic"}},"exampleRequest":{"name":"test-generic-webhook","sourceType":"generic"},"tags":[],"displayCostAmount":"0","displayCostAsset":"USDC","priceDynamic":false,"priceHint":null,"priceStatus":"proven_free","priceSource":"registry","requiresHandshake":false,"reviewCount":0,"rating":{"score":"0.00","successRate":"0.00","reviews":0,"stars":null,"state":"unrated"},"availabilityStatus":"unknown","priceObserved":null,"sessionDeposit":null,"pricing":{"kind":"free","summary":"Free","primary":null,"accepted":[]},"paymentMethods":[],"brandName":"inbox.withzero.xyz","brandSlug":"inbox-withzero-xyz-mpp","brandBaseUrl":"https://inbox.withzero.xyz","brandDocsUrl":null,"whatItDoes":"Registers an external webhook source (GitHub, Stripe, or generic) and returns the inbound URL and HMAC secret to configure in the external system.","exampleAgentPrompt":"Register a new GitHub webhook source called 'my-repo-events' in my inbox so I can paste the returned inbound URL into my GitHub repo settings — use the github source type and I'll provide my own secret 'gh-secret-abc123xyz'.","exampleUseCases":[{"title":"Connect Stripe webhooks to agent inbox","prompt":"Set up a new Stripe webhook source called 'stripe-payments' in my inbox so I can start receiving payment events — use the stripe source type and generate a signing secret for me that I can paste into my Stripe dashboard settings."},{"title":"Register generic webhook for custom service","prompt":"Register a generic webhook source called 'shopify-orders' in my inbox for my custom e-commerce integration — I need the inbound URL and HMAC secret back so I can configure them on the sending side."},{"title":"Provision durable GitHub Actions listener","prompt":"Create a new GitHub webhook source called 'ci-pipeline-events' in my inbox using the github source type — I want to capture workflow run events from my GitHub Actions, so give me the inbound URL and secret I can drop into the repo's webhook settings."}],"resultDescription":"Returns a JSON object with the connection ID, human label, sourceType, the inbound webhook URL to paste into the external system, the HMAC signing secret (shown only once), and a createdAt timestamp.","failureModes":["Missing required fields (name or sourceType) returns 400 validation error","Invalid sourceType value (not github/stripe/generic) returns 400","Secret too short (under 8 chars) or too long (over 256 chars) returns 400","Unauthorized request (missing or invalid signed proof credential) returns 401","Duplicate or conflicting connection name may return 409"],"whenToPreferThis":"Use this endpoint when you need to receive events pushed by an external system (GitHub, Stripe, or any HTTP webhook source) into your agent's durable inbox. This is the first step before you can drain those events; choose the sourceType matching your provider to get correct HMAC signature verification and payload normalization.","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":3,"lastUsedAt":"2026-07-29T00:21:22.738Z","lastSuccessfullyRanAt":null,"lastHealthCheckAt":"2026-09-15T00:43:54.964Z","isFirstParty":true}