Webhooks
Receive real-time task completion notifications
Receive task results via HTTP callbacks instead of polling.
When using callback mode, APIXO sends a POST request to your specified URL when a task completes.
Benefits:
- No polling overhead
- Immediate notification
- Reduced API calls
- Better for high-volume applications
Your endpoint must:
- Accept POST requests
- Respond with HTTP 200 within 30 seconds
- Be publicly accessible via HTTPS
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);
// Process your images/videos
} else if (state === 'failed') {
console.error(`Task ${taskId} failed: ${failCode} - ${failMsg}`);
}
res.status(200).send('OK');
});
app.listen(3000);
{
"request_type": "callback",
"callback_url": "https://your-domain.com/webhook/apixo",
"input": {
"mode": "text-to-image",
"prompt": "A beautiful landscape"
}
}
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"
}
}'
{
"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
}
}
{
"code": 200,
"message": "success",
"data": {
"taskId": "task_abc123xyz",
"state": "failed",
"failCode": "CONTENT_VIOLATION",
"failMsg": "Content violates usage policy",
"createTime": 1704067200000,
"completeTime": 1704067205000
}
}
If your webhook endpoint fails to respond with HTTP 200:
| Attempt | Delay |
|---|
| 1st retry | 30 seconds |
| 2nd retry | 2 minutes |
| 3rd retry | 10 minutes |
After 3 failed attempts, the webhook is abandoned. You can still query task status via the API.
app.post('/webhook/apixo', (req, res) => {
// Verify the request comes from APIXO
const signature = req.headers['x-apixo-signature'];
const timestamp = req.headers['x-apixo-timestamp'];
// Implement signature verification
// (Contact support for signature details)
// Process webhook...
res.status(200).send('OK');
});
Always use HTTPS for your webhook endpoint to ensure data is encrypted in transit.
Webhooks may be delivered more than once. Use taskId to track processed requests:
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 ngrok to expose your local server:
ngrok http 3000
# Returns: https://abc123.ngrok.io
# Use this URL as callback_url
You can still query task status even when using callback mode:
curl "https://api.apixo.ai/api/v1/statusTask/nano-banana?taskId=task_abc123" \
-H "Authorization: Bearer YOUR_API_KEY"