Dashboard Management

Webhooks are managed through the inference.net dashboard:

  1. Navigate to Webhooks on the sidebar
  2. Create, test, archive, or restore webhooks through the UI
  3. Copy your webhook identifier for use in generation requests

Payload Structures

generation.completed

{
  "event": "generation.completed",
  "timestamp": "ISO 8601 timestamp",
  "webhook_id": "webhook identifier",
  "generation_id": "generation ID",
  "data": {
    "state": "Success|Failed",
    "stateMessage": "Human readable status",
    "request": { /* Original request with metadata */ },
    "response": { /* OpenAI format response */ },
    "dispatchedAt": "ISO 8601 timestamp",
    "finishedAt": "ISO 8601 timestamp"
  }
}

slow-group.completed

{
  "event": "slow-group.completed",
  "timestamp": "ISO 8601 timestamp",
  "group_id": "group ID",
  "data": {
    "group_size": 2,
    "status": "completed",
    "generations": [
      {
        "generationId": "generation ID",
        "state": "Success|Failed",
        "stateMessage": "Human readable status",
        "request": { /* Original request */ },
        "response": { /* OpenAI format response */ },
        "finishedAt": "ISO 8601 timestamp or null"
      }
    ]
  }
}

Headers

HeaderDescriptionExample
X-Inference-EventEvent typegeneration.completed or slow-group.completed
X-Inference-Webhook-IDWebhook identifierAhALzdz8S
X-Inference-Generation-IDGeneration ID (if applicable)XBKcs7F1s2oJ_AHiLMbF4
X-Inference-Group-IDGroup ID (for group events)GRP_XYZ123
User-Agentinference.net webhook agentKuzco-Webhook/1.0
Content-TypeAlways application/jsonapplication/json

Using Webhooks in Generations

Include the webhook identifier in your generation request metadata:

curl -X POST https://api.inference.net/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/llama-3.1-8b-instruct",
    "messages": [{"role": "user", "content": "Hello!"}],
    "metadata": {"webhook_id": "YOUR_WEBHOOK_IDENTIFIER"}
  }'

Minimal Webhook Handler Examples

Node.js/Express

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

  if (req.body.event === 'generation.completed') {
    // Process asynchronously
    setImmediate(() => {
      console.log('Generation completed:', req.body.generation_id);
      // Your processing logic here
    });
  } else if (req.body.event === 'slow-group.completed') {
    // Process group completion asynchronously
    setImmediate(() => {
      console.log('Group completed:', req.body.group_id);
      console.log('Group size:', req.body.data.group_size);
      req.body.data.generations.forEach(gen => {
        console.log(`Generation ${gen.generationId}: ${gen.state}`);
      });
      // Your processing logic here
    });
  }
});

Python/FastAPI

@app.post("/webhook")
async def handle_webhook(payload: dict, background_tasks: BackgroundTasks):
    background_tasks.add_task(process_webhook, payload)
    return {"received": True}

def process_webhook(payload):
    if payload["event"] == "generation.completed":
        print(f"Processing generation {payload['generation_id']}")
        # Your processing logic here
    elif payload["event"] == "slow-group.completed":
        print(f"Processing group {payload['group_id']}")
        print(f"Group size: {payload['data']['group_size']}")
        for gen in payload["data"]["generations"]:
            print(f"Generation {gen['generationId']}: {gen['state']}")
        # Your processing logic here

Go

func handleWebhook(w http.ResponseWriter, r *http.Request) {
    var payload map[string]interface{}
    json.NewDecoder(r.Body).Decode(&payload)

    // Process asynchronously
    go func() {
        switch payload["event"] {
        case "generation.completed":
            // Process single generation
        case "slow-group.completed":
            data := payload["data"].(map[string]interface{})
            fmt.Printf("Group %s completed with %v generations\n",
                payload["group_id"], data["group_size"])
            // Your processing logic here
        }
    }()

    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(map[string]bool{"received": true})
}

Timing & Limits

MetricValueNotes
Response timeout30 secondsMust respond within this time
Retry attempts3With exponential backoff
Max payload size10MBTypical: 5-50KB
Delivery timeUnder 60 secondsFrom completion to webhook

Response Codes

CodeMeaningRetry?
200-299SuccessNo
400-499Client errorNo
500-599Server errorYes
TimeoutNo response in 30sYes

Best Practices Checklist

  • Respond with 200 OK immediately
  • Process webhook data asynchronously
  • Implement idempotency with generation_id or group_id
  • Validate webhook source via headers
  • Handle errors gracefully
  • Monitor webhook processing
  • Use HTTPS endpoint
  • Set up proper error logging
  • Test webhook with dashboard test feature
  • Implement timeout handling
  • Handle both individual and group completions

Common Issues & Solutions

IssueSolution
Not receiving webhooksCheck webhook not disabled in dashboard, test connectivity, verify HTTPS URL
Duplicate webhooksImplement idempotency, ensure 200 OK response
Webhooks timing outRespond immediately, process asynchronously
Invalid payloadValidate against documented schema
Test webhook failsCheck endpoint is publicly accessible, returns 200 OK

Support Resources