Personal, store and admin keys for integrations: make, list, rotate and revoke them. Managed with a signed-in session, never with another key.
/admin/api-keysAdmins see every admin key; moderators their own.
collector.listAdminApiKeys()X-Request-Id200OKAdmin keys.
not_found: Not an admin (moderator): the same 404 as a missing route.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
/admin/api-keysActs as you while you’re on staff. Must expire within 90 days, may be limited to addresses, and needs a sign-in from the last 12 hours. Moderators’ keys get moderation scopes only. Every write it makes is in the audit log.
collector.createAdminApiKey()Idempotency-KeyX-Request-Idnamestringrequired1–80 characters
scopesarray of enumrequired1–40 items
catalog:readcollection:readcollection:writewishlist:readwishlist:writescans:writescans:readlabels:readlabels:writeinsights:readinsights:writeexports:readholds:readholds:writequestions:readquestions:writeaccount:readaccount:writeaccount:deletereports:writestores:readstores:writeassistant:usestore:readstore:inventory:readstore:inventory:writestore:holds:readstore:holds:writestore:questions:readstore:questions:writestore:storefront:writestore:staff:readstore:staff:writestore:billing:readadmin:catalog:readadmin:catalog:writeadmin:moderation:writeadmin:imports:writeadmin:users:readadmin:users:writeadmin:support:writeadmin:ops:readadmin:ops:writeexpiresInDays"7" or "30" or "90" or "180" or "365" or nullDays until it stops working, or null for never. Admin keys must expire within 90 days.
default null
Option 1: "7"
Option 2: "30"
Option 3: "90"
Option 4: "180"
Option 5: "365"
ipAllowlistarray of string or nullAdmin keys only: the addresses or CIDR ranges it may be used from.
at most 20 items
201CreatedThe new key, shown once.
invalid_requestinvalid_jsoninvalid_idempotency_key
invalid_request: The query or body doesn’t match the schema (see errors[]).
invalid_json: The body isn’t JSON.
invalid_idempotency_key: The Idempotency-Key isn’t 1–255 visible ASCII characters.
reauthentication_required: Sign in again first.
not_found: Not an admin (moderator): the same 404 as a missing route.
idempotency_in_progresstoo_many_keys
idempotency_in_progress: The first request with this key is still running.
too_many_keys: Already 25 active keys here: revoke one first.
payload_too_large: The body is over 1,048,576 bytes, this operation’s limit.
idempotency_key_reused: This key was used for a different request.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
api_keys_unavailable: This deployment isn’t set up for API keys.
/admin/api-keys/{keyId}Admins can revoke any admin key; moderators their own.
collector.revokeAdminApiKey()X-Request-IdkeyIdstring (uuid)required200OKThe revoked key.
not_found: Not an admin (moderator): the same 404 as a missing route.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
/admin/api-keys/{keyId}/rotateMakes a new admin key with the same name, scopes, expiry and addresses, acting as you, and retires the old one, at once or after 24 hours. Like making one, it needs a sign-in from the last 12 hours.
collector.rotateAdminApiKey()Idempotency-KeyX-Request-IdkeyIdstring (uuid)requiredgraceHours"0" or "24"Keep the old key working this many hours, so integrations can switch over.
default 0
Option 1: "0"
Option 2: "24"
201CreatedThe new key (shown once) and the old one.
A rotated key: the new one (shown once) and the one it replaces.
tokenstringrequiredThe new key. Store it now: it can’t be shown again.
invalid_requestinvalid_jsoninvalid_idempotency_key
invalid_request: The query or body doesn’t match the schema (see errors[]).
invalid_json: The body isn’t JSON.
invalid_idempotency_key: The Idempotency-Key isn’t 1–255 visible ASCII characters.
reauthentication_required: Sign in again first.
not_found: Not an admin (moderator): the same 404 as a missing route.
idempotency_in_progresskey_not_active
idempotency_in_progress: The first request with this key is still running.
key_not_active: The key is revoked, expired or already rotating.
payload_too_large: The body is over 1,048,576 bytes, this operation’s limit.
idempotency_key_reused: This key was used for a different request.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
api_keys_unavailable: This deployment isn’t set up for API keys.
/api-keysYour personal keys, newest first, without their secrets.
collector.listMyApiKeys()X-Request-Id200OKYour keys.
unauthorized: Not signed in (no session or token, or an expired one).
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
/api-keysThe answer is the only time the whole key is shown. It acts as you, limited to its scopes. You’re emailed a security notice.
collector.createMyApiKey()Idempotency-KeyX-Request-Idnamestringrequired1–80 characters
scopesarray of enumrequired1–40 items
catalog:readcollection:readcollection:writewishlist:readwishlist:writescans:writescans:readlabels:readlabels:writeinsights:readinsights:writeexports:readholds:readholds:writequestions:readquestions:writeaccount:readaccount:writeaccount:deletereports:writestores:readstores:writeassistant:usestore:readstore:inventory:readstore:inventory:writestore:holds:readstore:holds:writestore:questions:readstore:questions:writestore:storefront:writestore:staff:readstore:staff:writestore:billing:readadmin:catalog:readadmin:catalog:writeadmin:moderation:writeadmin:imports:writeadmin:users:readadmin:users:writeadmin:support:writeadmin:ops:readadmin:ops:writeexpiresInDays"7" or "30" or "90" or "180" or "365" or nullDays until it stops working, or null for never. Admin keys must expire within 90 days.
default null
Option 1: "7"
Option 2: "30"
Option 3: "90"
Option 4: "180"
Option 5: "365"
ipAllowlistarray of string or nullAdmin keys only: the addresses or CIDR ranges it may be used from.
at most 20 items
201CreatedThe new key, shown once.
invalid_requestinvalid_jsoninvalid_idempotency_key
invalid_request: The query or body doesn’t match the schema (see errors[]).
invalid_json: The body isn’t JSON.
invalid_idempotency_key: The Idempotency-Key isn’t 1–255 visible ASCII characters.
unauthorized: Not signed in (no session or token, or an expired one).
idempotency_in_progresstoo_many_keys
idempotency_in_progress: The first request with this key is still running.
too_many_keys: Already 25 active keys here: revoke one first.
payload_too_large: The body is over 1,048,576 bytes, this operation’s limit.
idempotency_key_reused: This key was used for a different request.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
api_keys_unavailable: This deployment isn’t set up for API keys.
/api-keys/{keyId}It stops working at once. Revoking a revoked key answers it unchanged.
collector.revokeMyApiKey()X-Request-IdkeyIdstring (uuid)required200OKThe revoked key.
unauthorized: Not signed in (no session or token, or an expired one).
not_found: Nothing at that address.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
/api-keys/{keyId}/rotateMakes a new key with the same name, scopes and expiry, and retires the old one, at once or after 24 hours.
collector.rotateMyApiKey()Idempotency-KeyX-Request-IdkeyIdstring (uuid)requiredgraceHours"0" or "24"Keep the old key working this many hours, so integrations can switch over.
default 0
Option 1: "0"
Option 2: "24"
201CreatedThe new key (shown once) and the old one.
A rotated key: the new one (shown once) and the one it replaces.
tokenstringrequiredThe new key. Store it now: it can’t be shown again.
invalid_requestinvalid_jsoninvalid_idempotency_key
invalid_request: The query or body doesn’t match the schema (see errors[]).
invalid_json: The body isn’t JSON.
invalid_idempotency_key: The Idempotency-Key isn’t 1–255 visible ASCII characters.
unauthorized: Not signed in (no session or token, or an expired one).
not_found: Nothing at that address.
idempotency_in_progresskey_not_active
idempotency_in_progress: The first request with this key is still running.
key_not_active: The key is revoked, expired or already rotating.
payload_too_large: The body is over 1,048,576 bytes, this operation’s limit.
idempotency_key_reused: This key was used for a different request.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
api_keys_unavailable: This deployment isn’t set up for API keys.
/api-keys/scopesEvery scope a key can hold, which kinds of key may hold it, and the presets the key screens offer.
collector.listApiKeyScopes()If-None-MatchX-Request-Id200OKThe scope catalogue.
Every scope a key can hold, and the presets the key screens offer.
scopesarray of objectrequirednamestringrequireddescriptionstringrequiredgroupstringrequiredwritebooleanrequiredkindsarray of enumrequiredpersonalstoreadminpresetsarray of objectrequiredidstringrequiredlabelstringrequireddescriptionstringrequiredkindenumrequiredpersonalstoreadminscopesarray of stringrequired304Not ModifiedNot modified: your copy (the ETag in If-None-Match) is current.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
/stores/{storeId}/api-keysThe store’s keys, for its owners and admins.
collector.listStoreApiKeys()X-Request-IdstoreIdstring (uuid)required200OKThe store’s keys.
unauthorized: Not signed in (no session or token, or an expired one).
forbidden: Store staff can’t manage keys.
not_found: Nothing at that address.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
/stores/{storeId}/api-keysFor the store’s point of sale or inventory system. It acts for this store only, as the manager who makes it; it stops working if they leave the store or become staff. The store’s owners are emailed.
collector.createStoreApiKey()Idempotency-KeyX-Request-IdstoreIdstring (uuid)requirednamestringrequired1–80 characters
scopesarray of enumrequired1–40 items
catalog:readcollection:readcollection:writewishlist:readwishlist:writescans:writescans:readlabels:readlabels:writeinsights:readinsights:writeexports:readholds:readholds:writequestions:readquestions:writeaccount:readaccount:writeaccount:deletereports:writestores:readstores:writeassistant:usestore:readstore:inventory:readstore:inventory:writestore:holds:readstore:holds:writestore:questions:readstore:questions:writestore:storefront:writestore:staff:readstore:staff:writestore:billing:readadmin:catalog:readadmin:catalog:writeadmin:moderation:writeadmin:imports:writeadmin:users:readadmin:users:writeadmin:support:writeadmin:ops:readadmin:ops:writeexpiresInDays"7" or "30" or "90" or "180" or "365" or nullDays until it stops working, or null for never. Admin keys must expire within 90 days.
default null
Option 1: "7"
Option 2: "30"
Option 3: "90"
Option 4: "180"
Option 5: "365"
ipAllowlistarray of string or nullAdmin keys only: the addresses or CIDR ranges it may be used from.
at most 20 items
201CreatedThe new key, shown once.
invalid_requestinvalid_jsoninvalid_idempotency_key
invalid_request: The query or body doesn’t match the schema (see errors[]).
invalid_json: The body isn’t JSON.
invalid_idempotency_key: The Idempotency-Key isn’t 1–255 visible ASCII characters.
unauthorized: Not signed in (no session or token, or an expired one).
forbidden: Store staff can’t manage keys.
not_found: Nothing at that address.
idempotency_in_progresstoo_many_keys
idempotency_in_progress: The first request with this key is still running.
too_many_keys: Already 25 active keys here: revoke one first.
payload_too_large: The body is over 1,048,576 bytes, this operation’s limit.
idempotency_key_reused: This key was used for a different request.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
api_keys_unavailable: This deployment isn’t set up for API keys.
/stores/{storeId}/api-keys/{keyId}It stops working at once. Owners and admins can revoke any of the store’s keys.
collector.revokeStoreApiKey()X-Request-IdstoreIdstring (uuid)requiredkeyIdstring (uuid)required200OKThe revoked key.
unauthorized: Not signed in (no session or token, or an expired one).
not_found: Nothing at that address.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
/stores/{storeId}/api-keys/{keyId}/rotateThe new key acts as the manager who rotates it.
collector.rotateStoreApiKey()Idempotency-KeyX-Request-IdstoreIdstring (uuid)requiredkeyIdstring (uuid)requiredgraceHours"0" or "24"Keep the old key working this many hours, so integrations can switch over.
default 0
Option 1: "0"
Option 2: "24"
201CreatedThe new key (shown once) and the old one.
A rotated key: the new one (shown once) and the one it replaces.
tokenstringrequiredThe new key. Store it now: it can’t be shown again.
invalid_requestinvalid_jsoninvalid_idempotency_key
invalid_request: The query or body doesn’t match the schema (see errors[]).
invalid_json: The body isn’t JSON.
invalid_idempotency_key: The Idempotency-Key isn’t 1–255 visible ASCII characters.
unauthorized: Not signed in (no session or token, or an expired one).
not_found: Nothing at that address.
idempotency_in_progresskey_not_active
idempotency_in_progress: The first request with this key is still running.
key_not_active: The key is revoked, expired or already rotating.
payload_too_large: The body is over 1,048,576 bytes, this operation’s limit.
idempotency_key_reused: This key was used for a different request.
rate_limitedtemporarily_blocked
rate_limited: Over the caller’s limit: the per-minute burst or the per-day quota (RateLimit headers; wait Retry-After seconds).
temporarily_blocked: Too many refused requests in a row: blocked for a while (Retry-After says how long).
internal: Something went wrong on our side (quote the requestId).
api_keys_unavailable: This deployment isn’t set up for API keys.