Developer API keys, request limits and errors
How to create an API key, test it, and stay inside the request limits of the Zepio Developer API. What each error means and what to do about it.
Updated 19 Oct 2026 4 min read
On this page
Read this first if you are connecting your own code, an ERP or a billing system to your Zepio store. It covers what every endpoint has in common: keys, limits and errors.
Where: Admin › Settings › Developer API
Create an API key
- Go to Settings › Developer API and click Create API key.
- Give the key a name you will recognise later, for example "Tally sync".
- Tick only the abilities this key needs. A key for stock sync needs Update products and nothing else.
- Optionally set an expiry date. A key with no expiry works until you delete it.
- Copy the key when it is shown. It is shown only once. If you lose it, delete the key and create a new one.
A store can have up to 20 API keys.
Abilities
| Ability | What it allows |
|---|---|
orders:read |
Read orders |
orders:update |
Move orders along (accept, ship, complete, cancel) and add tracking |
customers:read |
Read customers |
products:read |
Read products, categories and taxes |
products:update |
Bulk update products |
blog:create |
Create blog posts |
Send the key
Every request goes to your own store domain and carries the key as a Bearer token.
https://yourwebsite.com/api/developer/v1
Authorization: Bearer YOUR_API_KEY
Accept: application/json
Test your key
GET /me works with any valid key. It tells you which store the key belongs to, what it can do and your request limits. It is the quickest way to check a new key.
curl -X GET "https://yourwebsite.com/api/developer/v1/me" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
{
"success": true,
"message": "OK",
"data": {
"store": "yourstore",
"key": {
"name": "Tally sync",
"abilities": ["products:update"],
"expires_at": null,
"created_at": "2026-10-17T06:52:53+00:00"
},
"rate_limits": {
"read": 60,
"product_sync": 2,
"order_write": 30,
"content": 10
}
}
}
Request limits
Zepio sets these limits for every store. They are per minute, per store, and shared by all your API keys. Creating more keys does not give you more requests.
| What | Endpoints | Limit |
|---|---|---|
| Reading | GET /orders, /customers, /products, /categories, /taxes, /me |
60 a minute |
| Product updates | POST /products/bulk-update |
2 a minute |
| Order updates | POST /orders/{id}/status |
30 a minute |
| Blog posts | POST /blog/create |
10 a minute |
| AI assistant (MCP) | Every call Claude makes to your store | 120 a minute |
Every successful reply tells you where you stand:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
Stay inside the limits
- Let Zepio tell you about orders. Instead of asking
GET /ordersevery minute, add a webhook. Zepio sends each new order and status change to your URL as it happens, and webhooks do not count towards your limits. - Send changes in bulk. One product update request can carry up to 2000 products. Send one request with all your changes, not one request per product.
- Ask only for what changed. Use
updated_afteron orders and products, andcreated_afteron orders and customers, with the time of your last sync. - Use
per_page=100when you read lists, so you need fewer requests. - Wait when you are told to. If you get a
429, wait forretry_afterseconds before you try again.
Errors
Every error reply has success: false and a message.
| Status | Meaning | What to do |
|---|---|---|
401 |
No key was sent, or the key is wrong, deleted or expired | Check the Authorization header. Create a new key if needed |
403 |
The key is valid but does not have the ability this endpoint needs | Edit the key in Settings › Developer API and tick the ability |
404 |
The order, customer or product does not exist | Check the ID |
409 |
The change cannot be made to the order as it stands, for example shipping an order that was never accepted | Read message and current_status, fetch the order, and decide what to send next |
422 |
Something in the request is missing or invalid | Read errors, which lists each field and what is wrong |
429 |
Too many requests | Wait for retry_after seconds (also in the Retry-After header), then send it again |
Too many requests
{
"success": false,
"message": "Rate limit exceeded.",
"retry_after": 41
}
A request that gets 429 is not processed at all. Nothing in it is saved, so send it again after the wait.
If the same server keeps sending a wrong or deleted key, after 20 failed requests in a minute it starts getting 429 instead of 401 for those requests. Valid keys from that server keep working.
Keep your keys safe
- Treat a key like a password. Keep it on your server, never in a website, app or public code.
- Give each integration its own key with only the abilities it needs. If one leaks, delete just that key.
- Delete keys you no longer use. Last used on each key shows whether it is still in use.