---
title: Callbacks | RunAPI
description: Task-callback-leveringen veilig ontvangen en verifiëren.
url: https://runapi.ai/nl/docs/guides/task-api/callbacks.md
canonical: https://runapi.ai/nl/docs/guides/task-api/callbacks
locale: nl
---

> HTML-versie: https://runapi.ai/nl/docs/guides/task-api/callbacks
> Site-index voor agents: https://runapi.ai/llms.txt

# Callbacks

Gebruik Callbacks om Task-levenscyclusgebeurtenissen te ontvangen op een openbaar HTTPS-
eindpunt. Verifieer elke callback voordat u de JSON-body verwerkt, zodat
alleen leveringen die zijn ondertekend voor uw account de applicatiestatus kunnen wijzigen.

## Een callback-URL configureren

Voeg een openbare HTTPS-`callback_url` toe wanneer u een taak aanmaakt. De gebeurtenisinhoud en levenscyclusstatussen zijn afhankelijk van het eindpunt; raadpleeg de API-referentie van dat eindpunt voor de bijbehorende callback-payloads.

```json
{
  "model": "flux-2-pro-text-to-image",
  "prompt": "A product photograph on a clean studio background",
  "callback_url": "https://your-domain.com/webhooks/runapi"
}
```

## Een Callback Secret aanmaken

Volg de [Authenticatie-handleiding](https://runapi.ai/nl/docs/guides/authentication.md) om u aan te
melden, open vervolgens API-sleutels en maak een Callback-geheim aan voor het account dat
de taak aanmaakt. Sla de waarde op in een geheimenbeheerder en maak hem uitsluitend
beschikbaar voor uw callback-ontvanger. Het is geen API-sleutel en mag nooit in een taakverzoek worden verstuurd.

Het geheim ondertekent callbacks voor dat account. Het roteren ervan wijzigt de handtekening voor latere leveringen, dus werk elke callback-ontvanger onmiddellijk bij en bewaar beide waarden alleen lang genoeg om lopende leveringen af te handelen.

## Een callback-handtekening verifiëren

Elke callback is een HTTP `POST` met `Content-Type: application/json`.
RunAPI voegt geen `Authorization`-header toe aan dit verzoek. Verifieer
deze headers voordat u de body deserialiseert:

| Header | Betekenis |
|----------
| `X-Callback-Id` | Unieke identificatie voor deze bezorgpoging. |
| `X-Callback-Timestamp` | Unix-tijdstempel in seconden waarop de bezorging werd ondertekend. |
| `X-Callback-Signature` | Base64-gecodeerde HMAC-SHA-256-handtekening. |

Stel de ondertekende waarde als volgt samen, met de ongewijzigde bytes van de aanvraagbody:

```text
X-Callback-Id + "." + X-Callback-Timestamp + "." + raw request body
```

Decodeer het Callback Secret met Base64, bereken HMAC-SHA-256 over die waarde, codeer het resultaat met Base64 en vergelijk het met `X-Callback-Signature` via een tijdconstante vergelijking. Parseer en herserialiseer JSON niet vóór de verificatie.

### JavaScript

```javascript
import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyCallback({headers, rawBody, callbackSecret}) {
  const callbackId = headers["x-callback-id"];
  const timestamp = Number(headers["x-callback-timestamp"]);
  const signature = headers["x-callback-signature"];

  if (!callbackId || !signature || !Number.isSafeInteger(timestamp)) return false;
  if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;

  const signedContent = `${callbackId}.${timestamp}.${rawBody}`;
  const expected = createHmac("sha256", Buffer.from(callbackSecret, "base64"))
    .update(signedContent, "utf8")
    .digest();
  const received = Buffer.from(signature, "base64");

  return expected.length === received.length && timingSafeEqual(expected, received);
}
```

Geef de onbewerkte verzoek-body-string van het framework door aan `rawBody`; roep `JSON.stringify` niet aan op geparseerde gegevens.

### Python

```python
import base64
import hashlib
import hmac
import time


def verify_callback(headers, raw_body, callback_secret):
    callback_id = headers.get("X-Callback-Id")
    timestamp = headers.get("X-Callback-Timestamp")
    signature = headers.get("X-Callback-Signature")

    if not callback_id or not timestamp or not signature:
        return False

    try:
        timestamp = int(timestamp)
        secret = base64.b64decode(callback_secret, validate=True)
        received = base64.b64decode(signature, validate=True)
    except (ValueError, TypeError):
        return False

    if abs(time.time() - timestamp) > 300:
        return False

    signed_content = f"{callback_id}.{timestamp}.{raw_body}".encode("utf-8")
    expected = hmac.new(secret, signed_content, hashlib.sha256).digest()
    return hmac.compare_digest(expected, received)
```

Geef de exacte onbewerkte verzoek-body-string die door uw HTTP-framework is ontvangen door als `raw_body`.

## Leveringen veilig verwerken

* Geef alleen een `2xx`-respons terug nadat de callback is geaccepteerd voor verwerking. Na een niet-`2xx`-respons of transportfout wordt de bezorging tot maximaal 10 keer opnieuw geprobeerd.
* Reageer binnen 15 seconden. Zet trager werk in de wachtrij na verificatie in plaats van de HTTP-respons te blokkeren.
* Wijs callbacks af met ontbrekende handtekeningheaders, een ongeldige handtekening of een tijdstempel buiten het tolerantievenster dat uw ontvanger definieert.

## Verificatie probleemoplossing

* **Handtekeningmismatch:** controleer of het Callback Secret behoort tot hetzelfde
  account als de taak, decodeer het met Base64 en onderteken de oorspronkelijke body
  in plaats van geparseerde JSON.
* **Ontbrekende handtekeningheaders:** maak een Callback Secret aan voordat u
  callbacks voor statuswijzigingen gebruikt.
* **Tijdstempel geweigerd:** synchroniseer de klok van de ontvanger en gebruik
  een tolerantie die past bij uw implementatie.

Ga voor installatie- en levenscyclusbegeleiding terug naar de [Task API-snelstart](https://runapi.ai/nl/docs/guides/task-api/quickstart.md).

---

## Meer van RunAPI

- [Home](https://runapi.ai/nl/.md)
- [Modelcatalogus](https://runapi.ai/nl/models.md)
- [Prijzen](https://runapi.ai/nl/pricing.md)
- [Providers](https://runapi.ai/nl/models)
- [Documentatie](https://runapi.ai/nl/docs/guides)
- [SDK's](https://runapi.ai/nl/sdk.md)
- [CLI](https://runapi.ai/nl/cli.md)
- [MCP Server](https://runapi.ai/nl/mcp.md)
- [Claude Code vs Cursor](https://runapi.ai/nl/claude-code-vs-cursor.md)
- [Cursor API instellen](https://runapi.ai/nl/cursor-api-setup.md)
- [RunAPI vs OpenRouter](https://runapi.ai/nl/openrouter-alternative.md)
- [Enterprise](https://runapi.ai/nl/contact.md)
- [Contact](https://runapi.ai/nl/contact.md)
- [Voorwaarden](https://runapi.ai/nl/terms.md)
- [Privacy](https://runapi.ai/nl/privacy.md)
- [Site-index voor agents](https://runapi.ai/llms.txt)

Contact: contact@runapi.ai

## Gestructureerde gegevens

```json
[
  {
    "@context": "https://schema.org",
    "inLanguage": "nl",
    "@type": "WebSite",
    "name": "RunAPI",
    "url": "https://runapi.ai/nl",
    "potentialAction": {
      "@type": "SearchAction",
      "target": {
        "@type": "EntryPoint",
        "urlTemplate": "https://runapi.ai/nl/models?q={search_term_string}"
      },
      "query-input": "required name=search_term_string"
    }
  },
  {
    "@context": "https://schema.org",
    "inLanguage": "nl",
    "@type": "Organization",
    "name": "RunAPI",
    "url": "https://runapi.ai/nl",
    "logo": {
      "@type": "ImageObject",
      "url": "https://runapi.ai/nlicon.svg"
    },
    "sameAs": [
      "https://github.com/runapi-ai"
    ]
  },
  {
    "@context": "https://schema.org",
    "inLanguage": "nl",
    "@type": "TechArticle",
    "headline": "Callbacks",
    "description": "Task-callback-leveringen veilig ontvangen en verifiëren.",
    "url": "https://runapi.ai/nl/docs/guides/task-api/callbacks",
    "mainEntityOfPage": "https://runapi.ai/nl/docs/guides/task-api/callbacks"
  }
]
```
