How it works
- Register a webhook endpoint via the API
- Select which event types to subscribe to
- Store the signing secret securely — it is only shown once at creation
- 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_approvalon 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: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 abovetimestamp— Unix seconds when Beach Depository queued the deliverydata— event-specific fields; always includesidandorganizationId- Document IDs are opaque Convex IDs (not prefixed strings like
ship_…)
Status values
Whenever a payload includesstatus, 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
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
Respond quickly
Respond quickly
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.Handle duplicates
Handle duplicates
Use the
svix-id header to deduplicate. In rare cases, the same event may be delivered more than
once during retries.Verify signatures
Verify signatures
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.
HTTPS required
HTTPS required
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.Monitor deliveries
Monitor deliveries
Check delivery history in Settings > Webhooks periodically. If your endpoint has been
failing, fix the issue and replay missed messages from the portal.