API Getting Started
The canonical OpenAPI contract is served by the API at /v1/openapi.yaml, and Swagger UI is rendered at /v1/docs.
Environments
| Stage | API base URL | OpenAPI | Swagger UI |
|---|---|---|---|
| Local | http://localhost:3000/v1 | http://localhost:3000/v1/openapi.yaml | http://localhost:3000/v1/docs |
| Production | https://api.roundworld.sy/v1 | https://api.roundworld.sy/v1/openapi.yaml | https://api.roundworld.sy/v1/docs |
Portal: https://roundworld.sy · Admin: https://admin.roundworld.sy · Docs: https://docs.roundworld.sy
Authentication flow
The login body accepts identifier or email (mobile sends identifier).
LOGIN=$(curl -sS https://api.roundworld.sy/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"identifier":"owner@example.com","password":"Passw0rd!"}')
ACCESS_TOKEN=$(printf '%s' "$LOGIN" | jq -r .access_token)Send the token on protected requests:
curl -sS https://api.roundworld.sy/v1/me/ \
-H "Authorization: Bearer $ACCESS_TOKEN"Access tokens are short-lived JWTs. Use refresh tokens for long sessions. Business-scoped routes require an active membership; permissions are enforced in middleware as <module>.<action>.
SDKs
TypeScript, Dart, and PHP SDK packages are generated from the OpenAPI spec.
pnpm sdk:generateInstall examples after publication:
pnpm add @tadbeer/sdk
dart pub add tadbeer_sdk
composer require tadbeer/sdkDraft vs posting
CRUD endpoints create and edit drafts. State transitions (issue invoice, post payment, dispatch transfer, void) use dedicated posting actions. Posted rows are not deleted — cancellations insert reversing journals and stock movements.
Error shape
Errors return a JSON object with an error string and the appropriate HTTP status code.
{ "error": "permission denied" }