Skip to Content

Webhooks

Webhooks allow you to receive real-time notifications when specific events occur in your account, such as when a video upload is completed or when a connected account requires re-authentication.

Base URL

https://api.multi-upload-tool.com/api/v1

Authentication

All requests require an API Token in the header: x-api-key: YOUR_API_TOKEN


Supported Events

The following events can trigger a webhook notification:

Event NameDescription
upload.completedTriggered when a video or post is successfully published to a platform.
upload.failedTriggered when a publication fails.
upload.scheduledTriggered when a post is scheduled for later. data includes uploadId, platform, accountId and scheduledFor.
upload.cancelledTriggered when a scheduled post is cancelled before it went out. Same data as upload.scheduled.
upload.changes_requestedA post awaiting approval was sent back to draft, by your client (review link) or an owner/admin. data includes uploadId, platform, reviewedBy (client or team) and comment.
upload.approvedA post awaiting approval was approved and is now scheduled or publishing. data includes uploadId, platform, reviewedBy, scheduledFor.
connected_account.connectedTriggered when a new social media account is connected.
connected_account.disconnectedTriggered when a social media account is disconnected.
connected_account.expiredTriggered when an account’s access token expires and requires reconnection.
connected_account.refresh_failedTriggered when the system fails to refresh an expired access token automatically.
subscription.createdTriggered when a new subscription is created.
subscription.updatedTriggered when a subscription is updated (e.g. plan change).
subscription.cancelledTriggered when a subscription is cancelled.
subscription.expiredTriggered when a subscription expires.
suggestion.createdTriggered when a new suggestion or feedback item is created.
suggestion.updatedTriggered when the status of a suggestion is updated (e.g. approved, implemented).
security.loginTriggered when a user logs in to the account (security audit).
team.inviteTriggered when a new member is invited to the team.

Payload Structure

All webhook requests are sent as POST requests with a JSON body. The payload follows a standard envelope format:

{ "id": "evt_V1StGXR8_Z5jdHi6B-myT", "event": "upload.completed", "createdAt": "2026-01-01T12:00:00.000Z", "data": { // Event-specific data } }

Example: Upload Completed Payload

{ "id": "evt_abc123", "event": "upload.completed", "createdAt": "2026-01-01T12:00:00.000Z", "data": { "uploadId": 123, "platform": "tiktok", "status": "completed", "metadata": { "videoId": "73123456789", "shareUrl": "https://www.tiktok.com/@user/video/73123456789" } } }

Delivery & Retries

  • Your endpoint must answer with a 2xx status within 10 seconds. Anything else (a 4xx, a 5xx, a redirect, a timeout) is a failed attempt.
  • A failed attempt is retried 5 more times: after 30 seconds, 2 minutes, 10 minutes, 1 hour and 6 hours (about 7 hours in total).
  • Every attempt carries the same X-Webhook-ID. Use it to ignore an event you already processed: a retry or a replay can reach you after a success you did not acknowledge in time.
  • A webhook is disabled only after 3 events in a row failed all their attempts. You get an email, and you can enable it again with PATCH /webhooks/:id.
  • Every attempt is recorded in the delivery log for 30 days.

Security & Verification

To ensure that the webhook requests are coming from us, we include a signature in the headers. You should verify this signature using your webhook secret.

Headers

HeaderDescription
X-Webhook-EventThe name of the event (e.g., upload.completed).
X-Webhook-IDThe unique ID of the event.
X-Webhook-TimestampThe timestamp of the request.
X-Webhook-SignatureThe HMAC SHA-256 signature, computed with the secret current when the attempt is sent.

Verifying the Signature

The signature is generated using HMAC SHA-256 with your webhook secret. The data to sign is constructed as: timestamp + "." + JSON.stringify(payload)

Node.js Example

const crypto = require('crypto'); function verifySignature(payload, signature, secret, timestamp) { const data = `${timestamp}.${JSON.stringify(payload)}`; const expectedSignature = crypto .createHmac('sha256', secret) .update(data) .digest('hex'); return signature === expectedSignature; }

Python Example

import hmac import hashlib def verify_signature(payload, signature, secret, timestamp): data = f"{timestamp}.{payload}" expected_signature = hmac.new( secret.encode(), data.encode(), hashlib.sha256 ).hexdigest() return hmac.compare_digest(signature, expected_signature)

Manage Webhooks

List Webhooks

Retrieve all configured webhooks for your account.

Endpoint

GET /webhooks

Example Request

curl -X GET "https://api.multi-upload-tool.com/api/v1/webhooks" \ -H "x-api-key: YOUR_API_TOKEN"

Example Response

{ "success": true, "data": [ { "id": 1, "url": "https://your-api.com/webhooks", "events": ["upload.completed", "upload.failed"], "isActive": true, "failureCount": 0, "createdAt": "2026-01-01T10:00:00.000Z", "updatedAt": "2026-01-01T10:00:00.000Z" } ] }

Create Webhook

Register a new webhook endpoint to receive event notifications.

Endpoint

POST /webhooks

Body Parameters

ParameterTypeRequiredDescription
urlstringYesThe HTTPS URL where the webhook payloads will be sent.
eventsstring[]YesArray of event names to subscribe to (e.g., upload.completed).
secretstringNoOptional custom secret for signature verification. If omitted, one will be generated for you.

Example Request

curl -X POST "https://api.multi-upload-tool.com/api/v1/webhooks" \ -H "x-api-key: YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-api.com/webhooks", "events": ["upload.completed", "upload.failed", "connected_account.expired"], "secret": "my-custom-secret-key" }'

Example Response

{ "success": true, "data": { "id": 2, "url": "https://your-api.com/webhooks", "events": ["upload.completed", "upload.failed", "connected_account.expired"], "secret": "my-custom-secret-key", "isActive": true, "createdAt": "2026-01-01T12:00:00.000Z" } }

Test Webhook

Trigger a test event to verify your endpoint configuration. This sends a mock ping event to your webhook URL.

Endpoint

POST /webhooks/:id/test

Example Request

curl -X POST "https://api.multi-upload-tool.com/api/v1/webhooks/2/test" \ -H "x-api-key: YOUR_API_TOKEN"

Example Response

{ "success": true, "message": "Test webhook sent successfully" }

Delete Webhook

Remove a webhook configuration.

Endpoint

DELETE /webhooks/:id

Example Request

curl -X DELETE "https://api.multi-upload-tool.com/api/v1/webhooks/2" \ -H "x-api-key: YOUR_API_TOKEN"

Example Response

{ "success": true, "message": "Webhook deleted" }

List Deliveries

Every delivery attempt, newest first. An event that failed twice then succeeded shows 3 rows with the same eventId.

Endpoint

GET /webhooks/:id/deliveries?limit=50

limit is at most 200.

Example Response

{ "success": true, "data": [ { "id": 812, "eventId": "evt_V1StGXR8_Z5jdHi6B-myT", "event": "upload.completed", "attempt": 3, "success": true, "statusCode": 200, "error": null, "durationMs": 184, "payload": { "id": "evt_V1StGXR8_Z5jdHi6B-myT", "event": "upload.completed", "createdAt": "2026-09-23T10:00:00.000Z", "data": { "uploadId": 123 } }, "createdAt": "2026-09-23T10:02:31.000Z" }, { "id": 811, "eventId": "evt_V1StGXR8_Z5jdHi6B-myT", "event": "upload.completed", "attempt": 2, "success": false, "statusCode": 502, "error": "502 Bad Gateway", "durationMs": 97, "createdAt": "2026-09-23T10:00:31.000Z" } ] }

Replay a Delivery

Sends an event again, with its original id — for example after fixing your endpoint. The replay gets its own attempts and retries.

Endpoint

POST /webhooks/:id/deliveries/:deliveryId/replay

Returns 409 if the webhook is disabled: enable it first.

curl -X POST "https://api.multi-upload-tool.com/api/v1/webhooks/2/deliveries/811/replay" \ -H "x-api-key: YOUR_API_TOKEN"
{ "success": true, "data": { "eventId": "evt_V1StGXR8_Z5jdHi6B-myT" } }

Rotate the Secret

Generates a new signing secret and returns it. It applies immediately, including to retries already queued: update your endpoint with the new secret right away.

Endpoint

POST /webhooks/:id/rotate-secret

{ "success": true, "data": { "secret": "5f0c2a8e7d1b4c3e9a612b8f4e1d9c07..." } }

Enable or Disable a Webhook

Enable a webhook that was disabled after repeated failures, or pause one without deleting it.

Endpoint

PATCH /webhooks/:id

curl -X PATCH "https://api.multi-upload-tool.com/api/v1/webhooks/2" \ -H "x-api-key: YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"isActive": true}'

Team members with the MEMBER role cannot replay, rotate or enable webhooks.