Authenticate API requests
Every request to the e-bon API must carry one of two credentials: an API key (for server-to-server integrations and POS partners) or a Portal access token (for users signed in to the e-bon Portal or the on-device app). This page shows you how to obtain each one, how to send it, and what to do when authentication fails.
Choose your authentication method
| You are… | Use this credential | Sent as |
|---|---|---|
| A POS partner or back-office integration | API key | x-api-key: <key> header or Authorization: Bearer <key> |
| A user signed in to the Portal or on-device app | Portal access token (JWT) | Authorization: Bearer <token> |
The two credentials are not interchangeable. API keys are bound to an organization and have scopes. Portal tokens are bound to a user inside an organization and have a role.
Authenticate with an API key
API keys are the recommended way to call the e-bon API from any server, POS terminal or back-office system. A key looks like this:
ebon_live_{orgId}_{32-hex}
The full key is shown to you only once, in the modal where you create it. Store it in a secure secrets store immediately — e-bon never displays the full secret again. The Portal will only show you the prefix (everything before the random tail) so you can identify the key later.
Send your first authenticated request
Create an API key in the Portal
Sign in to the Portal, open Settings → API keys, click Create API key, give it a label, pick the scopes it needs, and copy the key from the confirmation modal.
Add the key to your request
Send the key in the x-api-key header (preferred) or in Authorization: Bearer …:
POST /api/v1/receipts HTTP/1.1
Host: api.e-bon.ro
Content-Type: application/json
x-api-key: ebon_live_abc123def456_0123456789abcdef0123456789abcdef
{ "deviceId": "dev_…", "items": [ … ] }
Or, equivalently:
Authorization: Bearer ebon_live_abc123def456_0123456789abcdef0123456789abcdef
Handle the response
On success you get the resource back. On authentication failure you get a 401 or 403 JSON envelope — see Handle authentication errors below.
Revoke or rotate a key
API keys never expire on their own. To stop a key from working, open the Portal, find the key by its prefix and click Revoke. The next request that uses it returns 401 UNAUTHORIZED — API key is inactive. immediately.
There is no in-place rotation. To rotate a key, create a new one, update your secrets store, then revoke the old one once your deployment has rolled out.
Sign in to the Portal
Portal users sign in with email and password and receive a pair of tokens:
- An access token valid for 15 minutes, sent on every API call as
Authorization: Bearer <token>. - A refresh token valid for 7 days, used only to mint a new access token.
Complete the sign-in flow
Sign in
POST /api/v1/auth/login
Content-Type: application/json
{ "email": "you@example.com", "password": "…" }
The response contains accessToken, refreshToken and the user profile.
Call protected endpoints
Send the access token on every request:
GET /api/v1/devices
Authorization: Bearer <accessToken>
Refresh before expiry
When the access token expires (or earlier — anytime within the 7-day refresh window), exchange the refresh token for a fresh pair:
POST /api/v1/auth/refresh
Content-Type: application/json
{ "refreshToken": "<refreshToken>" }
The previous refresh token is invalidated immediately. Replace both stored tokens with the new pair returned in the response.
Sign out
POST /api/v1/auth/logout
Authorization: Bearer <accessToken>
Content-Type: application/json
{ "refreshToken": "<refreshToken>" }
This revokes only the supplied refresh token. Sessions on other devices remain active.
401 — Refresh token has been revoked. The user must sign in again.For full request and response shapes, see the Auth API reference.
Manage API key scopes
Every API key carries one or more scopes. Each request requires a specific scope; if the key is missing it, the API returns 403 FORBIDDEN — Insufficient scopes.
| Scope | Use it for |
|---|---|
receipts | Create and read fiscal receipts. |
receipts:read | Read-only receipt access (reporting dashboards, exports). |
receipts:admin | Admin-grade receipt actions (void / reversal endpoints). |
reports | Generate and read X, Z, daily and monthly fiscal reports. |
devices | General devices access (list, fetch, update). |
devices:read | Read-only device listing and lookup. |
devices:write | Create, update or delete devices; assign operators; configure fiscal settings. |
commands | Issue device commands (POST /devices/:id/commands). |
all | Universal access — satisfies any scope check. |
receipts; a reporting dashboard only needs receipts:read and reports.Manage user roles
Portal users have one of three roles, set when they are added to the organization:
| Role | What they can do |
|---|---|
owner | Full Portal access. Created automatically for the user who signs the organization up. Can delete the organization. |
admin | Same Portal access as Owner, except for organization-deletion actions. |
operator | Day-to-day Portal use — view receipts, run reports, manage operators on devices. Reduced administrative surface. |
Roles are evaluated on every Portal API call. If a user tries an action their role does not permit, the API returns 403 FORBIDDEN — Insufficient role.
Understand plan limits
Some actions are gated by your subscription plan:
| Plan | Maximum devices | API keys allowed |
|---|---|---|
| Free | 2 | No |
| Pro | 10 | Yes |
| Enterprise | Unlimited | Yes |
When you hit a plan limit, the API returns 403 TIER_LIMIT_EXCEEDED with a message telling you which limit you hit and how to lift it (typically: upgrade your plan).
Handle rate limits
The API enforces three rate-limit buckets. All three return the same response on exhaustion:
{
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests, please try again later.",
"status": 429
}
Every 429 response includes a Retry-After header in seconds — wait at least that long before retrying.
| Bucket | Window | Limit | Applies to | Keyed by |
|---|---|---|---|---|
| Global | 10 min | 150 requests | Every request to the API | API-key prefix if present, else client IP |
| Sign-in | 10 min | 30 requests | POST /auth/register, /auth/login, /auth/refresh, /auth/forgot-password | Client IP |
| Device commands | 10 min | 50 requests | POST /devices/:deviceId/commands and the wrapper endpoints | API-key prefix if present, else client IP |
429 responses with respect to the Retry-After header.Handle authentication errors
Every authentication and authorization failure returns a structured JSON envelope with a stable code field. Match on code (not on the human-readable message) when building error handling.
| HTTP | code | Message | What it means |
|---|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid Authorization header. Expected: Bearer <token> | You forgot the Authorization header or sent it in the wrong format. |
| 401 | UNAUTHORIZED | Missing access token | The header is present but the token after Bearer is empty. |
| 401 | UNAUTHORIZED | Invalid or expired access token | The Portal access token is bad, expired or signed by someone else. Refresh it. |
| 401 | UNAUTHORIZED | Refresh token has been revoked | The refresh token has already been used or was revoked. Sign in again. |
| 401 | UNAUTHORIZED | Invalid or expired refresh token | The refresh token is malformed or past its 7-day window. Sign in again. |
| 401 | UNAUTHORIZED | Missing API key. Provide via x-api-key header or Authorization: Bearer <key>. | No credential at all on a protected endpoint. |
| 401 | UNAUTHORIZED | Invalid API key format. | The key does not match ebon_live_{orgId}_{32-hex}. Probably truncated or copied wrong. |
| 401 | UNAUTHORIZED | Invalid API key. | The key is shaped correctly but is not registered for this organization. |
| 401 | UNAUTHORIZED | API key is inactive. | The key was revoked from the Portal. Create a new one. |
| 401 | UNAUTHORIZED | Missing authentication. Provide an API key via x-api-key header or a JWT via Authorization: Bearer <token>. | The endpoint accepts either credential and you sent neither. |
| 403 | FORBIDDEN | Insufficient role. Required: <role> or <role> | The signed-in user does not have a role allowed for this endpoint. |
| 403 | FORBIDDEN | Insufficient scopes. Missing: <scope>, <scope> | The API key is valid but is missing the scopes this endpoint requires. |
| 403 | TIER_LIMIT_EXCEEDED | Device limit reached. Your <plan> plan allows a maximum of <N> devices (current: <K>). Upgrade your plan to add more devices. | You are at your plan's device cap. |
| 403 | TIER_LIMIT_EXCEEDED | API keys are not available on the Free plan. Upgrade to Pro to create API keys. | Free plans cannot create API keys. |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests, please try again later. | You hit a rate-limit bucket. Wait at least Retry-After seconds. |
401 responses do not distinguish a bad signature from an expired token from a malformed one — they all return Invalid or expired access token. Treat any 401 UNAUTHORIZED on a protected endpoint as "the credential is dead, get a new one" rather than as a parseable diagnostic.Where to go next
- Auth API reference — full request and response shapes for
/auth/{register,login,refresh,logout,forgot-password}. - API keys API reference — REST reference for managing keys programmatically.
- Portal: API keys — UI flow for creating, scoping and revoking keys.
- Portal: Sign up — bootstrap flow for the first Owner and the organization.
- Integration walkthrough — end-to-end sandbox loop that exercises authentication, receipts and webhooks together.
How receipt emission works
Understand how e-bon dispatches a print command to your device, when it falls back to a push wakeup, how long each stage takes, and how you receive the final result.
Email notifications
Which automatic emails e-bon sends today, what is inside the end-of-day Z-report email, how to choose who receives them, and what to do if a recipient does not get the message.