Webhooks
Receive real-time notifications when session statuses change, eliminating the need for continuous polling.
Quick Setup
- Navigate to your Dashboard Profile Settings
- In Developer Settings, enter your webhook URL
- Save settings
Your endpoint will receive notifications for all session status changes.
Webhook Event
session_status_changed
Triggered when a session transitions between statuses (e.g., incomplete
→ complete
or incomplete
→ failed
).
Available for all session types: image_to_3d
, multiview_to_3d
, text_to_image
, image_to_kit
, retopology
, animation
.
Payload Structure
Webhook Payload Schema
Field | Type | Description |
---|---|---|
type | string | Event type. Always "session_status_changed" |
payload | object | Event payload containing session details |
payload.session_id | string | Unique session identifier |
payload.user_id | string | User identifier who owns the session |
payload.session_type | string | Type of session (image_to_3d , multiview_to_3d , etc.) |
payload.old_status | string | Previous session status |
payload.new_status | string | New session status |
payload.timestamp | string | ISO 8601 timestamp of the status change |
payload.session_data | object | Complete session object - see schema below |
Session Data Schema
The session_data
field contains the complete session object as defined in the API specification. The structure varies by session type. Here’s an example for Image to 3D sessions:
For other session types, refer to their specific documentation pages.
Note: Large embedding arrays (input_image_embedding
fields) are automatically removed from the payload to optimize size and delivery speed.
Example Payload
{
"type": "session_status_changed",
"payload": {
"session_id": "SESSION_1756711515_3265503",
"user_id": "681dcde5253883b154accfde",
"session_type": "image_to_3d",
"old_status": "incomplete",
"new_status": "complete",
"timestamp": "2025-09-01T07:26:51.484Z",
"session_data": {
/* Complete session object as per API schema above */
}
}
}
Delivery Details
- Method: HTTP POST with
Content-Type: application/json
- Timeout: 5 seconds
- Retries: 3 attempts with exponential backoff (2s, 4s, 8s delays)
- Expected Response: Return
2xx
status code - Async Processing: Webhook failures don’t affect session processing
Implementation
Basic Handler
// Node.js/Express
app.post('/webhook', express.json(), (req, res) => {
const { type, payload } = req.body;
if (type === 'session_status_changed') {
const { session_id, new_status, session_data } = payload;
if (new_status === 'complete') {
// Handle completed session
processCompletedSession(session_data);
} else if (new_status === 'failed') {
// Handle failed session
handleFailure(session_data);
}
}
res.status(200).send('OK');
});
# Python/Flask
@app.route('/webhook', methods=['POST'])
def webhook():
data = request.get_json()
if data['type'] == 'session_status_changed':
payload = data['payload']
if payload['new_status'] == 'complete':
process_completed_session(payload['session_data'])
elif payload['new_status'] == 'failed':
handle_failure(payload['session_data'])
return '', 200
Best Practices
- Use HTTPS for your webhook endpoint
- Respond quickly (under 5 seconds) to avoid timeouts
- Handle duplicates - implement idempotency using
session_id
+timestamp
- Log webhook receipts for debugging
- Queue heavy processing - respond immediately, process asynchronously
Testing
Use ngrok for local development:
ngrok http 3000
# Use the HTTPS URL: https://abc123.ngrok.io/webhook
Requirements
- Publicly accessible HTTPS URL (HTTP allowed for testing)
- Must accept POST requests
- Should return 200-299 status codes
- Must respond within 5 seconds
Advantages over Polling
- Real-time notifications
- Reduced API usage
- Lower latency
- More efficient resource usage