API Principles & Versioning
Definition of how all MASARUK APIs must be designed and documented
1. Purpose
This document defines how all MASARUK APIs must be designed and documented, across:
- B2C Web (Next.js)
- Mobile Apps (Flutter – Android & iOS)
- Admin Panel (SPA)
- Provider Portal (B2B)
- Internal services and future integrations
It is the single source of truth for:
- Base URL structure & versioning
- REST conventions
- Request / response shapes
- Error contracts
- Pagination / filtering patterns
- Authentication & authorization expectations
- Localization & currency rules
- Deprecation and change-management
Any new API must comply with this file + module-specific specs.
2. Scope
Covered in this document:
- Public & private REST APIs exposed by the Node.js backend
- Used by: B2C Web (SSR/CSR via Next.js), Mobile (Flutter), Admin Panel & Provider Portal frontends
- External machine clients (if allowed by RBAC/API keys in future)
Not covered:
- Direct DB access rules (see 07-architecture/data-architecture-postgresql.md)
- Frontend-specific client wrappers (see respective architecture docs)
- Non-HTTP integrations (queues, cron, internal CLI tools)
3. Base URL & Environments
3.1 Protocol & General Rules
- HTTPS is mandatory for all environments.
- HTTP (unencrypted) must either: Redirect (301/308) to HTTPS in public environments, or be disabled entirely.
3.2 Environment Segregation
Indicative structure (actual hostnames decided at deployment time):
| Environment | URL |
|---|---|
| Production | https://api.masaruk.com/ |
| Staging / UAT | https://api-staging.masaruk.com/ |
| Development / Internal | https://api-dev.masaruk.com/ |
3.3 Versioned Base Path
Every endpoint must be prefixed with an explicit version:
No unversioned endpoints are allowed for business-critical resources. Future versions: v2, v3, … following parallel structure.
4. Versioning Strategy
4.1 Guiding Principles
Backwards compatible changes (additive) do not require a new major version:
- Adding optional fields
- Adding new endpoints
- Adding new enum values with documented default behaviors
Breaking changes require a new version (e.g., /api/v2/...):
- Removing fields
- Renaming fields or endpoints
- Changing response structure in a non-additive way
- Changing semantics of existing behavior
4.2 Deprecation Policy (High Level)
For each breaking change: Keep old version (e.g., v1) alive for a deprecation window (suggested: 6–12 months). Document change summary in changelog and future-expansion-and-roadmap.md.
Clients (Web / Mobile / Provider) should: Target specific versions in their clients, avoid relying on undocumented behaviors.
5. REST Resource Design
5.1 Resource Naming
Pluralized, lower-kebab or lower-snake in URLs, with plural nouns:
Resource names must match domain entities defined in 03-domain-model/domain-entities-and-relationships.md.
5.2 HTTP Methods Semantics
Standard REST mapping:
| Method | Usage |
|---|---|
| GET /resource | List or fetch collection |
| GET /resource/{id} | Fetch single item |
| POST /resource | Create new resource |
| PUT /resource/{id} | Full update (idempotent) – overwrite |
| PATCH /resource/{id} | Partial update (if needed) |
| DELETE /resource/{id} | Soft-delete or mark as inactive |
Non-CRUD actions (e.g., confirm booking, cancel booking, launch campaign) should be exposed as sub-resources or action endpoints:
6. Request & Response Format
6.1 Content Types
All API requests and responses must use:
File upload endpoints (images, attachments) may use multipart/form-data and must be documented explicitly per endpoint.
6.2 Encoding & Locales
- Encoding: UTF-8 only.
- Arabic labels / values (e.g., status labels like "ملغاه") are allowed in response fields intended for UI display (e.g., ui_label_ar).
- System-level enums stay in English (UPPER_SNAKE), see 00-guidelines/naming-conventions.md.
6.3 Field Naming
JSON fields: snake_case:
No camelCase or mixed styles.
6.4 Envelope Pattern
Single resource:
{
"data": {
"...": "..."
}
}Collection:
{
"data": [
{ "...": "..." },
{ "...": "..." }
],
"meta": {
"total": 120,
"per_page": 20,
"current_page": 1,
"last_page": 6
}
}7. Pagination, Filtering & Sorting
7.1 Pagination
- page: 1-based index.
- per_page: between 10 and 100 by default (configurable per module).
{
"meta": {
"total": 120,
"per_page": 20,
"current_page": 1,
"last_page": 6
}
}7.2 Filtering
Query parameters used for filtering must be explicit and documented in each module's API file.
All date filters use ISO 8601 (YYYY-MM-DD or full timestamp where needed).
7.3 Sorting
- field for ascending
- -field for descending
Allowed sort fields must be explicitly whitelisted per endpoint.
9. Error Handling & Error Contract
9.1 General Rules
- No HTML error pages from API.
- Errors must always return JSON body with standard structure.
9.2 Error Envelope
{
"error": {
"code": "VALIDATION_ERROR",
"message": "One or more fields are invalid.",
"details": {
"email": ["The email field is required."],
"trip_id": ["Selected trip is not available for booking."]
}
}
}- code – machine-friendly error code (UPPER_SNAKE).
- message – human-readable message (English, potentially localized later).
- details – optional object with field-level errors.
9.3 Common HTTP Status Codes
10. Idempotency & Concurrency
10.1 Idempotent Operations
GET, PUT, DELETE must be idempotent. POST may create new resources on each call; for operations that must not be duplicated (e.g., payment capture), we should support client-provided Idempotency-Key header:
10.2 Concurrency Rules
Where capacity-based resources exist (e.g., trip seats): APIs should check remaining capacity at booking time. Fail with 409 CONFLICT and a consistent error code (e.g., TRIP_CAPACITY_REACHED) when sold out.
11. Localization & Currency
11.1 Languages
Primary UI language: Arabic. Secondary: English (for future internationalization).
- All system enums and internal attributes remain in English.
- Arabic labels (as seen in UI, e.g., "ملغاه", "مكتملة") appear only in dedicated fields.
{
"status": "CANCELLED",
"status_label_ar": "ملغاه",
"status_label_en": "Cancelled"
}Language negotiation: Clients may send Accept-Language: ar. Default: ar if header missing or unsupported.
11.2 Currency & Tax
System currency: SAR (Saudi Riyal).
{
"currency": "SAR",
"amount": 24560.0
}- Default VAT: 15%.
- Any deviations (e.g., 20% shown in Ad Campaigns UI) are documented as discrepancies.
12. Security & Rate Limiting
12.1 Security Principles
- All APIs must run only under HTTPS.
- Never expose sensitive data (full card numbers, CVV) in logs.
- Avoid placing sensitive information in query strings.
- Payment-related endpoints must follow integration-specific rules.
12.2 Rate Limiting (High-Level)
API should define per-role rate limits:
- End users (B2C mobile/web): generous but bounded rate.
- Admin / Provider: higher limits where needed.
- Machine-to-machine (if introduced later): controlled via API keys.
When a limit is hit: Return 429 Too Many Requests.
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1700000000
13. Logging & Observability (API Perspective)
Each request should be logged with at least:
- Timestamp
- Path & method
- Status code
- Authenticated user id (if present)
- Provider id (when applicable)
- Correlation / trace id (if used)
14. API Lifecycle & Documentation
Each module's detailed endpoints are maintained in:
This file defines global rules. If any module documentation diverges, it must either be adjusted to follow this file, or explicitly mark deviations and their rationale.