Skip to main content
This domain covers everything needed to establish and maintain a session with the Genuka API. It includes user registration (with company creation), email/password login, PIN-based login, password reset via OTP, email verification, and multi-company management. After a successful login or registration, the server returns a Passport accessToken (plain-text bearer token) and the resolved companyId that must be sent as the X-Company header on all subsequent requests. Base URL https://api.genuka.com · Auth Authorization: Bearer <token> + X-Company: <companyId> · See Getting Started for shared conventions, pagination & error formats.

Endpoints at a glance


Authentication

GET /2023-11/auth/login

Redirects the browser to the configured frontend login page. This is a convenience redirect for web flows and does not return JSON. Clients integrating the API directly should use POST /2023-11/auth/login.

POST /2023-11/auth/login

Authenticate a user with their email and password. Returns a Passport bearer token and basic company context.
  • Query parameters: none
  • Request body:
Request example
Success response — 200 OK
The companies array is only present when the user belongs to more than one company.
Error responses
  • 401 Unauthorized — invalid email/password combination

GET /2023-11/auth/register

Redirects the browser to the configured frontend registration page. Not a JSON API endpoint.

POST /2023-11/auth/register

Register a new company and its first admin user in a single request. Creates the company, creates the user (role admin), queues a welcome notification, creates a trial subscription, and returns a bearer token.
  • Request body:
Request example
Success response — 200 OK Same shape as POST /2023-11/auth/login:
Error responses
  • 400 Bad Request — missing company or user payload, or missing currency_code
  • 409 (surfaced as a BusinessException) — email already registered; returns the list of companies the existing user belongs to

POST /2023-11/auth/register-additional-company

Add a new company to an existing authenticated user. The user must already have a valid token. Creates the company, attaches the user as admin, creates a trial subscription, and issues a new token scoped to the new company. Rate-limited to 5 requests per minute.
  • Request body:
The user object (if sent) is silently ignored — the company is attached to the currently authenticated user.
Request example
Success response — 200 OK
Use the returned accessToken and companyId for all subsequent requests scoped to the new company.
Error responses
  • 400 Bad Request — missing company payload or currency_code
  • 401 Unauthorized — no valid token provided

POST /2023-11/auth/login-with-pin

Authenticate using a company short code and numeric PIN. Tokens issued by this endpoint expire after 24 hours. Intended for point-of-sale and kiosk flows.
  • Request body:
Request example
Success response — 200 OK
The token.expires_at is set to 24 hours after issuance. The companies array is included when the PIN user belongs to more than one company.
Error responses
  • 401 Unauthorized — invalid company code or PIN
  • 422 Unprocessable Entitycompany_code does not exist in the database

POST /2023-11/auth/verify-company-code

First step of the PIN login flow. Validates a company short code and returns basic company information to display on the PIN entry screen. Rate-limited to 5 requests per minute.
  • Request body:
Request example
Success response — 200 OK
Error responses
  • 422 Unprocessable Entitycompany_code does not exist

POST /2023-11/auth/logout

Revokes the current access token and its refresh token. Requires a valid bearer token.
  • Request body: none
Request example
Success response — 200 OK
Error responses
  • 401 Unauthorized — token is missing or already revoked

POST /2023-11/auth/password/email

Sends a 6-digit OTP to the user’s email address to initiate the password reset flow.
  • Request body:
Request example
Success response — 200 OK
Error responses
  • 404 Not Found — no user with the given email
  • 500 Internal Server Error — mail delivery failure

POST /2023-11/auth/password/reset

Resets the user’s password using the OTP received by email. The OTP is single-use and expires after a fixed window.
  • Request body:
Request example
Success response — 200 OK
Error responses
  • 400 Bad Request — OTP is invalid or expired
  • 404 Not Found — no user with the given email
  • 422 Unprocessable Entity — validation failure (e.g. passwords do not match, OTP not exactly 6 chars)

Email Verification

These endpoints require a valid bearer token (middleware auth:apikey,app,admin,developer).

POST /2023-11/auth/email/send-verification

Dispatches a new 6-digit OTP to the authenticated user’s email address. The job is queued and fires after the HTTP response is sent. Rate-limited to 3 requests per minute.
  • Request body: none
Request example
Success response — 200 OK
Error responses
  • 401 Unauthorized — no valid token
  • 422 Unprocessable Entity — email is already verified
  • 500 Internal Server Error — failed to dispatch notification

POST /2023-11/auth/email/verify

Verifies the authenticated user’s email address using the OTP. The OTP is marked as used after a successful verification.
  • Request body:
Request example
Success response — 200 OK
Error responses
  • 401 Unauthorized — no valid token
  • 422 Unprocessable Entity — email already verified, or OTP is invalid/expired

User Profile

GET /2023-11/user

Returns the full profile of the authenticated user, including their active company, subscription status, permissions, and (if applicable) a list of all companies they belong to.
  • Query parameters:
Request example
Success response — 200 OK
companies is only present when has_multiple_companies is true. subscription may be null if no active subscription exists.
Error responses
  • 401 Unauthorized — missing or revoked token

GET /2023-11/user/companies

Returns the list of all companies the authenticated user belongs to, ordered by most recently used. Request example
Success response — 200 OK
Error responses
  • 401 Unauthorized — missing or revoked token

PUT /2023-11/user/metadata

Merges the supplied key/value pairs into the authenticated user’s metadata JSON column. Existing keys not in the request body are preserved. Keys named metadata or anonymous in the request body are ignored.
  • Request body: Any flat JSON object. All top-level keys (except metadata and anonymous) are merged into the stored metadata.
Request example
Success response — 200 OK Returns a UserResource object (same shape as a user in a list response — see GET /2023-11/user for the company-context variant):
Error responses
  • 401 Unauthorized — missing or revoked token

POST /2023-11/user/set-pin

Sets or replaces the authenticated user’s 4-digit numeric PIN. The PIN is stored hashed and enables PIN-based login via POST /2023-11/auth/login-with-pin.
  • Request body:
Request example
Success response — 200 OK
Error responses
  • 401 Unauthorized — missing or revoked token
  • 422 Unprocessable Entity — PIN is not exactly 4 digits, contains non-numeric characters, or confirmation does not match

POST /2023-11/user/switch-company

Switches the authenticated user’s active company. Resolves effective permissions for the new company (role defaults merged with per-user overrides), syncs Spatie permissions, updates last_used_at on the pivot, revokes all existing tokens, and issues a new token scoped to the target company’s permissions.
  • Request body:
Request example
Success response — 200 OK
Replace the Authorization header with the new accessToken and update X-Company to the new companyId for all subsequent requests.
Error responses
  • 401 Unauthorized — missing or revoked token
  • 403 Forbidden — the user does not belong to the requested company
  • 422 Unprocessable Entitycompany_id missing

POST /2023-11/user/refresh-token

Re-issues the user’s token with the current permissions stored in the database, without requiring a full re-login. Useful when server-side permissions or the subscription plan have changed. All existing tokens are revoked and replaced.
  • Request body: none
Request example
Success response — 200 OK
Error responses
  • 401 Unauthorized — missing or revoked token

Invitations

Invitation endpoints are public — they do not require Authorization or X-Company headers. The invitation token is a 64-character random string delivered via email. Invitations expire 7 days after being issued.

GET /2023-11/invitations

Retrieve invitation details to display on the acceptance screen. Validates the token and checks expiry before returning.
  • Query parameters:
Request example
Success response — 200 OK
Error responses
  • 404 Not Found — token not found or invitation already accepted/declined
  • 410 Gone — invitation is more than 7 days old
  • 422 Unprocessable Entitytoken query parameter is missing

POST /2023-11/invitations/accept

Accept a pending company invitation. Updates the pivot status to accepted, records accepted_at, attaches any pre-granted shops to the user, and clears the invitation token.
  • Request body:
Request example
Success response — 200 OK
Error responses
  • 404 Not Found — token not found or invitation is not in pending status
  • 410 Gone — invitation has expired (older than 7 days)
  • 422 Unprocessable Entitytoken field missing

POST /2023-11/invitations/decline

Decline a pending company invitation. The pivot row is deleted permanently.
  • Request body:
Request example
Success response — 200 OK
Error responses
  • 404 Not Found — token not found or invitation is not in pending status
  • 422 Unprocessable Entitytoken field missing