Webhook Delivery and Retries

Inspect webhook delivery history and understand retry and rate behavior

AuthOS release 0.8.2 API v1 Latest-only documentation
Updated Jul 15, 2026 Edit this page
On this page

Webhook Delivery

GET /api/organizations/:org_slug/webhooks/:webhook_id/deliveries

Get paginated delivery history for a webhook, including request payload, response status, and retry information.

Authentication: Required (Organization Management JWT)

Permissions: Organization owner or admin

Path Parameters:

Parameter Type Description
org_slug string Organization slug
webhook_id string Webhook ID

Query Parameters:

Parameter Type Required Default Description
page integer No 1 Page number (minimum: 1)
limit integer No 50 Results per page (maximum: 100)
event_type string No - Filter by event type
delivered boolean No - Filter by delivery status (true/false)

Request Headers:

Authorization: Bearer {jwt_token}

Example Request:

curl -X GET "https://sso.example.com/api/organizations/acme-corp/webhooks/550e8400-e29b-41d4-a716-446655440000/deliveries?page=1&limit=20&event_type=user.login.success" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Response (200 OK):

{
  "deliveries": [
    {
      "id": "770e8400-e29b-41d4-a716-446655440222",
      "webhook_id": "550e8400-e29b-41d4-a716-446655440000",
      "webhook_name": "Production Webhook",
      "event_type": "user.login.success",
      "payload": {
        "event": "user.login.success",
        "timestamp": "2025-01-15T10:35:00Z",
        "organization_id": "org-123",
        "actor_user_id": "user-456",
        "actor_email": "user@example.com",
        "data": {
          "provider": "github",
          "service_id": "service-789"
        }
      },
      "response_status_code": 200,
      "response_body": "{\"status\":\"received\"}",
      "attempt_count": 1,
      "max_attempts": 5,
      "next_retry_at": null,
      "delivered": true,
      "delivery_error": null,
      "created_at": "2025-01-15T10:35:00Z",
      "updated_at": "2025-01-15T10:35:01Z"
    },
    {
      "id": "880e8400-e29b-41d4-a716-446655440333",
      "webhook_id": "550e8400-e29b-41d4-a716-446655440000",
      "webhook_name": "Production Webhook",
      "event_type": "user.signup.success",
      "payload": {
        "event": "user.signup.success",
        "timestamp": "2025-01-15T10:30:00Z",
        "organization_id": "org-123",
        "actor_user_id": "user-789",
        "actor_email": "newuser@example.com",
        "data": {
          "provider": "google",
          "service_id": "service-789"
        }
      },
      "response_status_code": 500,
      "response_body": "{\"error\":\"Internal Server Error\"}",
      "attempt_count": 3,
      "max_attempts": 5,
      "next_retry_at": "2025-01-15T10:45:00Z",
      "delivered": false,
      "delivery_error": "HTTP 500: Internal Server Error",
      "created_at": "2025-01-15T10:30:00Z",
      "updated_at": "2025-01-15T10:40:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 156,
    "total_pages": 8,
    "has_next": true,
    "has_prev": false
  }
}

Response Fields:

Delivery Object:

  • id (string): Delivery unique identifier
  • webhook_id (string): Webhook ID
  • webhook_name (string): Webhook name
  • event_type (string): Event type that triggered delivery
  • payload (object): Full webhook payload sent
  • response_status_code (integer, nullable): HTTP status code from target endpoint
  • response_body (string, nullable): Response body from target endpoint
  • attempt_count (integer): Number of delivery attempts
  • max_attempts (integer): Maximum retry attempts (5)
  • next_retry_at (string, nullable): ISO 8601 timestamp of next retry
  • delivered (boolean): Whether delivery was successful
  • delivery_error (string, nullable): Error message if delivery failed
  • created_at (string): ISO 8601 timestamp of first delivery attempt
  • updated_at (string): ISO 8601 timestamp of last delivery attempt

Pagination Object:

  • page (integer): Current page number
  • limit (integer): Results per page
  • total (integer): Total number of deliveries
  • total_pages (integer): Total number of pages
  • has_next (boolean): Whether there is a next page
  • has_prev (boolean): Whether there is a previous page

Error Responses:

  • 401 Unauthorized: Missing or invalid JWT token
  • 403 Forbidden: User is not an admin or owner
  • 404 Not Found: Organization or webhook not found

Retry Logic

Failed webhook deliveries are automatically retried with exponential backoff:

Retries provide additional attempts, not an exactly-once or eventual-delivery guarantee. The same delivery may be received more than once.

Retry Configuration:

  • Max Retries: 5 attempts total
  • Initial Delay: 5 seconds
  • Max Delay: 30 minutes
  • Backoff Formula: delay = base_delay × 2^(attempt - 1) + jitter
  • Jitter: 0-9 seconds (prevents thundering herd)

Retry Schedule Example:

  1. Attempt 1: Immediate
  2. Attempt 2: 5 seconds + jitter
  3. Attempt 3: 10 seconds + jitter
  4. Attempt 4: 20 seconds + jitter
  5. Attempt 5: 40 seconds + jitter (capped at 30 minutes)

Success Criteria:

  • HTTP status codes 2xx (200-299) are considered successful
  • All other status codes (3xx, 4xx, 5xx) trigger retries
  • Network timeouts and connection errors trigger retries

Retry Headers: Each retry includes headers indicating the attempt number:

X-Webhook-Delivery-Id: {delivery_id}
X-Webhook-Attempt: {attempt_number}

Best Practices for Webhook Endpoints:

  • Return 2xx status codes immediately upon receipt
  • Process webhooks asynchronously in background jobs
  • Implement idempotency using X-Webhook-Delivery-Id
  • Return non-2xx only for malformed payloads or authentication failures
  • Avoid long-running operations in webhook handlers

Rate Limiting

Webhook endpoints should implement rate limiting to prevent abuse:

Recommended Limits:

  • Per Webhook: 100 deliveries per minute
  • Per Organization: 1000 deliveries per minute across all webhooks

Rate Limit Headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1642244400