Queues, Buses and Buckets
An outbound endpoint doesn't have to be a URL. It can publish each message to:
| Type | What each message becomes |
|---|---|
| Amazon SQS | One SendMessage (standard or FIFO queue) |
| Amazon SNS | One Publish (standard or FIFO topic) |
| Amazon EventBridge | One PutEvents entry on your bus |
| Google Cloud Pub/Sub | One publish to your topic |
| Amazon S3 | One object per message (PutObject), on S3 or any S3-compatible store such as Cloudflare R2 |
These endpoint types are available on the Starter plan and above.
Your consumers read from your own queue, bus or bucket, so you don't run an HTTP receiver whose only job is to forward webhooks. Subscriptions, filters, transforms, retries, the circuit breaker, the DLQ, replays and tracing work the same as for HTTPS endpoints.
If you have no queue and can't accept inbound HTTP, use a polling endpoint instead. Your consumer then pulls messages from Hookbase with a cursor.
Creating one
In the dashboard, go to Outbound → Endpoints → Create Endpoint and choose a Delivery type. With the API, set endpointType and put the settings in destination:
curl -X POST https://api.hookbase.app/api/organizations/$ORG_ID/webhook-endpoints \
-H "Authorization: Bearer $HOOKBASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"applicationId": "'$APP_ID'",
"endpointType": "sqs",
"destination": {
"queueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/orders",
"accessKeyId": "AKIA...",
"secretAccessKey": "..."
}
}'The response's url is a display URI such as sqs://us-east-1/123456789012/orders. destination echoes the settings back, but never a credential. You get only accessKeyIdHint (••••WXYZ) or serviceAccountEmail, plus hasCredentials. Credentials are encrypted at rest.
To change the settings, PATCH the endpoint with a new destination. If you leave the credential fields out, the stored ones are kept. Changing endpointType also needs the new type's full settings and credentials, or a url when you switch back to http.
headers, authentication, useStaticIp and successStatusCodes apply only to HTTPS endpoints, and the API rejects them for these types. To restrict access, use the provider's IAM policy instead.
What gets published
- Body: the payload exactly as it would have been POSTed to an HTTPS endpoint, after any transform. It's the same bytes the signature covers.
- Attributes: the Standard Webhooks headers, as message attributes (SQS, SNS, Pub/Sub) or object metadata (S3):
| Attribute | Value |
|---|---|
webhook-id | The message id (the same across retries) |
webhook-timestamp | Unix seconds when it was signed |
webhook-signature | v1,... (HMAC) or v1a,... (Ed25519) |
hookbase-event-type | The event type, e.g. order.created |
content-type | The payload's content type |
traceparent | The W3C trace context, when tracing is on |
EventBridge has no message attributes, so it gets the same values in the event's detail. See EventBridge.
To verify a message, pass the attributes to your Standard Webhooks library in place of the HTTP headers, and the body as the payload.
Retries and failures
Each try is recorded as a delivery attempt. Its status is the provider API's HTTP status, and its error is the provider's error code (AccessDenied, ThrottlingException, ...).
- Retried on the endpoint's normal schedule: throttling, provider 5xx errors, timeouts and network errors.
- Dead-lettered immediately, with the reason Destination rejected and the provider's error: authentication and permission errors, a missing queue, topic or bucket, and other 4xx errors. Retrying these would only fail the same way. Fix the policy or the settings, then retry the message from the DLQ.
Repeated failures open the circuit breaker, as they do for HTTPS endpoints.
Test sends
Send test publishes a real, signed test message (test.event by default) to the destination and shows the provider's response, so you can check your IAM policy before any events go out.