General
General Endpointsβ
General endpoints of the Ambrosia POS system that provide basic information and configuration.
Root Endpointβ
GET /β
API root endpoint.
Authorization: No authentication required.
cURL Example:
curl -X GET "http://127.0.0.1:9154/"
Response Body (200 OK):
"Root path of the API Nothing to see here"
Healthβ
GET /api/healthβ
Verifies that the server is running.
Authorization: No authentication required.
cURL Example:
curl -X GET "http://127.0.0.1:9154/api/health"
Response Body (200 OK):
{
"status": "healthy",
"timestamp": "1712150400000"
}
Initial Setupβ
These endpoints handle the first-time setup process. They are only relevant on first boot.
GET /initial-setupβ
Checks whether the system has already been initialized.
Authorization: No authentication required.
cURL Example:
curl -X GET "http://127.0.0.1:9154/initial-setup"
Response Body (200 OK):
{
"initialized": false,
"needsBusinessType": false
}
POST /initial-setupβ
Runs the initial setup β creates the admin role, the first user, and stores the business data. If the system is already initialized but the business type still needs to be confirmed, this endpoint also resolves that.
Authorization: No authentication required.
Request Body (first-time setup):
{
"businessType": "restaurant",
"businessName": "My Business",
"businessCurrency": "USD",
"userName": "admin",
"userPassword": "S3cur3P4ssw0rd!!",
"userPin": "1234",
"businessAddress": "string (optional)",
"businessPhone": "string (optional)",
"businessEmail": "string (optional)",
"businessTaxId": "string (optional)",
"businessRFC": "string (optional, alias of businessTaxId)",
"businessLogoUrl": "string (optional)",
"businessLogo": "string (optional, alias of businessLogoUrl)"
}
Request Body (confirm business type only):
{
"businessType": "store"
}
cURL Example:
curl -X POST "http://127.0.0.1:9154/initial-setup" \
-H "Content-Type: application/json" \
-d '{
"businessType": "restaurant",
"businessName": "My Restaurant",
"businessCurrency": "USD",
"userName": "admin",
"userPassword": "S3cur3P4ssw0rd!!",
"userPin": "1234"
}'
Response Body (201 Created):
{
"message": "Initial setup completed",
"userId": "f9b9d411-590f-4d10-a164-0173805857de",
"roleId": "70d96869-b363-4b5f-a972-897afd30a68c"
}
userId and roleId are UUIDs (strings), not integers.
Response Body (400 Bad Request): missing data or invalid business type.
{ "message": "Invalid business type" }
Response Body (404 Not Found): unknown currency acronym.
{ "message": "Unknown currency acronym: XYZ" }
Response Body (409 Conflict): system already initialized.
{ "message": "Initial setup already completed" }
HTTP Status Codesβ
Success (2xx)β
- 200 OK: Successful operation. Empty lists also return
200with a descriptive string (e.g."No orders found"). - 201 Created: Resource created successfully.
- 202 Accepted: Accepted but not yet completed (e.g.
POST /store/orders/checkout-if-paidwith an unconfirmed Lightning payment β{ "status": "pending" }). - 204 No Content: No body. Used by successful
DELETEs (exceptDELETE /store/orders/{id}) and byGET /shifts/openwhen there is no open shift.
Client Error (4xx)β
- 400 Bad Request: Missing or invalid parameters.
- 401 Unauthorized: Not authenticated or invalid token.
- 403 Forbidden: Insufficient permissions (
Permission required,Admin privileges required,Wallet access required). - 404 Not Found: Resource not found.
- 409 Conflict: State conflict β duplicate SKU, duplicate username/role name, an already-open shift, deleting the last admin, etc.
- 429 Too Many Requests: Login attempt limit. Includes the
Retry-Afterheader and{ "retryAfter": <seconds> }.
Server Error (5xx)β
- 500 Internal Server Error: Internal server error.
- 503 Service Unavailable: External service unavailable (Phoenix node or printing).
Data Formatβ
Timestampsβ
- Timestamps are usually Unix in milliseconds (e.g.
1753549837824), sent/received as a string or number depending on the field. Some dates use ISO 8601 (2025-01-15T14:30:00Z).
Identifiersβ
- Type: UUID v4.
- Example:
76ee1086-b945-4170-b2e6-9fbeb95ae0be.
Currencies and Amountsβ
- Restaurant-module amounts are expressed as decimals (e.g.
45.50). - Store-module amounts (products, checkout, reports) are expressed as integers in cents (e.g.
25000= $250.00). - Lightning amounts in satoshis.
Authenticationβ
- Type: JWT in HTTP cookies.
- accessToken (
auth-jwt): standard API operations. Lifetime ~1 minute. - refreshToken: renews the access token. Lifetime 30 days.
- walletAccessToken (
auth-jwt-wallet): required by most/wallet/*endpoints. Obtained fromPOST /wallet/auth. - Endpoints:
POST /auth/login,POST /auth/refresh,POST /auth/logout.
Paginationβ
Some endpoints (e.g. /wallet/payments/*) support pagination:
- limit (int): maximum results (default: 20).
- offset (int): results to skip (default: 0).
- all (boolean): return all with no pagination.
curl -X GET "http://127.0.0.1:9154/wallet/payments/incoming?limit=10&offset=20" \
-H "Cookie: accessToken=$ACCESS_TOKEN" \
-H "Cookie: walletAccessToken=$WALLET_ACCESS_TOKEN"
/wallet/payments/incoming requires walletAccessToken in addition to accessToken.
Common Filtersβ
Most filter query params use camelCase (userId, paymentMethod, minTotal, startDate, endDate, sortBy, sortOrder).
snake_case exceptions (because of how the server reads them):
user_idinGET /shifts/open.start_date/end_dateinGET /orders/date-range.- The
total_saleskey in theGET /orders/total-sales/{date}response.
Wallet endpoints use from / to (timestamps) for date filtering.
Error Handlingβ
Errors handled by the central handler return an object:
{ "message": "Error description" }
Exceptions:
- Some route-level validations respond with a plain string (e.g.
"Missing or malformed ID","There is already an open shift"). - Phoenix errors return a
WalletErrorResponse:{ "message": "...", "code": <int?>, "source": "..." }.
Environmentsβ
- Development: base URL
http://127.0.0.1:9154, local SQLite. - Production: URL per deployment, HTTPS required.
Custom Data Typesβ
Table Statusesβ
available,occupied,reserved.
Order Statusesβ
open,closed,paid(valid values of an order'sstatusfield).
Dish (preparation) Statusesβ
- An
OrderDish'sstatusreflects the kitchen flow (e.g.pending); each dish also includesshouldPrepare.
Ticket Statusesβ
1Pending,2Paid,3Cancelled.
Bitcoin Lightning Integrationβ
The system integrates with the Bitcoin Lightning Network through the Phoenix service: create invoices, process payments, query balance/transactions, and on-chain payments. See Wallet.
Securityβ
- PIN: stored with PBKDF2WithHmacSHA256 (10,000 iterations, 256-bit key), using the app master key + the username as salt (
SecurePinProcessor.hashPinForStorage()). - JWT: signed with a secret key.
- HttpOnly cookies: to mitigate XSS.
- Production: HTTPS required, valid SSL certificates, regular backups, and monitoring.