Skip to main content
Version: 1.0.0

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

Security Scheme Type:

http

HTTP Authorization Scheme:

bearer

Bearer format:

sk_live_… / sk_test_…