Resources
Content Integration Webhooks

Content Integration Webhooks

Register webhooks, verify signatures, handle events, and fetch Content Integration results.

Use webhooks after the polling flow works. Webhooks notify your system when a Content Integration job finishes or fails.

Events

EventTrigger
content.completedA job reached completed.
content.failedA job reached failed.

Create webhook

curl -X POST "https://api.tutorflow.io/v1/content/organizations/{organizationId}/webhooks" \
  -H "Content-Type: application/json" \
  -b tutorflow-admin.cookies \
  -d '{
    "url": "https://example.com/tutorflow/content-webhooks",
    "events": ["content.completed", "content.failed"]
  }'

Response:

{
  "id": "2f083d42-5c0f-4de6-9c3f-35c4823a589e",
  "organizationId": "00000000-0000-4000-8000-000000000001",
  "url": "https://example.com/tutorflow/content-webhooks",
  "events": ["content.completed", "content.failed"],
  "status": "ACTIVE",
  "secret": "generated-signing-secret"
}

The secret is shown once. Store it in your webhook receiver.

Request headers

X-Content-Integration-Event: content.completed
X-Content-Integration-Signature: hmac_sha256_signature
Content-Type: application/json

Receiver behavior

  1. Verify the signature.
  2. Return a 2xx response quickly.
  3. Use the job id in the payload to fetch the result endpoint.
  4. Treat repeated deliveries as duplicates and handle them idempotently.

Node.js signature verification

import crypto from 'node:crypto'
 
function verifyContentSignature(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex')
 
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  )
}

List webhooks

curl "https://api.tutorflow.io/v1/content/organizations/{organizationId}/webhooks" \
  -b tutorflow-admin.cookies

List responses do not include the signing secret.

Delete webhook

curl -X DELETE "https://api.tutorflow.io/v1/content/organizations/{organizationId}/webhooks/{webhookId}" \
  -b tutorflow-admin.cookies

Retry handling

TutorFlow retries failed deliveries. Your receiver should:

  • Return 2xx only after accepting the event.
  • Avoid side effects before signature verification.
  • Store processed event ids or job ids to prevent duplicate processing.
  • Fetch the result endpoint if a webhook payload is not enough for your workflow.