Queek API docs

Authentication

One header, two kinds of key, and the rules the browser one plays by.

Base URL:

https://client.usequeek.com/v1

Every request carries the store's API key in X-Client-Key, and should ask for JSON:

curl https://client.usequeek.com/v1/store/info \
  -H "X-Client-Key: pk_live_your_key_here" \
  -H "Accept: application/json"

There is no OAuth flow and no token exchange. The key is the credential, and it belongs to one store: a key never reaches another merchant's data.

Two kinds of key

The merchant mints both in the dashboard under Settings → API keys.

pk_live_… — public

Made to be shipped in browser code, where anyone can read it. Because the key itself cannot be a secret there, the browser's Origin is what is actually checked: a public key only works from an origin on its own allowlist, which the merchant controls. Typically that is http://localhost:3000 while building and the real domain in production.

A public key whose allowlist is * works from any origin and from none — which is what makes it the practical choice for an AI or a script building a site before that site has a domain. Ask the merchant to narrow it to the real domain at launch.

Calling an origin-restricted public key from a terminal or a test runner? Send an allowlisted origin yourself:

curl https://client.usequeek.com/v1/store/products \
  -H "X-Client-Key: pk_live_your_key_here" \
  -H "Origin: https://the-store.example"

sk_live_… — private

For servers, SSR and build-time fetches, and native apps — anywhere the key is not handed to a visitor. A private key needs no Origin, and it must never appear in a browser bundle, a public repository, or a client-side environment variable.

Rule of thumb

If a visitor's device can read the string, it has to be a pk_live_ key with a real origin allowlist.

What the browser is allowed to send

Cross-origin requests may carry X-Client-Key, X-Cart-Session, If-None-Match, Content-Type and Accept. Anything else is not part of the CORS contract.

Rate limits

180 requests per minute, per API key and IP. A 429 carries Retry-After and the X-RateLimit-* headers, which are on successful responses too — read x-ratelimit-remaining rather than guessing.

Reads answer with an ETag and Cache-Control: private, no-cache. Send the value back as If-None-Match and an unchanged resource costs you a 304 instead of a payload.

When authentication fails

The reply carries error_code — it names exactly what to fix.

error_codeStatusWhat it means
client_key_required401No X-Client-Key header was sent.
invalid_client_key401The key is unknown or was revoked.
origin_required403A public key was used with no Origin and its allowlist is not *.
origin_not_allowed403The Origin is not on this key's allowlist. The message lists the ones that are.
plan_inactive403The store's plan does not include API access.
route_not_available404Not part of this API — the endpoints are exactly those in the reference.

An origin_* failure is the merchant's to fix, not yours: they add your origin to the key, or set it to *. See versioning & errors for the full envelope.

On this page