Skip to content

REST API reference

Webhooks

Receive verified business updates without polling the REST API.

DeliveryAt least once
OrderingNot guaranteed
Retry policyUp to 8 attempts

Implement a receiver

  1. Create a webhook destination. Add a public HTTPS URL in your portal's External API settings and save the signing secret when it is shown.
  2. Read the raw request body. Keep the unmodified bytes until after signature verification; parsing and re-encoding JSON changes the signed value.
  3. Verify Levr-Signature. Reject timestamps older than 300 seconds and compare every v1 digest using a constant-time comparison.
  4. Acknowledge after durable acceptance. Return a 2xx response within 10 seconds, then perform slower work asynchronously. Deduplicate retries by the event id.

Signature format

The header uses t=<unix-timestamp>,v1=<lowercase-hex-digest>. Parse its comma-separated values, read t and every v1, then compute HMAC-SHA256(signing_secret, timestamp + "." + raw_body) as lowercase hexadecimal. Accept the request when any v1 value matches; secret rotation may temporarily send two signatures.

Request headers

Header Use
Content-Type Always application/json. Verify the signature before parsing the body.
Levr-Event-ID Stable event identifier. Store it to make processing idempotent.
Levr-Delivery-ID Stable identifier for this destination's delivery across retries.
Levr-Signature Timestamp and one or more HMAC-SHA256 digests.

Levr retries timeouts, connection failures, and non-2xx responses with exponential backoff. Events can arrive more than once or out of order.

business.status_changed

A business moved to a different stage in the portal pipeline. Verify Levr-Signature against the unmodified request body before processing.

View example event
{
  "id": "evt_2m8q7c9k4x6p3n5d",
  "type": "business.status_changed",
  "api_version": "v1",
  "created_at": "2026-08-19T16:42:13Z",
  "data": {
    "business": {
      "id": "org_7fj3k9m2d8q4n6wx",
      "name": "Example Analytics Inc.",
      "status": {
        "pipeline": "Clients",
        "stage": "Underwriting",
        "changed_at": "2026-08-19T16:42:13Z"
      }
    }
  }
}
View payload schema
{
  "type": "object",
  "required": [
    "id",
    "type",
    "api_version",
    "created_at",
    "data"
  ],
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^evt_[a-z0-9]+$"
    },
    "type": {
      "type": "string",
      "const": "business.status_changed"
    },
    "api_version": {
      "type": "string",
      "const": "v1"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "data": {
      "type": "object",
      "required": [
        "business"
      ],
      "properties": {
        "business": {
          "type": "object",
          "required": [
            "id",
            "name",
            "status"
          ],
          "properties": {
            "id": {
              "type": "string",
              "pattern": "^org_[a-z0-9]+$"
            },
            "name": {
              "type": "string"
            },
            "status": {
              "type": "object",
              "required": [
                "pipeline",
                "stage",
                "changed_at"
              ],
              "properties": {
                "pipeline": {
                  "type": "string"
                },
                "stage": {
                  "type": "string"
                },
                "changed_at": {
                  "type": "string",
                  "format": "date-time"
                }
              },
              "additionalProperties": false
            }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}

Early access

Request a capability

Tell us what you need your integration to do. Add an email if you want a reply.