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:
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"
}'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 webhookconst 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 webhookResponse (immediate):
{
"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:
{
"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:
{
"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:
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)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
| Field | Type | Description |
|---|---|---|
id | string | Task ID |
model | string | Model slug (e.g. google/nano-banana-pro/text-to-image) |
status | string | completed or failed |
created_at | string | ISO 8601 timestamp |
input | object | The original request parameters |
outputs | string[] | Output URLs (only when completed) |
error | string | Error 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