Webhook inboxes: capture and inspect HTTP callbacks
Create a temporary webhook URL with the socket.help API, receive callbacks from any service, and read captured methods, headers, query values and bodies.
Updated 27 October 2026What a webhook inbox does
A webhook inbox is a temporary URL that records every request sent to it. Use it to see exactly what a payment provider, Git host, form service or your own code sends before you write a handler. The inbox answers each sender with 200 and stores the method, path, headers, query parameters and body for you to read.
Create an inbox
POST /api/inboxes takes no body. Optional query parameters set visibility, ttlSeconds and persistent; see Lifetimes and renewal. The response includes webhookUrl, the inspectionToken for reading and deleting, and, for private inboxes, the accessToken that senders need.
curl -X POST 'https://socket.help/api/inboxes?visibility=public&ttlSeconds=1800'
# 201 Created
{
"id": "INBOX_ID",
"inspectionToken": "INSPECTION_TOKEN",
"expiresAt": "2026-10-27T12:30:00.000Z",
"visibility": "public",
"accessVersion": "ACCESS_VERSION",
"webhookUrl": "https://socket.help/hooks/INBOX_ID"
}Send requests to the webhook URL
The webhook URL accepts GET, HEAD, POST, PUT, PATCH, DELETE and OPTIONS, with a body on any method up to 100 KiB. Query strings are captured; additional path segments after the inbox ID are not accepted.
A successful capture returns 200 with {"received":true,"requestId":"..."} and an X-Webhook-Request-Id header. HEAD returns 200 with no body. The response status and body are fixed; an inbox cannot be configured to answer differently. Use a mock API for that.
Private inboxes accept a request only with the access token in X-Access-Token or Authorization: Bearer. Without it the sender gets 404 and nothing is stored. Workspace credentials with resources:write can also send to their own private inboxes.
curl -X POST 'https://socket.help/hooks/INBOX_ID?source=test' \
-H "X-Access-Token: $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"type":"invoice.paid","id":"evt_test_1"}'
# 200 OK
# X-Webhook-Request-Id: CAPTURE_ID
{"received":true,"requestId":"CAPTURE_ID"}Read captured requests
GET /api/inboxes/{id}/requests returns captures in arrival order. Each record has id, method, path, headers, query, body, bodyEncoding, bodySize and timestamp. Bodies that are valid UTF-8 are stored as text; other bodies are stored as Base64 with bodyEncoding set to base64.
Header names that contain authorization, cookie, token, api key, secret or password are stored as [REDACTED]. Bodies and query values are kept as sent, so use test data.
For polling, the response has an ETag. Send it back in If-None-Match and you get 304 until a new request arrives. The response also carries X-Resource-Visibility, X-Access-Version and X-Resource-Expires-At headers.
curl -i https://socket.help/api/inboxes/INBOX_ID/requests \
-H "Authorization: Bearer $INSPECTION_TOKEN" \
-H 'If-None-Match: "ETAG_FROM_LAST_RESPONSE"'Inbox details and deletion
GET /api/inboxes/{id} returns id, visibility, accessVersion, expiresAt, requestCount and storedBytes, plus createdAt, persistent, requestLimit and byteLimit. DELETE /api/inboxes/{id} removes the inbox and its history immediately and returns 204.
Use the inspection token for anonymous inboxes. Inboxes created with an API key are managed with workspace access; send the key instead.
| Method and path | Purpose |
|---|---|
| POST /api/inboxes | Create an inbox |
| ANY /hooks/{id} | Capture an incoming request |
| GET /api/inboxes/{id}/requests | Read captured requests |
| GET /api/inboxes/{id} | Read expiry and usage |
| POST /api/inboxes/{id}/sharing | Change visibility or rotate the access token |
| POST /api/inboxes/{id}/renew | Extend the lifetime within your plan |
| DELETE /api/inboxes/{id} | Delete the inbox and its history |
Limits
Anonymous inboxes hold up to 100 requests or 1 MiB of captured data; account inboxes hold up to 1,000 requests or 10 MiB. When an inbox is full, new captures get 429 and existing history stays readable. Each inbox accepts up to 120 requests per minute.
Frequently asked questions
Can the inbox respond with a custom status code or body?
No. A webhook inbox always answers a successful capture with 200 and {"received":true,"requestId":"..."}. To return a chosen status, body or delay, create a mock API.
My provider cannot send custom headers. How do I use a private inbox?
You cannot: private inboxes require X-Access-Token or a Bearer access token. Create the inbox with ?visibility=public, or switch an existing inbox with POST /api/inboxes/{id}/sharing and {"visibility":"public"}.
Are signature headers from my provider captured?
Yes, unless the header name contains authorization, cookie, token, api key, secret or password. Those headers are redacted before storage.
How long does an inbox last?
One hour by default. You can set ttlSeconds at creation or renew up to your plan’s maximum retention: 1 hour anonymously, 1 day on Free, 7 days on Pro and 30 days on Team.