Getting started
The Perkss Partner API lives under /api/v1. All requests use HTTPS, JSON bodies (unless noted), and a Bearer token obtained with your API key.
Every API key belongs to exactly one company. Everything you read or write is scoped to that company.
Authentication
Create an API key
In the Perkss CMS, go to API Keys in your “Admin” panel and create a client_secret (prefixed perkss_sk_live_).The secret is shown exactly once — store it in a secret manager. Only a display prefix is visible afterwards.
If you lose it, you will have to create a new one. Keep it safe!
client_secret is a server-side credential. Never embed it in a browser, mobile app, or public repository. If a secret leaks,
revoke the key in the CMS — revocation immediatelyery token minted from it**.
POST /api/v1/auth/logout revokes the calling tok
Rate limits
Limits are enforced per minute, in separate buckets:
Reads and writes never share a bucket, so heavy re(and vice versa).
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (seconds until the window resets). When you exceed a limit you get 429 with code RATE_LIMIT.EXCEEDED and a Retry-After header (seconds). Honor Retry-After — retrying earlier only consumes your next window.
Idempotency
Transaction writes move money-like state, so they are protected against accidental double-execution.
Send an Idempotency-Key header — any unique stri
How it behaves:
- Retry with the same key and same body → the original response is replayed (stored for 24 hours). The write executes once.
- Same key, different body →
409 IDEMPOTENCY.PAYLOAD_MISMATCH. Keys identify one operation; never reuse them. - Duplicate while the first attempt is still running →
409 IDEMPOTENCY.REQUEST_IN_PROGRESSwithRetry-After. Wait and retry
with the same key. - Failed requests are not stored — retrying a rejected write with the same key re-executes it once the blocking condition is resolved.
Keys are scoped per company, method, and path, so a key used on one endpoint never replays another endpoint’s response.
Errors
Two shapes, by design:
The token endpoint returns standard OAuth error bodies (RFC 6749 §5.2):
Everything else returns the Perkss error envelope:
Codes worth handling explicitly:
Include the requestId when contacting support — es.
Customer identity
- Phone is the identity. It’s required at creation, accepted in any parseable format, and stored canonicalized to E.164. Creating a customer with an already-registered phone returns
409— one phone, one customer per company. externalIdis your alias. Optional, uniqueterable (GET /customers?externalId=…returns 0 or1 rows). Use it to link Perkss customers to your own system without storing our ids.- Email is not an identity. Multiple customers may share one; the email filter returns all of them.
Pagination
List endpoints take page (1-based, default 1) and pageSize (default 20, max 100) and always return the same shape:
The API is browser-callable (CORS allows any origin, Bearer-only, no cookies), but because the client_secret must stay server-side, the intended integration is from your backend.

