Skip to main content
Webhooks deliver generation results to your server in real-time. Instead of polling GET /api/generations/:id repeatedly, you receive a single POST request when the generation is done.

Polling vs. webhooks

PollingWebhooks
SetupNo setup neededRequires a public HTTPS endpoint
LatencyDepends on poll intervalNear-instant notification
EfficiencyMany requests per generationOne request per generation
Best forQuick scripts, testingProduction applications

How to use webhooks

Add a webhook URL to your /api/run request:
curl -X POST https://api.artificialstudio.ai/api/run \
  -H "Content-Type: application/json" \
  -H "Authorization: YOUR_API_KEY" \
  -d '{
    "tool": "create-image",
    "input": {
      "prompt": "A mountain landscape at dawn"
    },
    "webhook": "https://your-server.com/webhook"
  }'
Webhook URLs must use HTTPS. Private or internal URLs (localhost, private IPs) are rejected for security.

Webhook payload

When a generation completes successfully, we send a POST request to your URL with these headers and body:

Headers

HeaderValue
Content-Typeapplication/json
X-Webhook-Sourceartificial-studio
X-Media-IdThe generation ID

Body

{
  "id": "507f1f77bcf86cd799439011",
  "status": "success",
  "tool": "create-image",
  "type": "image",
  "output": "https://files.artificialstudio.ai/generations/abc123.png",
  "thumbnail": "https://files.artificialstudio.ai/thumbnails/abc123.jpg",
  "createdAt": "2024-01-15T10:30:00.000Z"
}
FieldTypeDescription
idstringGeneration identifier
statusstringAlways success (webhooks are only sent on success)
toolstringTool used
typestringimage, video, audio, text, or object
outputstringURL to the generated media
thumbnailstring | nullThumbnail URL (null for audio)
createdAtstringISO 8601 timestamp

Example handlers

app.post('/webhook', express.json(), (req, res) => {
  const { id, output, tool, type } = req.body;

  console.log(`Generation ${id} completed: ${output}`);
  // Save to database, notify user, etc.

  res.status(200).send('OK');
});

Retries

If your endpoint does not return a 200 status, we retry with exponential backoff:
RetryDelay
15 seconds
215 seconds
31 minute
45 minutes
515 minutes
61 hour
76 hours
812 hours
924 hours
After 9 failed retries, the webhook is marked as failed.

Best practices

Return a 200 quickly. Your endpoint should respond within 5 seconds. Process the webhook data asynchronously if needed.
  • Handle duplicates — Retries may deliver the same webhook twice. Use the id field to deduplicate.
  • Validate the payload — Check that the data matches expected formats before processing.
  • Log everything — Keep logs of received webhooks for debugging.

Requirements

Your webhook endpoint must:
  • Be publicly accessible (no localhost or private IPs)
  • Use HTTPS
  • Accept POST requests with a JSON body
  • Return 200 to acknowledge receipt