Skip to content
luranta/docs

Search documentation

Search pages, sections and API operations.

Webhooks
.md

Webhooks

Receive signed Signals events at an organisation-owned public HTTPS endpoint.

Event types

Event typeWhen it is sent
signals.monitor.deliveryWhen a configured monitor has new resources to deliver.
integration.testWhen an owner or admin sends a test delivery.
posting.publishedWhen an employer publishes a job posting.
posting.closedWhen an employer closes a job posting.
application.receivedWhen an employer receives an application.
application.updatedWhen an application changes.
grant.revokedWhen a company revokes an employer authorization grant.

Envelope

Every body is canonical JSON using schema version 1.

FieldTypeRequired
schema_version1Yes
event_idUUIDv7Yes
delivery_idUUIDv7Yes
event_typeevent typeYes
occurred_atRFC 3339 timestampYes
dataevent payloadYes

Delivery headers

HeaderPurpose
X-Luranta-Delivery-IdUnique delivery attempt identity. Use it when investigating delivery state.
X-Luranta-Event-IdStable event identity. Use it as the primary idempotency key.
X-Luranta-Event-TypeThe event discriminator for routing and payload handling.
X-Luranta-SignatureThe v0 HMAC-SHA256 signature.
X-Luranta-TimestampUnix time in seconds included in the signed input.

Verify with the SDK

Use constructEvent / construct_event as the default path. It checks the timestamp window, verifies HMAC-SHA256 over v0.<timestamp>.<raw_body>, and returns a typed event.

Read the request body as raw bytes before verification. Deduplicate business processing by event_id; retain delivery_id for per-attempt diagnostics.

Receive and verify

import { Client } from "@luranta/sdk"

const client = new Client({ apiKey: process.env.LURANTA_API_KEY! })

export async function POST(request: Request) {
  const payload = await request.text()
  const event = await client.webhooks.constructEvent(
    payload,
    request.headers,
    process.env.LURANTA_WEBHOOK_SECRET!,
  )

  switch (event.event_type) {
    case "signals.monitor.delivery":
      break
    case "integration.test":
      break
  }

  return new Response(null, { status: 200 })
}

Acknowledgement and retries

Receiver resultLuranta behaviour
Any 2xxMarks that destination delivery as complete.
408, 409, 425, 429 or 5xxRetries with bounded backoff, up to 12 attempts.
Other non-2xxTreats the delivery as terminal.
Repeated terminal deliveriesPauses the destination after 5 consecutive failures.
RedirectDoes not follow it; the delivery fails.

Endpoint requirements

  • Use a public HTTPS hostname on port 443.
  • Do not use credentials in the URL.
  • Luranta rejects loopback, private, link-local, metadata and non-public DNS answers before every attempt.
  • The maximum body size is 64 KiB and the request timeout is 10 seconds.
  • Return a 2xx as soon as the verified event is durably queued; process it asynchronously.

Rotate or troubleshoot

  1. Create a new secret in Settings → Integrations.
  2. Update your receiver and send a test event.
  3. Check the delivery receipt for destination, event, attempt count and terminal failure code. Receipts omit secrets and payloads.
  4. Fix the cause, then explicitly resume a paused destination.