Skip to Content

GraphQL API - Webhooks

Webhooks provide real-time notifications for order status updates in your Layer One platform. Track the order’s progress by either registering a webhook for asynchronous updates or querying for order details directly.

Webhook Schema

type Webhook { webhook_id: ID! created: DateTime! webhook_url: String! webhook_events: [String!]! } enum WebhookEvent { ORDER_UPDATED } type WebhookEvent { event: String! timestamp: DateTime! order: OrderEventData! } type OrderEventData { order_id: ID! order_status: String! failure_reason: String metadata: String }

Queries

Get All Webhooks

Lists all webhooks created by App (limited to 1). App has two ways of requesting the order status: querying for order details or via a webhook event.

query { webhooks { webhook_id created webhook_url webhook_events } }

Response:

{ "data": { "webhooks": [ { "webhook_id": "244d8058-035b-422d-821f-44eedbaa42a4", "created": "2025-06-05T06:43:04.000Z", "webhook_url": "https://local-api.integrated-projects.com/v1/webhooks/test", "webhook_events": [ "order.updated" ] } ] } }

Mutations

Create Webhook

Track the order’s progress by registering a webhook for asynchronous updates.

mutation CreateWebhook($webhook_url: String!) { createWebhook(webhook_url: $webhook_url) { webhook_id created webhook_url webhook_events } }

Variables:

{ "webhook_url": "https://local-api.integrated-projects.com/v1/webhooks/test" }

Response:

{ "data": { "createWebhook": { "webhook_id": "244d8058-035b-422d-821f-44eedbaa42a4", "created": "2025-06-05T06:43:04.000Z", "webhook_url": "https://local-api.integrated-projects.com/v1/webhooks/test", "webhook_events": [ "order.updated" ] } } }

Parameters

ParameterTypeDescriptionRequired
webhook_urlStringSupplied Webhook URL to receive order updates

Response Fields:

FieldTypeDescription
webhook_idIDWebhook identifier
createdDateTimeTime webhook was created
webhook_urlStringSupplied Webhook URL to receive order updates
webhook_eventsArrayOnly order.updated supported

Update Webhook

Update an existing webhook’s URL or configuration.

mutation UpdateWebhook( $webhook_id: ID! $webhook_url: String! ) { updateWebhook( webhook_id: $webhook_id webhook_url: $webhook_url ) { webhook_id created webhook_url webhook_events } }

Variables:

{ "webhook_id": "244d8058-035b-422d-821f-44eedbaa42a4", "webhook_url": "https://local-api.integrated-projects.com/v1/webhooks/test" }

Response:

{ "data": { "updateWebhook": { "webhook_id": "244d8058-035b-422d-821f-44eedbaa42a4", "created": "2025-06-05T06:43:04.000Z", "webhook_url": "https://local-api.integrated-projects.com/v1/webhooks/test", "webhook_events": [ "order.updated" ] } } }

Delete Webhook

Remove an existing webhook.

mutation DeleteWebhook($webhook_id: ID!) { deleteWebhook(webhook_id: $webhook_id) { webhook_id created webhook_url webhook_events } }

Variables:

{ "webhook_id": "244d8058-035b-422d-821f-44eedbaa42a4" }

Response:

{ "data": { "deleteWebhook": { "webhook_id": "244d8058-035b-422d-821f-44eedbaa42a4", "created": "2025-06-05T06:43:04.000Z", "webhook_url": "https://local-api.integrated-projects.com/v1/webhooks/test", "webhook_events": [ "order.updated" ] } } }

Parameters

ParameterTypeDescriptionRequired
webhook_idIDWebhook identifier
webhook_urlStringSupplied Webhook URL to receive order updates✓ (update only)

Webhook Event Examples

When order status changes occur, your webhook URL will receive HTTP POST requests with order update information.

Order Failed Event

{ "event": "order.updated", "timestamp": "2025-06-04T18:15:30Z", "order": { "order_id": "123", "order_status": "Order Failed", "failure_reason": "Point cloud processing error", "metadata": "{\"project_id\":\"123\"}" } }

Order Completed Event

{ "event": "order.updated", "timestamp": "2025-06-04T18:15:30Z", "order": { "order_id": "123", "order_status": "Order Completed", "metadata": "{\"project_id\":\"123\"}" } }

Webhook Implementation

Endpoint Setup

Your webhook endpoint should:

  • Accept HTTP POST requests
  • Respond with HTTP 200 status for successful delivery
  • Handle the order.updated event type
  • Process order status changes asynchronously

Example Implementation

// Express.js webhook handler app.post('/webhooks/order-updates', (req, res) => { const { event, timestamp, order } = req.body; if (event === 'order.updated') { console.log(`Order ${order.order_id} status: ${order.order_status}`); switch (order.order_status) { case 'Order Processing': handleOrderProcessing(order.order_id); break; case 'Order Completed': handleOrderCompleted(order.order_id); break; case 'Order Failed': handleOrderFailed(order.order_id, order.failure_reason); break; } } res.status(200).send('OK'); }); const handleOrderCompleted = (orderId: string) => { console.log(`Order ${orderId} completed successfully`); // Download results, notify user, update database, etc. }; const handleOrderFailed = (orderId: string, reason: string) => { console.log(`Order ${orderId} failed: ${reason}`); // Notify user, log error, retry logic, etc. };

Complete Webhook Workflow

Step-by-Step Integration

// 1. Create a webhook const createWebhookMutation = ` mutation CreateWebhook($webhook_url: String!) { createWebhook(webhook_url: $webhook_url) { webhook_id webhook_url webhook_events created } } `; const webhookResponse = await graphqlClient.request(createWebhookMutation, { webhook_url: "https://your-app.com/webhooks/order-updates" }); console.log("Webhook created:", webhookResponse.createWebhook.webhook_id); // 2. Query existing webhooks const queryWebhooksQuery = ` query { webhooks { webhook_id webhook_url webhook_events created } } `; const webhooksResponse = await graphqlClient.request(queryWebhooksQuery); console.log("Active webhooks:", webhooksResponse.webhooks); // 3. Update webhook if needed const updateWebhookMutation = ` mutation UpdateWebhook($webhook_id: ID!, $webhook_url: String!) { updateWebhook(webhook_id: $webhook_id, webhook_url: $webhook_url) { webhook_id webhook_url webhook_events } } `; // 4. Delete webhook when no longer needed const deleteWebhookMutation = ` mutation DeleteWebhook($webhook_id: ID!) { deleteWebhook(webhook_id: $webhook_id) { webhook_id } } `;

Error Handling

Common Webhook Errors

{ "errors": [ { "message": "Invalid webhook URL", "extensions": { "code": "INVALID_WEBHOOK_URL", "url": "invalid-url" } }, { "message": "Webhook not found", "extensions": { "code": "WEBHOOK_NOT_FOUND", "webhook_id": "invalid-webhook-id" } } ] }

Error Codes

  • INVALID_WEBHOOK_URL - Malformed or unreachable webhook URL
  • WEBHOOK_NOT_FOUND - Webhook does not exist
  • WEBHOOK_LIMIT_EXCEEDED - App limited to 1 webhook
  • WEBHOOK_DELIVERY_FAILED - Failed to deliver webhook event

Best Practices

Webhook Endpoint Requirements

  • HTTPS Only - Webhook URLs must use HTTPS
  • Fast Response - Respond with HTTP 200 within 30 seconds
  • Idempotency - Handle duplicate deliveries gracefully
  • Error Handling - Log and handle webhook processing errors

URL Validation

const isValidWebhookUrl = (url: string): boolean => { try { const parsedUrl = new URL(url); return parsedUrl.protocol === 'https:' && parsedUrl.hostname !== 'localhost' && !parsedUrl.hostname.startsWith('127.'); } catch { return false; } };

Webhook Reliability

// Implement idempotency const processedEvents = new Set(); app.post('/webhooks/order-updates', (req, res) => { const { event, timestamp, order } = req.body; const eventId = `${event}-${timestamp}-${order.order_id}`; if (processedEvents.has(eventId)) { console.log('Duplicate event, skipping'); return res.status(200).send('OK'); } try { // Process the event processOrderUpdate(order); processedEvents.add(eventId); res.status(200).send('OK'); } catch (error) { console.error('Webhook processing failed:', error); res.status(500).send('Processing failed'); } });

Order Status Tracking

Status Flow

Order webhooks will notify you of these status changes:

  1. Order Initialized - Order created successfully
  2. Order Processing - Order submitted and being processed
  3. Order Completed - Processing finished successfully
  4. Order Failed - Processing encountered an error

Event Monitoring

interface OrderStatusHandler { onInitialized: (orderId: string) => void; onProcessing: (orderId: string) => void; onCompleted: (orderId: string) => void; onFailed: (orderId: string, reason: string) => void; } const handleWebhookEvent = (payload: any, handlers: OrderStatusHandler) => { const { order } = payload; switch (order.order_status) { case 'Order Initialized': handlers.onInitialized(order.order_id); break; case 'Order Processing': handlers.onProcessing(order.order_id); break; case 'Order Completed': handlers.onCompleted(order.order_id); break; case 'Order Failed': handlers.onFailed(order.order_id, order.failure_reason); break; } };

Webhook Limitations

  • Limit: App is limited to 1 webhook registration
  • Events: Only order.updated events are supported
  • Delivery: No automatic retry mechanism - ensure endpoint reliability
  • Timeout: Webhook requests timeout after 30 seconds
Last updated on