Calafai Docs

Webhooks API Reference

Webhooks API Reference

Webhooks allow your application to receive real-time HTTP POST notifications when events occur in the Groundtruth Platform. You register endpoint URLs, select which events to subscribe to, and the platform sends signed payloads to your endpoints as events happen.

Base URL: /api/webhooks

Authentication: All webhook management endpoints require cookie-based session authentication only. You cannot use an API key to manage webhooks.


Available Events

EventDescription
engagement.startedAn engagement run has begun
engagement.completedAn engagement run finished successfully
engagement.failedAn engagement run failed with an error
deliverable.readyA deliverable has been generated
deliverable.approvedA deliverable was approved in the review workflow
deliverable.revision_requestedA revision was requested for a deliverable
deliverable.rejectedA deliverable was rejected in the review workflow
portal.comment_receivedA comment was left on the client portal
quality.scoredA quality score was assigned to a task
pattern_analysis.completedCross-engagement pattern analysis finished
account.deletion_requestedAn account deletion request was initiated
attachment.uploadedA file was uploaded to an engagement
report.generatedA PDF report was generated

List Webhook Endpoints

GET /api/webhooks

Returns all webhook endpoints for the authenticated tenant, including recent delivery history.

Response

{
  "webhooks": [
    {
      "id": "clxyz400whk",
      "url": "https://example.com/webhooks/groundtruth",
      "events": ["engagement.completed", "deliverable.ready"],
      "enabled": true,
      "description": "Production webhook",
      "createdAt": "2025-05-20T10:00:00.000Z",
      "recentDeliveries": [
        {
          "id": "clxyz410del",
          "event": "engagement.completed",
          "statusCode": 200,
          "durationMs": 245,
          "createdAt": "2025-06-01T12:00:00.000Z"
        }
      ]
    }
  ]
}

Example

curl -X GET https://app.groundtruth.ai/api/webhooks \
  -H "Cookie: sb-access-token=..."

Create Webhook Endpoint

POST /api/webhooks

Creates a new webhook endpoint. The webhook secret is returned only once in the response.

Request Body

FieldTypeRequiredDescription
urlstringYesThe endpoint URL. Must use HTTPS.
eventsstring[]YesArray of event types to subscribe to
descriptionstringNoHuman-readable description

Response

Status: 201 Created

{
  "id": "clxyz401whk",
  "url": "https://example.com/webhooks/groundtruth",
  "events": ["engagement.completed", "deliverable.ready"],
  "enabled": true,
  "description": "Production webhook",
  "secret": "whsec_a1b2c3d4e5f6a1b2c3d4e5f6",
  "createdAt": "2025-06-01T14:00:00.000Z"
}

IMPORTANT: The secret field (format: whsec_ + 24 hex characters) is only returned once at creation time. Store it securely. You will need it to verify webhook signatures.

Example

curl -X POST https://app.groundtruth.ai/api/webhooks \
  -H "Cookie: sb-access-token=..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/groundtruth",
    "events": ["engagement.completed", "deliverable.ready", "engagement.failed"],
    "description": "Production webhook"
  }'

Errors

StatusDescription
400Invalid URL (must be HTTPS), missing events, or invalid event type

Get Webhook Endpoint

GET /api/webhooks/:id

Returns a single webhook endpoint with its full delivery history.

Path Parameters

ParameterTypeDescription
idstringWebhook endpoint ID

Response

{
  "webhook": {
    "id": "clxyz400whk",
    "url": "https://example.com/webhooks/groundtruth",
    "events": ["engagement.completed", "deliverable.ready"],
    "enabled": true,
    "description": "Production webhook",
    "createdAt": "2025-05-20T10:00:00.000Z",
    "deliveries": [
      {
        "id": "clxyz410del",
        "event": "engagement.completed",
        "statusCode": 200,
        "responseBody": "{\"ok\":true}",
        "durationMs": 245,
        "createdAt": "2025-06-01T12:00:00.000Z"
      }
    ]
  }
}

Example

curl -X GET https://app.groundtruth.ai/api/webhooks/clxyz400whk \
  -H "Cookie: sb-access-token=..."

Update Webhook Endpoint

PATCH /api/webhooks/:id

Updates an existing webhook endpoint.

Path Parameters

ParameterTypeDescription
idstringWebhook endpoint ID

Request Body

All fields are optional. Only include fields you want to change.

FieldTypeDescription
urlstringNew endpoint URL (must be HTTPS)
eventsstring[]New event subscriptions (replaces existing list)
enabledbooleanEnable or disable the endpoint
descriptionstringUpdated description

Response

{
  "webhook": {
    "id": "clxyz400whk",
    "url": "https://example.com/webhooks/groundtruth-v2",
    "events": ["engagement.completed", "engagement.failed"],
    "enabled": true,
    "description": "Updated production webhook",
    "createdAt": "2025-05-20T10:00:00.000Z"
  }
}

Example

curl -X PATCH https://app.groundtruth.ai/api/webhooks/clxyz400whk \
  -H "Cookie: sb-access-token=..." \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["engagement.completed", "engagement.failed"],
    "description": "Updated production webhook"
  }'

Delete Webhook Endpoint

DELETE /api/webhooks/:id

Permanently deletes a webhook endpoint and all its delivery history.

Path Parameters

ParameterTypeDescription
idstringWebhook endpoint ID

Response

{
  "success": true
}

Example

curl -X DELETE https://app.groundtruth.ai/api/webhooks/clxyz400whk \
  -H "Cookie: sb-access-token=..."

Send Test Ping

POST /api/webhooks/:id/test

Sends a test ping event to the webhook endpoint to verify connectivity. The test payload uses the event type ping.

Path Parameters

ParameterTypeDescription
idstringWebhook endpoint ID

Response

{
  "success": true,
  "statusCode": 200,
  "durationMs": 312
}

Example

curl -X POST https://app.groundtruth.ai/api/webhooks/clxyz400whk/test \
  -H "Cookie: sb-access-token=..."

Errors

StatusDescription
200Test sent, but the remote endpoint may have returned an error. Check statusCode in the response.
404Webhook endpoint not found

Signature Verification

Every webhook delivery includes a cryptographic signature so you can verify that the request originated from the Groundtruth Platform and was not tampered with.

Request Headers

HeaderDescription
X-Groundtruth-SignatureSignature in the format t=<timestamp>,v1=<signature>
X-Groundtruth-EventThe event type (e.g., engagement.completed)

Payload Format

{
  "event": "engagement.completed",
  "data": {
    "engagementId": "clxyz500eng",
    "status": "completed",
    "runId": "clxyz600run"
  },
  "timestamp": "2025-06-01T12:00:00.000Z"
}

How Signatures Work

The signature is computed as an HMAC-SHA256 digest of the string {timestamp}.{body}, using your webhook secret as the key.

  1. Extract the timestamp (t) and signature (v1) from the X-Groundtruth-Signature header
  2. Construct the signed message: {timestamp}.{raw_request_body}
  3. Compute the HMAC-SHA256 of the message using your webhook secret
  4. Compare the computed signature with the v1 value using a timing-safe comparison

Node.js Verification Example

const crypto = require('crypto');

function verifyWebhookSignature(body, signature, secret) {
  const [tPart, v1Part] = signature.split(',');
  const timestamp = tPart.split('=')[1];
  const expectedSig = v1Part.split('=')[1];

  const message = `${timestamp}.${body}`;
  const computed = crypto
    .createHmac('sha256', secret)
    .update(message)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(computed),
    Buffer.from(expectedSig)
  );
}

// Usage in an Express handler:
app.post('/webhooks/groundtruth', (req, res) => {
  const signature = req.headers['x-groundtruth-signature'];
  const event = req.headers['x-groundtruth-event'];
  const body = req.body; // raw string body

  if (!verifyWebhookSignature(body, signature, process.env.GROUNDTRUTH_WEBHOOK_SECRET)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const payload = JSON.parse(body);
  console.log(`Received ${event}:`, payload.data);

  // Process the event...

  res.status(200).json({ ok: true });
});

Delivery Behavior

PropertyValue
Timeout10 seconds per delivery attempt
MethodPOST
Content-Typeapplication/json

Delivery Logging

Each delivery is logged with:

  • HTTP status code returned by your endpoint
  • Response body (first 1,000 characters)
  • Duration in milliseconds

You can view delivery history via the GET /api/webhooks/:id endpoint or in the Groundtruth dashboard.

On this page