Unified API Webhook
Introduction
To ensure timely updates and notifications, we offer webhook services integrated with our unified API. When you create a task, you can specify a webhook endpoint. Our API service will then send an HTTP POST request to this URL whenever a task succeeds, fails, or has a status update.
Webhooks are particularly useful in the following scenarios:
- Persisting Result Data and Files: Input and output data (including any files) are automatically deleted after a certain period. Webhooks allow you to receive all metadata for a completed task, enabling you to store it in a database or save the output files to persistent storage before they are removed.
- Notification for Long-Running Tasks: Some tasks may take several minutes to complete. By using a webhook handler, you can send notifications—such as an email or a Slack message—when a task is completed.
- Creating Model Pipelines: Webhooks can be used to capture the output of one long-running task and feed it into another model as input, facilitating seamless automation.
Supported models
- midjourney(through unified api)
- suno(through unified api)
- luma(through unified api)
- kling(through unified api)
- flux
- faceswap(through unified api)
- ai-hug-video
Set Up Webhook
To use webhooks, add the webhook_config
field in the request body when creating a task. Specify the endpoint and secret as shown in the example below:
//POST https://api.goapi.ai/api/v1/task
{
"model": "suno/v3-chorip",
"task_type": "lyrics",
"input": {},
"config": {
"webhook_config": {
"endpoint": "",
"secret": ""
}
}
}
Field | Description | Details |
---|---|---|
endpoint | The URL to send the webhook to | Ensure that the server receiving the notification can be accessed by Cloudflare worker |
secret | Field to verify the request source | If a secret is set, we will include this value in the x-webhook-secret header of the webhook request |
Receive Webhook
GoAPI will send an HTTP POST request to the specified URL whenever a task is created, logs new information, produces new output, or is completed.
The request body is formatted in JSON and contains two main parts: timestamp
and data
. The timestamp
can be used to detect duplicate notifications (e.g., in cases where a retry mechanism leads to multiple notifications). The data
structure aligns with the data
returned by the unified fetch API.
{
"timestamp": 1723018391,
"data": {}
}
Field | Description | Details |
---|---|---|
timestamp | Timestamp | Unix timestamp, used to confirm whether it is a duplicate notification |
data | Task data | Task data, consistent with the data part of the fetch interface |
Here is an example of a webhook request for a Luma video generation task:
{
"timestamp": 1724511853,
"data": {
"task_id": "58cb41b7-556d-46c0-b82e-1e116aa1a31a",
"model": "luma",
"task_type": "video_generation",
"status": "completed",
"config": {
"webhook_config": {
"endpoint": "https://webhook.site/1fbfe428-3e78-43be-8e98-1ede95750d25",
"secret": "123456"
}
},
"input": {
"aspect_ratio": "16:9",
"expand_prompt": true,
"image_end_url": "https://i.imgur.com/CSmEZud.png",
"image_url": "https://i.imgur.com/eJkSUnA.png",
"loop": false,
"user_prompt": ""
},
"output": {
"generation": {
"id": "ab9124ef-49d4-4da7-bf12-0c3891a3cca8",
"prompt": "",
"state": "completed",
"created_at": "2024-08-24T15:01:52.727Z",
"video": {
"url": "https://storage.cdn-luma.com/dream_machine/49995d70-d0f3-4b0d-afb0-ec034107e4e2/watermarked_video08fe0802a4e104f1a80fb6c6c658710ee.mp4",
"url_no_watermark": "https://img.midjourneyapi.xyz/ephemeral/db7420f9-8a24-48fd-ade5-ede803e835db.mp4",
"width": 1168,
"height": 864,
"thumbnail": ""
},
"like": null,
"estimate_wait_seconds": null
}
},
"meta": {
"created_at": "2024-08-24T23:01:12.3556324+08:00",
"started_at": "2024-08-24T23:01:36.7432691+08:00",
"ended_at": "2024-08-24T23:04:13.5301322+08:00",
"usage": {
"type": "luma_quota",
"frozen": 30,
"consume": 30
}
},
"detail": {
"account_id": 1,
"is_using_private_pool": false
},
"logs": [],
"error": {
"code": 0,
"message": ""
}
}
}
-
The status property will have one of the following values:
pending
: the system has received your request, but it has not yet started the prediction.processing
: the model is currently running.failed
: the prediction encountered an error during processing.completed
: the prediction completed successfully.
-
In webhook notifications, the
output
field within thedata
structure is particularly important as it represents the result (or latest progress) of the task. The content of the output field varies depending on the model and task type.- Suno
- Audio generation and audio stitching
{ "clips": [] // Same as the current fetch interface, returns a list of clips }
- Audio upload
{ "title": "", "clip_id": "", "duration": 10, "image_url": "" }
- Lyrics generation
{ "title": "", "text": "" }
- Luma
- Video generation and extension
{ "generation": [] // Same as the current fetch interface }
- Kling
- Video generation and extension
{ "task": {}, // Same as the current fetch interface "works": [] // Same as the current fetch interface }
- Suno
Your endpoint must quickly return a successful status code (2xx) prior to any complex logic that could cause a timeout.
Handling webhook deliveries
Set up an HTTP or HTTPS endpoint function that can accept webhook requests with a POST method. If you’re still developing your endpoint function on your local machine, it can use HTTP. After it’s publicly accessible, your webhook endpoint function must use HTTPS.
Set up your endpoint function so that it:
- Handles POST requests with a JSON payload consisting of an event object.
- Quickly returns a successful status code (2xx) prior to any complex logic that could cause a timeout.
Here's an example of a Next.js webhook handler:
export default async function handler(req, res) {
console.log("🪝 incoming webhook!", req.body.data.taskid);
const prediction = req.body;
await saveToMyDatabase(prediction);
await sendSlackNotification(prediction);
res.end();
}
Retries
When GoAPI sends the final webhook notification for a task (with a status of succeeded, failed, or canceled), we monitor the response status. If the request fails or receives a 4xx or 5xx response, we will retry the webhook. Retries occur after 5 seconds, with a maximum of 3 attempts for each notification.
Best Practices for Using Webhooks
-
Use HTTPS for Secure Communication: Always ensure that your server uses
HTTPS
to secure communication between your application and the webhook sender.HTTPS
encrypts data in transit, protecting sensitive information from potential interception. -
Timestamp Verification: GoAPI includes a
timestamp
field in the webhook request body. Proper handling of thistimestamp
is crucial for security and data integrity:
- Prevent Replay Attacks: Compare the
timestamp
in the webhook request against your system's currenttimestamp
. If the difference exceeds an acceptable threshold, reject the request to prevent replay attacks. - Deduplication: Implement logic to deduplicate webhook notifications based on the
timestamp
. Given that webhooks might be retried, earlier notifications could arrive after more recent ones. By using thetimestamp
, you can ensure that each event is processed only once.
- Test and Debug Webhooks Efficiently: We recommend testing and debugging your webhooks using a service like webhook.site (opens in a new tab). This tool allows you to easily capture and inspect webhook requests, ensuring your integration works correctly before deploying it to production.