2026 customs changesWhat it means

Webhook Setup Guide

Configure webhooks to receive real-time notifications for document, shipment, and compliance events.

Overview

Webhooks let your systems (for example a TMS or ERP) react in real time as CargoLint processes documents and evaluates shipments. This guide walks through configuring, securing, testing, and monitoring webhooks.

Webhook access is available on Business and Enterprise plans. Managing webhooks requires an Owner or Admin account.

Creating a Webhook

Via the dashboard

  1. Navigate to Settings > Integrations > Webhooks
  2. Click Add Webhook
  3. Enter your endpoint URL (must use HTTPS)
  4. Select which events should trigger notifications
  5. Click Create Webhook
  6. Copy the signing secret shown on creation and store it securely - it is displayed only once

Via the API

curl -X POST https://api.cargolint.com/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-domain.com/webhooks/cargolint",
    "events": ["document.completed", "shipment.evaluated"]
  }'

The create response includes a one-time secret field. Save it now - you will need it to verify signatures, and it cannot be retrieved later. If you lose it, rotate the secret.

Supported Events

Documents

  • document.uploaded - received and queued for processing
  • document.pending_approval - extracted with high confidence; awaiting approval
  • document.requires_review - extracted with low confidence, or sent back by a shipment-consistency finding
  • document.failed - extraction failed
  • document.reviewed - a reviewer submitted corrections
  • document.completed - approved and finalized
  • document.generated - generated from another document (e.g. a packing list from an invoice)
  • document.cloned - cloned from another document
  • document.skipped - deferred by a reviewer

Shipments

  • shipment.created - a new shipment was created
  • shipment.document_linked - a document was attached to a shipment
  • shipment.evaluated - cross-document consistency evaluation completed (includes overallStatus)
  • shipment.settled - a shipment was finalized

Compliance

  • compliance.completed - a single-document compliance check finished (includes overallStatus)
  • compliance.warning - deprecated; fires alongside compliance.completed only on Warning/Error

See the Webhooks API reference for payload shapes and the full delivery contract.

Webhook Security

Each delivery is signed with HMAC-SHA256. The request includes these headers:

HeaderPurpose
X-CargoLint-Signaturev1={hex} signature
X-CargoLint-TimestampUnix timestamp used in the signature
X-CargoLint-EventThe event type
X-CargoLint-DeliveryIdUnique delivery id (use for idempotency)

The signature is computed over "{timestamp}.{payload}". Your signing secret is base64-encoded - decode it to get the HMAC key:

import base64
import hashlib
import hmac

def verify_signature(payload: str, signature_header: str, timestamp_header: str, secret: str) -> bool:
    signed = f"{timestamp_header}.{payload}".encode()
    expected = hmac.new(
        base64.b64decode(secret),
        signed,
        hashlib.sha256,
    ).hexdigest()
    provided = signature_header.split("v1=", 1)[-1]
    return hmac.compare_digest(expected, provided)

Security: Always use hmac.compare_digest() (constant-time comparison) - never ==, which is vulnerable to timing attacks. Also reject deliveries whose timestamp is far from the current time to prevent replay.

Rotating the Signing Secret

If a secret is lost or may be exposed, rotate it. Rotation returns a new secret once and immediately invalidates the old one, without affecting the webhook or its delivery history.

curl -X POST https://api.cargolint.com/api/v1/webhooks/{id}/rotate-secret \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Testing Your Webhook

  1. In the webhook settings, click Send Test Payload (delivers a webhook.test event)
  2. Verify your endpoint returns HTTP 200
  3. Check the result in the delivery history

Monitoring Deliveries

The Delivery History shows, per attempt:

  • Timestamp of the attempt
  • Delivery status (Pending, Success, or Failed)
  • Response status code
  • Attempt count and last error

Retries and Failed Deliveries

A non-2xx response or network error is retried up to 3 attempts with a backoff of 5s, 15s, then 45s (each attempt times out after 10 seconds). After the final failed attempt the delivery is marked Failed. The webhook itself remains active - it is not automatically disabled, so subsequent events are still delivered.

Troubleshooting

Webhook not receiving events:

  • Confirm the endpoint is publicly reachable over HTTPS
  • Confirm the webhook is subscribed to the event you expect
  • Check firewall/proxy configuration
  • Review the delivery history for error messages

High failure rate:

  • Return a 2xx response within 10 seconds; offload heavy work to a background job
  • Check your server logs for connection or TLS errors