Skip to main content
Receive task results via HTTP callbacks instead of polling.

Overview

When using callback mode, APIXO sends a POST request to your specified URL when a task completes. This eliminates polling overhead and provides immediate notifications — ideal for high-volume production applications.

Setup

1

Create a webhook endpoint

Your endpoint must accept POST requests, respond with HTTP 200 within 30 seconds, and be publicly accessible via HTTPS.
If your endpoint does not respond with HTTP 200 within 30 seconds, APIXO will retry delivery up to 3 times with increasing delays.
const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhook/apixo', (req, res) => {
  const { taskId, state, resultJson, failCode, failMsg } = req.body.data;
  
  if (state === 'success') {
    const urls = JSON.parse(resultJson).resultUrls;
    console.log('Generated:', urls);
  } else if (state === 'failed') {
    console.error(`Task ${taskId} failed: ${failCode} - ${failMsg}`);
  }
  
  res.status(200).send('OK');
});

app.listen(3000);
2

Submit a task with callback

Include request_type: "callback" and your callback_url in the request:
curl -X POST https://api.apixo.ai/api/v1/generateTask/nano-banana \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_type": "callback",
    "callback_url": "https://your-domain.com/webhook/apixo",
    "input": {
      "mode": "text-to-image",
      "prompt": "A beautiful landscape"
    }
  }'

Webhook Payload

Success

{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "task_abc123xyz",
    "state": "success",
    "resultJson": "{\"resultUrls\":[\"https://cdn.apixo.ai/output/abc.jpg\"]}",
    "costTime": 12500,
    "createTime": 1704067200000,
    "completeTime": 1704067212500
  }
}

Failure

{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "task_abc123xyz",
    "state": "failed",
    "failCode": "CONTENT_VIOLATION",
    "failMsg": "Content violates usage policy",
    "createTime": 1704067200000,
    "completeTime": 1704067205000
  }
}

Payload Fields

taskId
string
Unique task identifier.
state
string
Final task state: success or failed.
resultJson
string
JSON string containing resultUrls array. Only present on success.
costTime
integer
Processing time in milliseconds.
failCode
string
Error code. Only present on failure.
failMsg
string
Human-readable error message. Only present on failure.

Retry Policy

If your webhook endpoint fails to respond with HTTP 200:
AttemptDelay
1st retry30 seconds
2nd retry2 minutes
3rd retry10 minutes
After 3 failed attempts, the webhook is abandoned. You can still query task status via the Status Task endpoint.

Security Recommendations

Implement Idempotency

Webhooks may be delivered more than once. Use taskId to deduplicate and prevent processing the same result twice.
const processedTasks = new Set();

app.post('/webhook/apixo', (req, res) => {
  const { taskId } = req.body.data;
  
  if (processedTasks.has(taskId)) {
    return res.status(200).send('Already processed');
  }
  
  processedTasks.add(taskId);
  // Process the task...
  
  res.status(200).send('OK');
});

Use HTTPS Only

Always use HTTPS for your webhook endpoint to ensure data is encrypted in transit.

Testing Webhooks

Use ngrok to expose your local server during development:
ngrok http 3000
# Returns: https://abc123.ngrok.io — use this as your callback_url
You can still query task status via the API even when using callback mode, which is useful for debugging.