Webhooks

Receive task results automatically via HTTP POST instead of polling. Every mutating endpoint accepts optional webhook configuration.

How It Works

When you include webhook_urlin your request, we'll POST the completed task result to that URL when the task finishes (or fails).

If you also include webhook_secret, we'll send it as the x-webhook-secret header so you can verify the request came from us.

Webhook Fields

FieldTypeDescription
webhook_urlstringHTTPS URL that accepts POST requests. Must respond with 2xx within 10 seconds.
webhook_secretstringArbitrary string sent as x-webhook-secret header for verification.

Webhook Delivery

POST https://your-server.com/webhook
Content-Type: application/json
x-webhook-secret: my-secret-123

{
  "task_id": "550e8400-e29b-41d4-a716-446655440000",
  "task_type": "imagine",
  "status": "finished",
  "percentage": "100",
  "original_image_url": "https://cdn.midjourney.com/abc123/grid_0.png",
  "image_urls": [
    "https://cdn.midjourney.com/abc123/0_0.png",
    "https://cdn.midjourney.com/abc123/0_1.png",
    "https://cdn.midjourney.com/abc123/0_2.png",
    "https://cdn.midjourney.com/abc123/0_3.png"
  ]
}

Failure Webhook

{
  "task_id": "550e8400-e29b-41d4-a716-446655440000",
  "task_type": "imagine",
  "status": "failed",
  "error": "Content policy violation"
}

Retry Policy

  • We retry failed webhook deliveries up to 3 times with exponential backoff.
  • Retry intervals: ~10s, ~30s, ~90s after the initial failure.
  • A delivery is considered failed if your server doesn't respond with a 2xx status within 10 seconds.
  • After all retries are exhausted, the webhook is marked as undeliverable. The task result is still available via /fetch.

Best Practices

  • 1. Always use HTTPS for your webhook URL.
  • 2. Verify the x-webhook-secret header matches what you sent.
  • 3. Respond with 200 quickly, then process the payload asynchronously.
  • 4. Handle duplicate deliveries (idempotency) — use task_id as a deduplication key.
  • 5. Use /fetch as a fallback if you suspect a webhook was missed.