Entrii REST APIs — OpenAPI
Versioned REST surfaces for the Entrii package: **Backoffice** (tenant data/settings), **Sales channel** (storefront-aligned catalog and orders), and **Accounting** (ledger and aggregates). **Tenant context** is bound to the OAuth access token (`tenant_id` on the Passport access token row). Clients must not send a separate tenant header for normal calls. To act on another tenant, obtain a new token (authorization must include `tenant_id` on the authorize request; see integration guide). **Money** values are integers in the smallest currency unit (e.g. øre, cents) unless an endpoint documents otherwise.
Entrii REST APIs — integration guide
This document describes how consuming applications expose the three Entrii REST surfaces with Laravel Passport and how integrators should authenticate.
Surfaces and base paths
Surface | Base path | Typical OAuth scopes |
|---|---|---|
Backoffice |
|
|
Sales channel |
|
|
Accounting |
|
|
Each group applies middleware for API JSON, Passport authentication, tenant resolution from the access token, throttling, and scope checks. Callers must send:
Authorization: Bearer <access_token>
Tenant binding (no X-Tenant-Id)
The active tenant is determined from the Passport access token (a tenant_id column on oauth_access_tokens, populated when the user authorizes with a tenant_id query parameter on /oauth/authorize). Integrators must not rely on a tenant header or tenant in the URL for routine calls.
To switch tenants, obtain a new access token after authorization for the other tenant.
Authorization request
The Entrii package ships middleware for the web stack that applies to Passport’s authorize endpoint (default path prefix oauth):
On GET
/oauth/authorize, the query must include `tenant_id` (UUID of the tenant). The authenticated user must be allowed to access that tenant (canAccessTenant). The tenant id is stored in session and written through to the issued access token (auth code + access token pipeline implemented in the package).
If the user is not yet logged in when hitting authorize, the middleware may stash a pending tenant id in session until login completes; your login flow should return the user to authorize with the same tenant_id.
Scopes
The Entrii package registers canonical scope names with Passport (Passport::tokensCan(ApiScopes::definitions())). Request only the scopes required for each integration. Route groups require at least one scope from the relevant family (e.g. backoffice:read or backoffice:write for the backoffice API).
Consumer application setup (checklist)
Add `laravel/passport` to Composer `dont-discover` so Laravel does not auto-register Passport’s default service provider (Entrii ships
EntriiPassportServiceProvider, which extends Passport and wires Entrii’s refresh-token grant). Example in your appcomposer.jsonunderextra.laravel.dont-discover:"laravel/passport".Run the Passport install steps your team uses (keys, clients, migrations).
Use the
apiauthentication guard with thepassportdriver (see Laravel docs). The packageUsermodel already usesLaravel\Passport\HasApiTokens; yourApp\Models\Usercan extendEntrii\Models\Userwithout adding the trait.Run package migrations (UUID
user_idon OAuth tables, `tenant_id` on Passport tables — seedatabase/migrations/2026_05_04_173500_alter_oauth_token_user_id_for_uuid_users.phpand2026_05_04_220000_add_tenant_id_to_oauth_tables.phpin the package).Register
ValidateOAuthAuthorizeTenanton the web middleware group so/oauth/authorizeenforcestenant_id.Merge or load Entrii
api_v1routes (package service provider) so/api/v1/...endpoints exist.
OAuth client provisioning
How clients are created (CLI only, Filament “API applications”, or a partner portal) is a product decision. Until a self-service flow exists, document for each environment:
Redirect URIs allowed for each OAuth client.
Who may create or rotate client secrets.
Use Authorization Code + PKCE for public/user agents; avoid the password grant.
For machine-only or tests, personal access tokens can be used; the same tenant_id column must be set on the token row if you bypass the authorize flow (see package tests for an example).
OpenAPI
A machine-readable contract skeleton lives next to this file: `openapi.yaml`. Extend it as endpoints are added; keep scopes, error shapes, and money as integers documented there.
Errors
401 — Missing or invalid bearer token.
403 — Token not bound to a tenant, user cannot access that tenant, insufficient scope, or policy denial.
422 — Validation (including missing
tenant_idon authorize when required).
Refer to Laravel’s JSON validation format for 422 responses on write endpoints.