Skip to main content
Webhooks let you subscribe to events in Beach Depository so your systems can react in real time — no polling required. When an event occurs (for example, an item is vaulted or an outbound shipment is delivered), Beach Depository delivers a signed HTTP POST to your registered URL via Svix.

How it works

  1. Register a webhook endpoint via the API
  2. Select which event types to subscribe to
  3. Store the signing secret securely — it is only shown once at creation
  4. Beach Depository delivers to your URL whenever a subscribed event fires

Inbound journey

The main inbound custody flow and the webhooks you receive: Between checked in and vaulted, items may be held internally before shelving. That intermediate state is not sent on webhooks. The first inventory webhook is vaulted.

What you will not receive

  • Floor-only inbound gate: pending_approval
  • Pre-vault inventory state: pending_shelve
  • Vault bin locations (binId / facility topology)
  • Outbound floor packing statuses: packing, inspecting, pending_approval on outbound shipments
  • Staff IDs, workstations, or check-in / shelving session identifiers

Creating a webhook

Via the API

Create endpoints with the API so URL rules (HTTPS + public hostname) are enforced:
Response:
The signing secret is only returned once at creation time. Store it securely — you will not be able to retrieve it again from the create response (you can rotate it in Settings > Webhooks).

Via the dashboard

Navigate to Settings > Webhooks to inspect deliveries, replay messages, and rotate signing secrets. Endpoint create/edit (including URL changes) is API-only so public-hostname URL validation cannot be bypassed.

Event types

Payload format

All webhook payloads follow the same structure:
  • event — one of the event types listed above
  • timestamp — Unix seconds when Beach Depository queued the delivery
  • data — event-specific fields; always includes id and organizationId
  • Document IDs are opaque Convex IDs (not prefixed strings like ship_…)

Status values

Whenever a payload includes status, fromStatus, or toStatus, the value is one of the sets below. fromStatus is omitted when the previous status was internal-only (not customer-visible).

Inventory (status / fromStatus / toStatus)

in_vault | pending_transfer | pending_outbound | shipped_out | returned | void

Inbound shipment (fromStatus / toStatus)

pending | in_transit | received | inspecting | accepted | partially_accepted | rejected | cancelled

Outbound request (fromStatus / toStatus)

pending | pending_checkout | denied | cancelled | fulfilling | fulfilled

Outbound shipment (fromStatus / toStatus)

approved | picked_up_by_carrier | shipped | delivered

Transfer (fromStatus / toStatus)

pending | approved | denied | cancelled | completed | partially_completed

Event payloads

inventory.vaulted

Fired once when an item first becomes available in vault (in_vault).

inventory.status_changed

inventory.valuation_changed

inbound_shipment.status_changed

outbound_request.status_changed

Emitted on create (toStatus: "pending"), approve, deny, cancel, fulfilling, and fulfilled.

outbound_shipment.status_changed

Filter on toStatus: "delivered" for delivery notifications (there is no separate delivered event).

transfer.status_changed

transfer.completed

fbo_account.created

fbo_account.updated

statement.generated

Signature verification

Every webhook request includes Svix signature headers for verifying authenticity:

Verifying in Node.js

Verifying in Python

See the Svix verifying payloads guide for more languages and framework examples.

Request headers

Each webhook delivery includes these headers: Use svix-id to deduplicate events if your endpoint receives the same delivery more than once during retries.

Retry policy

Delivery retries are managed by Svix with automatic exponential backoff. Failed deliveries appear in Settings > Webhooks where you can inspect responses and replay messages after fixing your endpoint.

Best practices

Return a 200 response as fast as possible. Process the event asynchronously (e.g., add it to a queue) rather than performing heavy work in the request handler.
Use the svix-id header to deduplicate. In rare cases, the same event may be delivered more than once during retries.
Always verify the Svix signature headers before processing a webhook. This ensures the request came from Beach Depository and was not tampered with. Use the raw request body for verification.
Webhook URLs must use https:// and a public DNS hostname. Bare IPs, private/loopback addresses, embedded credentials, and internal names (for example .local, .internal) are rejected. Create endpoints via the API so these rules are enforced.
Check delivery history in Settings > Webhooks periodically. If your endpoint has been failing, fix the issue and replay missed messages from the portal.

Testing locally

Use a tool like webhook.site, Svix Play, or ngrok to receive webhooks during development: