Developer API
The Automations API lets other tools follow what happens in a Zepsell store: new and paid orders, refunds, cancellations, new customers and product changes. It is what Zepsell's Zapier app uses, and you can call it from Make, n8n or your own code. It is included with every store, at no extra cost.
Getting a key
In your Zepsell dashboard, open your store, go to Apps > Automations, install it, and make a key under API keys. A key starts with zsk_, works for that one store only and is shown once. Revoking a key stops it at once and removes the hooks it made. A store can have up to 20 keys and 100 hooks.
Authentication
Send the key on every request, either as a bearer token or in X-API-Key. All requests and answers are JSON over HTTPS. The base URL is https://zepsell.com/api/automations/v1.
curl https://zepsell.com/api/automations/v1/me \ -H "Authorization: Bearer zsk_your_key"
Errors come back as { "error": "what went wrong" } with a status code: 400 for a bad request, 401 for a missing or revoked key, 403 when the Automations app isn't installed or the store is paused, 404 for an unknown hook or event, 429 when rate limited (with Retry-After), and 503 when the store couldn't be read just then. Each key can make 120 requests a minute.
Endpoints
GET /me
The store the key belongs to. Zapier uses it to test a connection.
{
"store": {
"id": "sto_example",
"name": "Example Shop",
"slug": "example-shop"
},
"key": {
"id": "key_example",
"name": "Zapier",
"prefix": "zsk_AbC123"
}
}GET /events
The events a hook can subscribe to, as { "events": [{ "key", "name", "description" }] }.
POST /hooks
Subscribes a URL to one event (REST Hooks). The body is { "event": "order.paid", "target_url": "https://..." }. The answer is 201 with the hook's id. The URL must be public HTTPS on port 443; addresses on private networks are refused. A new hook only receives events that happen after it was made.
curl -X POST https://zepsell.com/api/automations/v1/hooks \
-H "Authorization: Bearer zsk_your_key" \
-H "Content-Type: application/json" \
-d '{"event":"order.paid","target_url":"https://example.com/zepsell"}'GET /hooks
The store's hooks: id, event, target_url, source, active, created_at, last_delivery_at and consecutive_failures.
DELETE /hooks/{id}
Unsubscribes. Zapier calls this when a zap is turned off.
GET /samples/{event}
The store's latest three real records for an event, newest first, each exactly as a webhook would send it. An empty list when there are none yet. Use it to see the data shape, or to poll instead of subscribing.
Events
order.created: An order is placed, paid or not.order.paid: An order's payment is taken.order.refunded: Money is refunded on an order, once per refund.order.canceled: An order is cancelled.customer.created: A customer signs up or checks out for the first time.product.created: A product is added.product.updated: A product's details change.
Events go out a few minutes after they happen. Order payment, refunds and cancellations are checked for 30 days after an order is placed. A product counts as updated when its details, variants or prices change.
Webhooks
Each event is POSTed to every hook subscribed to it, as application/json, with these headers:
X-Zepsell-Event: the event, e.g.order.paidX-Zepsell-Delivery: this delivery's own idX-Zepsell-Timestamp: Unix seconds when it was sentX-Zepsell-Signature:sha256=and the hex HMAC-SHA256 of<timestamp>.<raw body>, keyed with your store's signing secret (Apps > Automations)
The body's id is the same for an event wherever it goes and however often it is tried, so you can ignore a repeat. Answer with any 2xx status. Anything else is tried again after 1 min, 5 min, 15 min, 1 h, 3 h, 6 h, 12 h: 8 tries in all. 410 Gone removes the hook. A hook that fails 30 times in a row over at least 6 hours is switched off, and can be switched back on in the dashboard.
Checking the signature (Node.js)
import { createHmac, timingSafeEqual } from "node:crypto"
function fromZepsell(rawBody, headers, secret) {
const ts = headers["x-zepsell-timestamp"]
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false
const want = "sha256=" + createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex")
const got = headers["x-zepsell-signature"] ?? ""
return want.length === got.length && timingSafeEqual(Buffer.from(want), Buffer.from(got))
}Example payloads
Money is in the order's currency, in major units (42.50 is £42.50).
order.paid
{
"id": "evt_3f9c2a7b1e4d8c6a0b5f2e19",
"event": "order.paid",
"occurred_at": "2026-11-07T10:00:00.000Z",
"store": {
"id": "sto_example",
"slug": "example-shop",
"name": "Example Shop"
},
"data": {
"id": "order_example",
"number": "#1001",
"display_id": 1001,
"status": "pending",
"payment_status": "captured",
"fulfillment_status": "not_fulfilled",
"email": "[email protected]",
"currency": "GBP",
"total": 42.5,
"subtotal": 35.42,
"tax_total": 7.08,
"shipping_total": 3.95,
"discount_total": 0,
"created_at": "2026-11-09T11:09:35.589Z",
"customer": {
"id": "cus_example",
"email": "[email protected]",
"first_name": "Sam",
"last_name": "Example",
"phone": "+44 7700 900123",
"has_account": true
},
"shipping_address": {
"first_name": "Sam",
"last_name": "Example",
"company": "",
"phone": "+44 7700 900123",
"address_1": "1 Example Street",
"address_2": "",
"city": "London",
"province": "",
"postal_code": "N1 1AA",
"country_code": "GB"
},
"billing_address": null,
"items": [
{
"id": "item_example",
"title": "Example T-shirt (Large)",
"product_id": "prod_example",
"variant_id": "variant_example",
"sku": "TEE-L",
"quantity": 2,
"unit_price": 19.28,
"total": 38.55
}
],
"refunded_total": 0,
"store_url": "https://example-shop.zepsell.com"
}
}customer.created
{
"id": "evt_3f9c2a7b1e4d8c6a0b5f2e19",
"event": "customer.created",
"occurred_at": "2026-11-07T10:00:00.000Z",
"store": {
"id": "sto_example",
"slug": "example-shop",
"name": "Example Shop"
},
"data": {
"id": "cus_example",
"email": "[email protected]",
"first_name": "Sam",
"last_name": "Example",
"phone": "+44 7700 900123",
"company": "",
"has_account": true,
"created_at": "2026-11-09T11:09:35.590Z"
}
}product.updated
{
"id": "evt_3f9c2a7b1e4d8c6a0b5f2e19",
"event": "product.updated",
"occurred_at": "2026-11-07T10:00:00.000Z",
"store": {
"id": "sto_example",
"slug": "example-shop",
"name": "Example Shop"
},
"data": {
"id": "prod_example",
"title": "Example T-shirt",
"handle": "example-t-shirt",
"status": "published",
"subtitle": "",
"description": "A soft cotton T-shirt.",
"thumbnail": "",
"url": "https://example-shop.zepsell.com/products/example-t-shirt",
"created_at": "2026-11-09T11:09:35.590Z",
"updated_at": "2026-11-09T11:11:35.590Z",
"variants": [
{
"id": "variant_example",
"title": "Large",
"sku": "TEE-L",
"prices": [
{
"amount": 19.28,
"currency": "GBP"
}
]
}
]
}
}Zapier and Make
In Zapier, choose Zepsell as the trigger app and connect with a key. In Make or n8n, add a custom webhook module, then add its address in Apps > Automations > Add a webhook and press Send a test so the tool learns the data shape.
AI apps (MCP)
To work with a store from Claude, ChatGPT, Claude Code, Cursor or another MCP client, use the remote MCP server at https://zepsell.com/mcp instead of an API key. It signs in with OAuth 2.1 (dynamic client registration and PKCE), and the merchant picks the stores and whether the app can make changes. Setup steps and the list of tools are on Connect AI apps.
Help
Questions about the API: contact the Zepsell team.