Skip to content

Webhook Mode

Webhook mode returns a task ID immediately and sends the result to your callback URL when the task completes. No polling needed.

Prerequisites

Make sure you have an API key. See Get Started with API for setup instructions.

Step 1: Submit a Task with Webhook

Add ?webhook=YOUR_CALLBACK_URL to the submit endpoint:

bash
curl -X POST "https://api.get3w.com/v1/google/nano-banana-pro/text-to-image?webhook=https://your-server.com/callback" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A sunset over mountains",
    "aspect_ratio": "16:9",
    "resolution": "1k",
    "output_format": "png",
    "channel": "stable"
  }'
python
import requests

response = requests.post(
    "https://api.get3w.com/v1/google/nano-banana-pro/text-to-image",
    params={"webhook": "https://your-server.com/callback"},
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json"
    },
    json={
        "prompt": "A sunset over mountains",
        "aspect_ratio": "16:9",
        "resolution": "1k",
        "output_format": "png",
        "channel": "stable"
    }
)

task = response.json()
print(task["id"])  # Task is running; result will be sent to your webhook
javascript
const apiKey = "YOUR_API_KEY";
const webhookUrl = encodeURIComponent("https://your-server.com/callback");

const response = await fetch(
    `https://api.get3w.com/v1/google/nano-banana-pro/text-to-image?webhook=${webhookUrl}`,
    {
        method: "POST",
        headers: {
            "Authorization": `Bearer ${apiKey}`,
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            prompt: "A sunset over mountains",
            aspect_ratio: "16:9",
            resolution: "1k",
            output_format: "png",
            channel: "stable"
        })
    }
);

const task = await response.json();
console.log(task.id);  // Result will be sent to your webhook

Response (immediate):

json
{
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "created",
  "estimated_duration": 52
}

Step 2: Receive the Webhook

When the task completes (or fails), Get3W sends a POST request to your callback URL with the result:

json
{
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "model": "google/nano-banana-pro/text-to-image",
  "status": "completed",
  "created_at": "2026-03-28T07:50:42",
  "input": {
    "prompt": "A sunset over mountains",
    "aspect_ratio": "16:9",
    "resolution": "1k",
    "output_format": "png",
    "channel": "stable"
  },
  "outputs": [
    "https://storage.example.com/output.png"
  ]
}

If the task fails, the payload includes an error field instead of outputs:

json
{
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "model": "google/nano-banana-pro/text-to-image",
  "status": "failed",
  "created_at": "2026-03-28T07:50:42",
  "error": "Invalid input: prompt is required"
}

Step 3: Handle the Webhook

Here's a minimal server that receives webhook callbacks:

python
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/callback", methods=["POST"])
def webhook_handler():
    data = request.json

    if data["status"] == "completed":
        print(f"Task {data['id']} completed!")
        print(f"Outputs: {data['outputs']}")
    elif data["status"] == "failed":
        print(f"Task {data['id']} failed: {data['error']}")

    return jsonify({"received": True}), 200

if __name__ == "__main__":
    app.run(port=3000)
javascript
const express = require("express");
const app = express();

app.use(express.json());

app.post("/callback", (req, res) => {
    const data = req.body;

    if (data.status === "completed") {
        console.log(`Task ${data.id} completed!`);
        console.log(`Outputs: ${data.outputs}`);
    } else if (data.status === "failed") {
        console.log(`Task ${data.id} failed: ${data.error}`);
    }

    res.json({ received: true });
});

app.listen(3000, () => console.log("Webhook server running on port 3000"));

Webhook Payload Fields

FieldTypeDescription
idstringTask ID
modelstringModel slug (e.g. google/nano-banana-pro/text-to-image)
statusstringcompleted or failed
created_atstringISO 8601 timestamp
inputobjectThe original request parameters
outputsstring[]Output URLs (only when completed)
errorstringError message (only when failed)

Retry Policy

Get3W retries webhook delivery up to 3 times with exponential backoff (2s, 4s, 8s) if your server returns a non-2xx status code or is unreachable.

When to Use Webhook Mode

  • Server-to-server integrations — No need to keep a connection open or run a polling loop
  • Event-driven architectures — Trigger downstream workflows when a task completes
  • High-throughput pipelines — Submit hundreds of tasks and process results as they arrive

TIP

Your webhook URL must be publicly accessible. For local development, use a tunneling tool like ngrok to expose your local server.

Next Steps

  • Sync Mode — Simplest approach for quick tasks
  • Async Mode — Poll for results instead of using webhooks

Released under the MIT License.