Store API
A read-only REST API over this store's cart drawer data, for your own scripts, dashboards and
integrations. Every endpoint is a GET, every response has the same shape, and each key belongs to
one store.
If what you want is an AI assistant that can answer questions about the store, you want MCP instead. This surface is for code you write.
| Base URL | https://aov-cart-drawer.firebaseapp.com/store-api/v1 |
| Methods | GET only |
| Credential | A key beginning aov_sk_ |
| Sent as | Authorization: Bearer aov_sk_… |
| Rate limit | 60 requests per minute, per key |
| Requires | A paid subscription, re-checked on every request |
Copy the Base URL from the app rather than typing the one above — it is shown in Settings → Store API, and it is the one correct for your store.
Create a key
- In AOV.ai Cart Drawer, go to Settings, then the Store API tab.
- Copy the Base URL.
- Name the key after the integration it is for. 1–40 characters.
- Click Create key.
The key is shown once, with a ready-to-run example underneath.
The key appears only at this moment. The server stores a fingerprint, not the key, so it cannot be shown again — not by you, and not by support. Copy it into your secret store before closing the banner.
Your first request
curl "https://aov-cart-drawer.firebaseapp.com/store-api/v1/setup-health" \
-H "Authorization: Bearer aov_sk_YOUR_KEY"const res = await fetch(
'https://aov-cart-drawer.firebaseapp.com/store-api/v1/analytics?start=2026-08-01&end=2026-08-31',
{headers: {Authorization: 'Bearer aov_sk_YOUR_KEY'}}
);
const {success, data, error} = await res.json();Every response has the same shape
{"success": true, "data": { }, "error": null}On failure, success is false, data is null, and error carries a stable code:
{"success": false, "data": null, "error": {"code": "INVALID_INPUT", "message": "…"}}Branch on error.code or on the HTTP status, not on the message. Codes and statuses are
stable; wording is not. Both are listed in Errors.
The envelope holds even for failures outside the router — a bad path, an unexpected server error. You will never get an HTML error page back.
The API describes itself
GET /store-api/v1 returns the endpoint list with each path, its summary and the query parameters
it accepts. It is generated from the same table that builds the routes, so it cannot fall out of date
with what exists. It needs a key, like everything under the prefix.
Never call this from a browser
The API sends permissive CORS headers, so a request from browser JavaScript will succeed. That is there for server-side tools and local development, not for your storefront.
A key in browser code is a key you have published. Anything running in a shopper's browser is readable by that shopper; bundling or minifying changes nothing. Call this API from your server, and let the browser talk to your server.
If a key has ever shipped to a browser, revoke it and create a new one. Removing the code does not un-publish what was already served.
Keys are per surface
| Prefix | Surface | For |
|---|---|---|
aov_sk_ | /store-api/v1 | This API |
aov_mcp_ | /mcp | AI clients — see MCP |
Present an aov_mcp_ key here and the response says so by name — WRONG_SURFACE — rather than
reporting it invalid, because the fix is to mint the right kind of key, not to hunt for a typo.
Losing the subscription revokes your keys
When a request arrives from a store that is no longer on a paid subscription, the response is
NO_PLAN and that store's Store API keys are revoked. Renewing does not bring them back — you
create new keys and update the integration with them.
Every other refusal here is recoverable with the same key. This one is not, so an integration that
retries through it will move from NO_PLAN to INVALID_KEY and stay there. Treat NO_PLAN as
an alert, not as a backoff.
Nothing changes on the MCP side: connections there are refused while the subscription is gone and resume when it returns.
Limits
| Requests | 60 per minute, per key |
| Result size | 16,000 characters per response |
| Analytics window | 400 days |
Rate limits are counted per key, so one integration cannot exhaust another's budget. Requests are counted before the key is resolved, so a flood of bad keys is throttled too.
What is never returned
- No customer data. No names, emails, addresses, or individual orders. Analytics figures are aggregates over a date range.
- No credentials or internal ids. The Shopify access token, the store's record id and the key's fingerprint are stripped before anything leaves the server.
- No write access. There is no
POST,PUTorDELETE. Nothing you call can change a template, a setting or a subscription.
Where next
- Endpoints — all six, with their parameters
- Errors — every code, what causes it, what to do
- MCP tool guide — the meaning of the fields each endpoint returns