SmartEPI External API
REST API for integrating SmartEPI organizational and transactional data with external systems (ERP / BI / internal tools).
Authentication. Send your API key as a bearer token:
Authorization: Bearer sk_live_…. Keys are minted in the web console
(Settings ▸ API Integration). A key is tenant-scoped — it only ever reads and
writes your own organization's data — and grants full access to every
endpoint in this API.
Versioning. The contract is versioned in the path (/v1). Within a
version, changes are additive only.
Envelope. Every response wraps its payload: a single record is
{ "data": <entity> }; a list is { "data": [<entity>, …], "cursor": <string|null> }.
Pagination. List endpoints return an opaque cursor; pass it back as the
cursor query parameter to fetch the next page. A null cursor means the
last page. Treat the cursor as opaque.
Errors. Application errors (400/403/404/405/409/422/429/500) use
RFC 7807 application/problem+json with a type of the form
urn:smartepi:error:<token>, and carry an X-Request-Id header. (A 403
means the request was authenticated but rejected — e.g. the key's IP
allow-list blocked the source IP.) Authentication failures are different: a
missing, malformed, unknown, or revoked key is rejected by the API gateway
before the application runs, so it returns a plain
{ "message": "Unauthorized" } (401) or an access-denied body (403) —
not RFC 7807, and without an X-Request-Id.
Writes & concurrency. Organization entities (sectors, cost centers, job
roles, groups, employees, products) support create / update / delete.
Updates and deletes use optimistic concurrency via the
ETag/If-Match headers: every read and write response returns the
record's current version as a strong ETag (e.g. ETag: "4"); send that value
back as If-Match on a subsequent update/delete. A stale value returns 409;
a missing one returns 400. (The body field _version is also accepted on
write, but the version is never returned in any response body — only via
ETag.) A successful create returns 201 with a Location header pointing at
the new resource. Any foreign key you set must exist in your organization or
the write is rejected with 422. A delete soft-deletes the record and returns
200 with the deleted entity as { "data": <entity> }; the record then
disappears from lists and GET-by-id returns 404. A delete is rejected with
409 (resource_in_use) if the entity is still referenced by other records
(e.g. an employee's sectorId, or a product in a group rule) — re-point or
remove the dependents first. Deleting a product also removes its sizes +
certificates. Transactions are read-only — devices are their sole origin.
Access. Every API key grants full access to all endpoints in this API. There are no per-entity scopes — a key can read and write every organization entity and read every transaction, within your own organization only.
Rate limits. Throttling is per organization (all your keys for an
environment share one bucket; live and test are separate). Exceeding it
returns 429. Defaults are generous; contact your provider if you need more.
Record id. Every entity carries an id. (Note: a small number of legacy
records may omit id; current records always include it.)
Webhooks. Register an endpoint in the console (Settings ▸ API
Integration) to receive real-time, HMAC-signed events
(withdrawal.created, return.created, exchange.created,
training_record.created). Each delivery is a POST whose
body matches the WebhookEvent schema. Verify the
X-SmartEPI-Signature: t=<unix>,v1=<hmac-sha256-hex> header by computing
HMAC-SHA256(secret, "<t>.<rawBody>") and comparing in constant time;
reject deliveries whose t is outside a ±300s window (replay protection).
Each delivery also carries X-SmartEPI-Event-Type (the event type, e.g.
withdrawal.created) and X-SmartEPI-Event-Id (a stable idempotency key).
When subscribing an endpoint you may register for specific event types or
* (all types); * is only a subscription selector and never appears as a
delivered event's type. Endpoints auto-disable after 100 consecutive
failures.
Authentication
- HTTP: Bearer Auth
Security Scheme Type: | http |
|---|---|
HTTP Authorization Scheme: | bearer |
Bearer format: | sk_live_… / sk_test_… |