Skip to contentNewDeepSeek V4.1 Flash 1017 is now availableTry it now
Docs / Webhooks reference

Webhooks reference

Payload structures, headers, retry timing, and response codes for asynchronous inference webhooks.

Payloads, headers, and delivery rules for asynchronous inference webhooks. For a step-by-step setup, see Webhooks.

Dashboard management

Manage webhooks in Settings → Webhooks:

  1. Create a webhook with a name and HTTPS URL.
  2. Send a test event, disable or enable, or delete a webhook, and see its recent invocation stats.
  3. Copy the webhook identifier to use in generation requests.

Payload structures

generation.completed

json
{
  "event": "generation.completed",
  "timestamp": "ISO 8601 timestamp",
  "webhookId": "webhook identifier",
  "data": {
    "id": "generation ID",
    "state": "Success|Failed|Queued|In Progress",
    "stateMessage": "Human readable status",
    "request": { /* Original request or null */ },
    "response": { /* OpenAI format response or null */ },
    "model": "model ID",
    "createdAt": "ISO 8601 timestamp",
    "dispatchedAt": "ISO 8601 timestamp or null",
    "firstChunkAt": "ISO 8601 timestamp or null",
    "finishedAt": "ISO 8601 timestamp or null",
    "usage": { /* Token usage */ }
  }
}

The generation ID is data.id. The response object is compatible with the OpenAI SDK types.

async-embedding.completed

json
{
  "event": "async-embedding.completed",
  "timestamp": "ISO 8601 timestamp",
  "webhookId": "webhook identifier",
  "data": {
    "id": "generation ID",
    "state": "Success|Failed|Queued|In Progress",
    "stateMessage": "Human readable status",
    "request": { /* Original embeddings request or null */ },
    "response": { /* OpenAI format embeddings response or null */ },
    "model": "model ID",
    "createdAt": "ISO 8601 timestamp",
    "dispatchedAt": "ISO 8601 timestamp or null",
    "firstChunkAt": "ISO 8601 timestamp or null",
    "finishedAt": "ISO 8601 timestamp or null",
    "usage": { /* Token usage */ }
  }
}

slow-group.completed

json
{
  "event": "slow-group.completed",
  "timestamp": "ISO 8601 timestamp",
  "groupId": "group ID",
  "data": {
    "groupSize": 2,
    "status": "completed|failed",
    "generations": [
      {
        "id": "generation ID",
        "state": "Success|Failed|Queued|In Progress",
        "stateMessage": "Human readable status",
        "request": { /* Original request or null */ },
        "response": { /* OpenAI format response or null */ },
        "model": "model ID",
        "createdAt": "ISO 8601 timestamp",
        "dispatchedAt": "ISO 8601 timestamp or null",
        "firstChunkAt": "ISO 8601 timestamp or null",
        "finishedAt": "ISO 8601 timestamp or null",
        "usage": { /* Token usage */ }
      }
    ]
  }
}

data.status is failed when the group could not finish: processing failed, or the group passed its 72-hour completion window. Check each entry's state in generations to see which requests finished.

Dashboard test events

Test on a webhook in Settings → Webhooks sends a sample payload for the event type you choose (generation.completed, slow-group.completed or async-embedding.completed). The payload has the same shape and headers as a real delivery, with test-model as the model (test-embedding-model for async-embedding.completed) and IDs that start with test- (for example test-generation-1767225600000), so your endpoint can tell a test from a real event.

Headers

HeaderDescriptionExample
X-Inference-EventEvent typegeneration.completed, async-embedding.completed, or slow-group.completed
X-Inference-Webhook-IDWebhook identifierAhALzdz8S
X-Inference-Generation-IDGeneration ID (generation events)XBKcs7F1s2oJ_AHiLMbF4
X-Inference-Embedding-IDGeneration ID (embedding events)XBKcs7F1s2oJ_AHiLMbF4
X-Inference-Group-IDGroup ID (group events)GRP_XYZ123
X-Inference-Delivery-AttemptDelivery attempt, starting at 11
User-AgentInference.net webhook agentKuzco-Webhook/1.0
Content-TypeAlways application/jsonapplication/json

Use a webhook in a generation

Include the webhook identifier in the request metadata:

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.inference.net/v1/slow",
  apiKey: process.env.INFERENCE_API_KEY,
});

const response = await client.chat.completions.create({
  model: "kimi-k3-fast",
  messages: [{ role: "user", content: "Hello!" }],
  // @ts-expect-error metadata is not in the OpenAI SDK types
  metadata: { webhook_id: "YOUR_WEBHOOK_IDENTIFIER" },
});

For groups, pass webhook_id at the top level of the request body. See Group API.

Minimal handlers

app.post("/webhook", express.json(), (req, res) => {
  res.status(200).json({ received: true });

  if (req.body.event === "generation.completed") {
    setImmediate(() => {
      console.log("Generation completed:", req.body.data.id);
      // Your processing logic here
    });
  } else if (req.body.event === "async-embedding.completed") {
    setImmediate(() => {
      console.log("Embedding completed:", req.body.data.id);
      console.log("Number of embeddings:", req.body.data.response.data.length);
    });
  } else if (req.body.event === "slow-group.completed") {
    setImmediate(() => {
      console.log("Group completed:", req.body.groupId);
      console.log("Group size:", req.body.data.groupSize);
      req.body.data.generations.forEach((gen: any) => {
        console.log(`Generation ${gen.id}: ${gen.state}`);
      });
    });
  }
});

Timing and limits

MetricValueNotes
Response timeout30 secondsPer delivery attempt
Delivery attemptsUp to 24 per eventOver about 3 days, then the event is dropped
Retry delays5s, 30s, 2m, 10m, 30m, 1h, 2h, then every 4hEach delay varies by up to 20%
Max payload sizeLarge payloads supportedPayload size scales with generation size

Retries are triggered by a non-2xx response, a timeout, or a connection error. Each attempt is a single POST; there is no OPTIONS preflight. Redirects are not followed, except 307 and 308.

Response codes

CodeMeaningRetry?
200-299SuccessNo
400-599Non-success statusYes
3xxRedirect (not 307/308)Yes
TimeoutNo response in 30sYes

Any response outside the 200-299 range is treated as a failed delivery and retried.

Checklist

  • Respond with 200 OK immediately
  • Process webhook data asynchronously
  • Make processing idempotent with data.id (generation events) or groupId (group events)
  • Validate the webhook source with headers
  • Handle errors gracefully
  • Monitor webhook processing
  • Use an HTTPS endpoint
  • Set up error logging
  • Test the webhook from the dashboard
  • Handle timeouts
  • Handle both individual and group completions

Common issues

IssueSolution
Not receiving webhooksCheck the webhook is not disabled in the dashboard, test connectivity, check URL
Duplicate webhooksMake processing idempotent, return 200 OK
Webhooks timing outRespond immediately, process asynchronously
Invalid payloadValidate against the documented schema
Test webhook failsCheck the endpoint is publicly reachable and returns 200 OK

Support

Email support@inference.net.