Relay Errors
All errors return a JSON body with error, code, and optional fields keys.
{
"error": "Human readable message",
"code": "service.error_name",
"fields": { "field_name": ["Validation error message"] }
}
Common errors
| Code | Status | Cause | Fix |
|---|
validation_error | 400 | Invalid request body or parameters. | Check the fields object for specific failures. |
unauthorized | 401 | Missing or invalid API key. | Add Authorization: Bearer <key> header. See Authentication. |
forbidden | 403 | Authenticated but not authorized for this webhook. | Verify you own the webhook and your key has required scopes. |
not_found | 404 | Webhook does not exist. | Check the ID. Webhooks are deleted after delivery or expiration. |
rate_limit_exceeded | 429 | Too many requests. | Back off and retry. See Rate Limits. |
Relay-specific errors
| Code | Status | Cause | Fix |
|---|
relay.delivery_failed | 500 | All retry attempts exhausted against target endpoint. | Verify target URL, ensure endpoint returns 2xx, check endpoint logs. |
relay.recipient_unreachable | 503 | DNS failure, connection timeout, or network error reaching target. | Confirm URL is publicly accessible, check DNS and SSL certificates. |
relay.webhook_timeout | 504 | Target endpoint took longer than 30 seconds to respond. | Return 200 immediately and process asynchronously. |
relay.signature_invalid | 400 | Signature verification failed. | Verify you sign the raw body with HMAC-SHA256 using your API key. |
Delivery guarantees
- At-least-once delivery. Webhooks may arrive more than once. Deduplicate using
X-Solenoid-Signature and X-Solenoid-Timestamp headers.
- No strict ordering. Webhooks are queued in order but delivery timing depends on network and endpoint latency.
Retry strategy
- 5xx and network errors: 3 retries with exponential backoff (1s, 2s, 4s).
- 4xx errors: no retry.
- After all retries fail, the webhook is marked
failed.
Next steps