Skip to content

Webhooks

Instead of polling for job status, you can receive results via webhook. Provide a webhook_url when calling the execute endpoint and the platform will POST to your URL when the job completes or fails.

Setup

Include webhook_url in your execute request:

{
  "inputs": { "customerAge": 35, "propertyValue": 500000 },
  "webhook_url": "https://your-app.com/webhooks/xlsxapi"
}

The URL must be http:// or https://.

Webhook Payloads

On Success

{
  "job_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "status": "completed",
  "inputs": {
    "customerAge": 35,
    "propertyValue": 500000
  },
  "outputs": {
    "premium": 1250.50,
    "deductible": 1000,
    "coverage": 500000
  },
  "created_at": "2026-03-18T10:30:00Z",
  "completed_at": "2026-03-18T10:30:08Z",
  "execution_time_ms": 1850
}

On Failure

{
  "job_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "status": "failed",
  "error_message": "Could not process at the moment",
  "created_at": "2026-03-18T10:30:00Z",
  "updated_at": "2026-03-18T10:30:25Z"
}

Behavior

Aspect Detail
Method POST
Content-Type application/json
Timeout 10 seconds
Retries None — the webhook is sent once
Delivery guarantee At-most-once

Webhook failures don't affect jobs

If your webhook endpoint is down or returns an error, the job itself is unaffected. You can always fall back to polling GET /jobs/{job_id} to retrieve the results.

Tracking Delivery

The webhook delivery status is included in the job status response:

{
  "job_id": "7c9e6679-...",
  "status": "completed",
  "webhook_url": "https://your-app.com/webhooks/xlsxapi",
  "webhook_sent_at": "2026-03-18T10:30:09Z",
  "webhook_response_status": 200
}
Field Description
webhook_sent_at When the webhook POST was attempted
webhook_response_status HTTP status code from your endpoint. 0 indicates a connection/timeout failure.

Best Practices

  1. Return 200 quickly — do your processing asynchronously after acknowledging receipt
  2. Use the job_id for idempotency — in case you receive duplicate deliveries (unlikely but possible during infrastructure events)
  3. Have a polling fallback — since webhooks are at-most-once, poll for any jobs that haven't triggered your webhook within an expected timeframe
  4. Verify the payload — check that the job_id corresponds to a job you submitted

Example Webhook Receiver

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/webhooks/xlsxapi", methods=["POST"])
def handle_webhook():
    payload = request.json
    job_id = payload["job_id"]
    status = payload["status"]

    if status == "completed":
        outputs = payload["outputs"]
        # Process the results...
        print(f"Job {job_id} completed: {outputs}")
    elif status == "failed":
        error = payload.get("error_message", "Unknown error")
        # Handle the failure...
        print(f"Job {job_id} failed: {error}")

    return jsonify({"received": True}), 200
const express = require("express");
const app = express();
app.use(express.json());

app.post("/webhooks/xlsxapi", (req, res) => {
  const { job_id, status, outputs, error_message } = req.body;

  if (status === "completed") {
    console.log(`Job ${job_id} completed:`, outputs);
    // Process the results...
  } else if (status === "failed") {
    console.log(`Job ${job_id} failed: ${error_message}`);
    // Handle the failure...
  }

  res.json({ received: true });
});