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.
https://api.possfer.comAuthentication
The API uses JWT Bearer tokens for authentication. Obtain a token by calling the login endpoint with valid credentials. Tokens expire after 24 hours.
curl https://api.possfer.com/categories \
-H "Authorization: Bearer <your-jwt-token>"Token expiry
401 Unauthorized. Re-authenticate to obtain a fresh token.Request & Response Format
All request bodies must be sent as JSON with the Content-Type: application/json header. All responses are JSON.
| Convention | Format | Example |
|---|---|---|
| Prices | Integer (cents) | 1250 = 12,50 EUR |
| IDs | UUID v4 | 550e8400-e29b-41d4-a716-446655440000 |
| Timestamps | ISO 8601 UTC | 2026-03-20T14:30:00Z |
| Nullable fields | Explicit 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.
| Name | Type | Required | Description |
|---|---|---|---|
admin | role | Optional | Full access. Manage restaurant settings, users, fiscal exports, and all operational data. |
manager | role | Optional | Operational access. Manage menus, tables, view reports, and handle voids/refunds. |
waiter | role | Optional | Floor access. Create and update orders, process payments, manage own tables. |
kitchen | role | Optional | Kitchen 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.
| Scope | Limit |
|---|---|
| Global (all endpoints) | 100 requests / minute |
| Auth endpoints | 10 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.
{
__PH0__: "menu item not found"
}HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 OK | Request succeeded. |
| 201 Created | Resource created successfully. |
| 204 No Content | Deletion or update succeeded with no body. |
| 400 Bad Request | Invalid JSON or missing required fields. |
| 401 Unauthorized | Missing or expired authentication token. |
| 403 Forbidden | Valid token but insufficient role permissions. |
| 404 Not Found | Resource does not exist or has been soft-deleted. |
| 409 Conflict | Duplicate resource or state conflict. |
| 422 Unprocessable Entity | Validation error on input data. |
| 429 Too Many Requests | Rate limit exceeded. Check Retry-After header. |
| 500 Internal Server Error | Unexpected 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.
{
__PH0__: "550e8400-e29b-41d4-a716-446655440000",
__PH2__: "Wiener Schnitzel",
__PH4__: 1890,
__PH5__: "2026-03-20T09:15:00Z"
}Audit trail
?include_deleted=true query parameter and are included in DSFinV-K exports for tax audit purposes.Example: List Menu Items
/menu-itemsProtectedReturns all active menu items for the authenticated restaurant.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
category_id | uuid | Optional | Filter by category. |
include_deleted | boolean | Optional | Include soft-deleted items. Requires admin role. Default: false. |
Response
[
{
__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.