API Reference

API Overview

The Possfer API is a RESTful JSON API that follows standard HTTP conventions. All requests and responses use JSON, and every mutation is append-only to satisfy GoBD compliance.

Base URL & Versioning

All API requests are made to the following base URL. The API is currently unversioned; breaking changes will be communicated with at least 90 days notice.

text
https://api.possfer.com

Authentication

The API uses JWT Bearer tokens for authentication. Obtain a token by calling the login endpoint with valid credentials. Tokens expire after 24 hours.

bash
curl https://api.possfer.com/categories \
  -H "Authorization: Bearer <your-jwt-token>"

Request & Response Format

All request bodies must be sent as JSON with the Content-Type: application/json header. All responses are JSON.

ConventionFormatExample
PricesInteger (cents)1250 = 12,50 EUR
IDsUUID v4550e8400-e29b-41d4-a716-446655440000
TimestampsISO 8601 UTC2026-03-20T14:30:00Z
Nullable fieldsExplicit null"deleted_at": null

Roles & Permissions

Every user is assigned one of four roles. Endpoints enforce role-based access control; attempting an action above your role returns 403 Forbidden.

NameTypeRequiredDescription
adminroleOptionalFull access. Manage restaurant settings, users, fiscal exports, and all operational data.
managerroleOptionalOperational access. Manage menus, tables, view reports, and handle voids/refunds.
waiterroleOptionalFloor access. Create and update orders, process payments, manage own tables.
kitchenroleOptionalKitchen display access. View incoming orders and update item preparation status.

Rate Limiting

To ensure fair usage, the API enforces rate limits on all endpoints. Exceeding the limit returns 429 Too Many Requests with a Retry-After header.

ScopeLimit
Global (all endpoints)100 requests / minute
Auth endpoints10 requests / minute

Error Handling

When an error occurs, the API returns an appropriate HTTP status code along with a JSON body containing a human-readable error message.

json
{
  __PH0__: "menu item not found"
}

HTTP Status Codes

CodeMeaning
200 OKRequest succeeded.
201 CreatedResource created successfully.
204 No ContentDeletion or update succeeded with no body.
400 Bad RequestInvalid JSON or missing required fields.
401 UnauthorizedMissing or expired authentication token.
403 ForbiddenValid token but insufficient role permissions.
404 Not FoundResource does not exist or has been soft-deleted.
409 ConflictDuplicate resource or state conflict.
422 Unprocessable EntityValidation error on input data.
429 Too Many RequestsRate limit exceeded. Check Retry-After header.
500 Internal Server ErrorUnexpected server error. Contact support.

Soft Deletes (GoBD Compliance)

German fiscal regulations (GoBD) require that financial records are never physically deleted. All DELETE operations in Possfer are soft deletes — the record's deleted_at timestamp is set and the record is excluded from standard list queries.

json
{
  __PH0__: "550e8400-e29b-41d4-a716-446655440000",
  __PH2__: "Wiener Schnitzel",
  __PH4__: 1890,
  __PH5__: "2026-03-20T09:15:00Z"
}

Example: List Menu Items

GET/menu-itemsProtected

Returns all active menu items for the authenticated restaurant.

Query Parameters

NameTypeRequiredDescription
category_iduuidOptionalFilter by category.
include_deletedbooleanOptionalInclude soft-deleted items. Requires admin role. Default: false.

Response

json
[
  {
    __PH0__: "550e8400-e29b-41d4-a716-446655440000",
    __PH2__: "Wiener Schnitzel",
    __PH4__: 1890,
    __PH5__: 19,
    __PH6__: "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    __PH8__: "2026-01-15T08:00:00Z",
    __PH10__: "2026-03-10T12:30:00Z",
    __PH12__: null
  }
]

Nullable Fields

Fields that may not have a value are represented as null in JSON responses, never as empty strings or omitted keys. Common nullable fields include deleted_at, description, and image_url.