Skip to main content

Setting Up Webhooks

Pass callback_url when creating a generation to receive notifications:
curl -X POST https://platform.runblob.io/v1/gemini/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A cute orange cat",
    "callback_url": "https://your-server.com/webhook"
  }'

Webhook Payload

When generation completes (success or failure), we send a POST request to your callback_url:

Success Payload

{
  "task_uuid": "ffd473d5-5bef-4e14-bf22-8d559be3c19f",
  "status": "completed",
  "result_image_url": "https://storage.runblob.io/nanobanana/outputs/2025/12/ffd473d5.png",
  "message": null
}

Failure Payload

{
  "task_uuid": "ffd473d5-5bef-4e14-bf22-8d559be3c19f",
  "status": "failed",
  "result_image_url": null,
  "message": "MODERATION_FAILED"
}

Webhook Fields

task_uuid
string
UUID of the completed generation
status
string
Final status: "completed" or "failed"
result_image_url
string
URL of generated image (only for completed status)
message
string
Error code if failed, otherwise null

Handling Webhooks

from flask import Flask, request

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    data = request.json
    
    if data['status'] == 'completed':
        print(f"Image ready: {data['result_image_url']}")
        # Download and process the image
    else:
        print(f"Generation failed: {data['message']}")
        # Handle error
    
    return 'OK', 200

Best Practices

Verify that webhook requests are coming from RunBlob by checking the request origin or implementing signature verification.
Return a 2xx response within 5 seconds. Process the webhook asynchronously if needed.
Implement idempotency - we may retry failed webhook deliveries. Use task_uuid to deduplicate.
Always use HTTPS endpoints for webhooks to ensure secure data transmission.
If your webhook endpoint returns an error (4xx/5xx) or times out, we will retry up to 3 times with exponential backoff.