Customei can POST JSON payloads to an HTTPS endpoint you control whenever an order event fires. Use webhooks to trigger fulfillment, notify a Slack channel, write to your data warehouse, or kick off any custom automation.Documentation Index
Fetch the complete documentation index at: https://docs.customei.com/llms.txt
Use this file to discover all available pages before exploring further.
Events you can subscribe to
Every subscription listens to one or more of the following events. Events correspond to Shopify order lifecycle transitions:| Event | Fires when |
|---|---|
order.created | A new order is placed. |
order.updated | Any order field changes after creation. |
order.paid | The order’s financial status moves to paid. |
order.fulfilled | The order (or a line item) is fulfilled. |
order.cancelled | The order is cancelled. |
order.paid and order.updated. Always make your handler idempotent (see Delivery guarantees).
Create a subscription
Enter your endpoint URL
Must be HTTPS. HTTP endpoints are rejected at save time. Plain IP addresses are allowed but not recommended — use a domain with a valid TLS certificate.
Accept the data-handling notice
Webhook payloads include order and (anonymized) customer data. Confirm you’re responsible for handling them securely before creating the subscription.
Payload shape
Every delivery is a POST request with a JSON body:Field notes
event— the specific event that matched this subscription (e.g. a single subscription listening to bothorder.paidandorder.updatedwill get two separate deliveries when both fire).trigger— the underlying order lifecycle change, mapped from Shopify’s topic. Useful when multiple events share a trigger.timestamp— ISO-8601 in UTC.data.order.id— Customei’s internal order ID (prefixedord_). Use this as your primary key when deduplicating.data.order.shopifyOrderId— Shopify’s numeric order ID. Handy for cross-referencing Shopify Admin.data.order.lineItems[].properties— the personalization payload, flattened to key-value pairs per line item. For richer data (uploaded image URLs, bound layer metadata), query the GraphQL API using theid.data.order.lineItems[].productionStatus— Customei’s internal print-file state:PENDING/GENERATING/READY/FAILED.
Verify the signature
Every request includes two headers:X-Pod-Timestamp— request timestamp in ISO-8601.X-Pod-Signature—sha256=<hex-digest>HMAC over${timestamp}.${rawBody}using your subscription secret.
Node.js example
401 — Customei will retry and log the failure.
Python example
Reject stale requests
Compare the timestamp against your server clock and reject anything more than 5 minutes off. This protects against replay attacks even if a signature is leaked.Verification challenge on create
When you create a new subscription, Customei immediately sends a verification request to your URL — aPOST with a special event: "_verification" payload. Your server must respond with 200 OK within 10 seconds. If it doesn’t, Customei refuses to activate the subscription and shows the error in the UI.
This is a light cost to set up but saves you from shipping a broken subscription to production.
Delivery guarantees
Webhooks are delivered at-least-once. Your handler must be idempotent — receiving the same event twice should not double-charge, double-fulfill, or double-anything.- Timeouts. Your endpoint has 10 seconds to respond. Beyond that, Customei treats the delivery as failed.
- Retries. Failed deliveries (non-2xx status, timeout, network error) are retried with exponential backoff starting at 30 seconds, for up to 5 attempts. After the fifth failure, the delivery is marked permanently failed and surfaced in the subscription’s delivery log.
- Ordering. Deliveries are not guaranteed to arrive in chronological order, especially across retries. Use the
timestampfield to reconstruct ordering yourself if you need it. - Deduplication. Use
data.order.id+eventas your idempotency key.
View delivery history
Each subscription has a Deliveries tab showing recent attempts, their status, response code, and response body (truncated). Click an individual delivery to replay the payload for debugging.- Succeeded — your endpoint returned 2xx.
- Failed — at least one attempt failed; check the last response body for the reason.
- Pending — queued for delivery but not sent yet.
Manually replay a delivery
From the delivery log, click Replay on any past delivery. Customei sends the exact same payload (including the original timestamp and a fresh signature) to your endpoint. Handy for reproducing bugs in staging.Edit or pause a subscription
- Edit — change the URL, events, or description. The secret stays the same unless you explicitly rotate it.
- Pause — temporarily stop deliveries without deleting the subscription. Incoming events during a pause are dropped; they’re not queued for later delivery.
- Delete — permanently removes the subscription and its delivery history.
Rotate the secret
From the subscription’s settings, click Rotate secret. Customei issues a new secret and shows it once — copy it and deploy it to your server before sending the next event. There’s no grace period — the old secret stops working immediately on rotation.Limits
- 10 active subscriptions per account. Contact Support if you need more.
- 10-second handler timeout.
- 5 retry attempts per delivery.
- Payloads are capped at 1 MB. Events that would exceed this are truncated; line-item properties are the most common culprit.
Troubleshooting
- I’m getting duplicate events. Normal under retry; dedupe on
data.order.id+event. - The signature doesn’t match. Make sure you’re signing
${timestamp}.${rawBody}, not the parsed JSON. The body must be the exact bytes received, before any framework parses it. - Timestamps feel wrong. They’re UTC ISO-8601. Your server might be comparing against local time.
- Verification challenge fails. Your endpoint needs to respond 2xx to the initial test POST with
event: "_verification"— many merchants forget their auth middleware blocks un-signed requests and reject the challenge.
Next
- API overview — for two-way integrations.
- Integrations overview
- Roles and permissions