Webhooks

Webhooks

Webhooks let external systems subscribe to events that happen in Lathe Studio — test run completions, build creations, release status changes, and more.

Availability: Webhooks are available on Pro (up to 5 endpoints) and Enterprise (unlimited endpoints) plans.


Event Taxonomy#

All events follow the naming convention: {resource}.{action}.{version}

EventTriggerAvailability
testrun.created.v1A new test run is createdPro+
testrun.submitted.v1A tester submits a test runPro+
testrun.completed.v1A test run is marked completed (after build completion)Pro+
testcase.failed.v1A test case is recorded as failed in an executionPro+
build.created.v1A new build is created via API, UI, or webhookPro+
release.released.v1A release status changes to releasedPro+

Event Payload Structure#

All events share a common envelope:

{
  "id": "evt_01HXYZ",
  "event": "testrun.submitted.v1",
  "created_at": "2026-03-01T14:32:00Z",
  "data": { ... }
}

testrun.submitted.v1

{
  "id": "evt_01HABC",
  "event": "testrun.submitted.v1",
  "created_at": "2026-03-01T14:32:00Z",
  "data": {
    "run_id": "run_01HDEF",
    "project_id": "prj_01HGHI",
    "build_id": "bld_01HJKL",
    "release_id": "rel_01HMNO",
    "submitted_by": "usr_01HPQR",
    "results_summary": {
      "pass": 42,
      "fail": 3,
      "blocked": 1,
      "skipped": 4,
      "total": 50
    }
  }
}

build.created.v1

{
  "id": "evt_01HSTU",
  "event": "build.created.v1",
  "created_at": "2026-03-01T12:00:00Z",
  "data": {
    "build_id": "bld_01HVWX",
    "project_id": "prj_01HGHI",
    "name": "v2.4.1",
    "commit_sha": "a1b2c3d4",
    "branch": "main",
    "source": "api"
  }
}

Payloads are self-contained — they include all the data you need to act without making follow-up API calls.


Signature Verification#

Every webhook delivery includes an X-Perpetual-Signature header. Verify this signature before processing the payload to ensure it came from Lathe Studio.

The signature is an HMAC-SHA256 digest of the raw request body, keyed with your webhook secret:

X-Perpetual-Signature: sha256=a1b2c3d4e5f6...

Verification Examples

Node.js:

import crypto from 'crypto'

function verifyWebhookSignature(
  rawBody: string,
  signatureHeader: string,
  secret: string
): boolean {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex')

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader)
  )
}

Python:

import hmac
import hashlib

def verify_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Always use a timing-safe comparison (timingSafeEqual / hmac.compare_digest) to prevent timing attacks.


Registering a Webhook Endpoint#

Webhook registration is managed in Organization Settings → Webhooks.

To register an endpoint:

  1. Enter your endpoint URL (must be HTTPS)
  2. Select the events to subscribe to
  3. Save — a signing secret is generated and shown once

Your endpoint must respond with a 2xx status within 10 seconds or the delivery is treated as failed.


Retry Policy#

Failed deliveries (non-2xx response, timeout, or connection error) are retried with exponential backoff:

AttemptDelay
1 (initial)Immediate
25 minutes
330 minutes
42 hours
512 hours

After 5 failed attempts, the event is sent to the dead-letter queue and delivery is stopped. You can view and replay dead-letter events from the Webhooks settings page.


Developer Skill#

Download the Lathe Studio Developer Skill for copy-paste signature verification examples, retry schedules, and CI/CD integration recipes in Node.js, Python, and Go.


Best Practices#

  • Respond immediately, process asynchronously. Return 200 OK immediately and process the payload in a background job to avoid timeouts.
  • Handle duplicate deliveries. Use evt.id to deduplicate — the same event may be delivered more than once after retries.
  • Verify signatures. Never process a webhook without first verifying the signature.
  • Monitor the dead-letter queue. Check failed deliveries periodically in Org Settings.