REST API mounts at /api/v1 (api/src/v1/index.ts). v2 at /api/v2 adds SCA v2 routes and re-mounts v1.
Authentication #
| Method | Path | Notes |
|---|---|---|
| POST | /api/v1/authenticate | Obtain session/JWT |
| GET | /api/v1/corp, /api/v1/corp/:corpCode | Corporation metadata |
Locations & units #
| Method | Path |
|---|---|
| GET | /api/v1/locations, /locations/:locationCode |
| GET | .../charges, unit-list, stats, marketing-sources, deals |
| GET | /api/v1/unit-list, POST /unit-list/by-type |
| GET | /api/v1/unit-types/matches |
Reservations & move-in #
| Method | Path |
|---|---|
| POST | /api/v1/reservation, /reservations, /reservation/save-quote |
| GET/PATCH | /api/v1/reservation/:id, list, by-ledger, unit-availability |
| GET/POST | /api/v1/move-in/:id, cost-retrieve, lease, payment callbacks |
SCA / payments #
| Method | Path |
|---|---|
| POST | /api/v1/sca/prepare/* — move-in, payment, reservation-fee, boxshop |
| POST/GET | /api/v1/sca/:id, notification handlers |
| POST | /api/v2/sca/notification, /standalone/return/:id |
| GET/POST | /api/v1/r6pay/*, /paypal/client-token |
Realtime payment events: After r6Pay success or failure, the API emits a paymentEvent on the Socket.IO room for the transaction (core/socketService.emitPaymentEvent). Clients join via joinRoom with roomType: 'payment'; late joins receive a stored replay. StorApp mobile and booking flows listen for this to confirm payment without polling.
SCA channel attribution: UK/SCA rent payments initiated from StorApp complete asynchronously on First Data's channel-less notification webhook. The originating sourceChannel (storapp) is persisted on scaTransaction.context.channel at creation and recovered at completion for payment.transaction.* events and failed-payment tracking — so Automate "% rent paid via app" KPIs attribute app-originated SCA payments correctly.
Email template keywords #
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/locations/email-keywords | Available merge keywords for email/PDF templates (includes unit dimension fields) |
| GET | /adminpanel/api/email-keywords | Legacy admin panel modal (tokenised admin route) |
Tenant accounts #
| Method | Path |
|---|---|
| POST/GET/PATCH | /api/v1/tenant/* — login, invoices, marketing, uploads |
| GET/POST | /api/v1/tenant/:id/payments/*, /ledgers/* |
| GET/POST/PUT/DELETE | /api/v1/users/* — portal users, access codes |
Internal / engine (JWT) #
Auth: getCorpSecureOnly middleware with engine API tokens.
| Method | Path |
|---|---|
| POST | /api/v1/internal/sitelink/rate-update |
| POST/GET/DELETE | /api/v1/internal/rev-mgmt/explorations/*, /rate-overrides, /cache/flush |
| GET | /api/v1/internal/unit-types, /unit-ids |
| GET/PUT | /api/v1/internal/settings/site — per-site settings + gating context for Automate native settings screen |
| GET/PUT | /api/v1/internal/settings/corp — corp-level adminOverview settings |
Unit-types payload (ADR-0010): Lean projection includes sitelink_unit_type_id, floor, and features[] (climate/inside/power/alarm/mobile) alongside dimensions and rates. Automate rev-mgmt uses these to render human discriminators for colliding unit_type_code siblings.
Automate integration: Automate rev-mgmt engine calls these internal endpoints and receives webhooks. See Automate docs for REV_MGMT_RAPIDSTOR_* configuration.
Tokenised customer routes #
100+ routes under /rapidstor/:corpToken/:siteToken/api/* (routes/publicTokenised.js). Still consumed by v2 frontend for tracking, wizard init, box shop coupons, etc.
MCP #
POST/GET/DELETE /api/v1/mcp — tools: enabled_locations__v1, unit_list_by_type__v1, create_reservation__v1, create_enquiry__v1. Consumed by Automate agent-runtime widget assistant.
Tool outputs are sanitized for LLM consumption: enabled_locations__v1 returns sites via convertSiteForApiReturn() (strips webhooks, payment secrets, Twilio credentials, reCAPTCHA keys; uses friendlyName for display). unit_list_by_type__v1 returns lean unit-type projections without internal admin fields.
Observability — Prometheus metrics #
GET /metrics (unauthenticated path, bearer-protected handler) exposes prom-client default metrics (prefixed rapidstor_) plus:
rapidstor_http_request_duration_seconds— histogram labeled by method, route, status_coderapidstor_http_requests_total— counter with the same labels
Auth: Authorization: Bearer <token> must match RAPIDSTOR_METRICS_TOKEN (timing-safe). Empty token → 503; missing/invalid Bearer → 401 with WWW-Authenticate. HTTP timing middleware records after the /metrics and /alive routes so scrape traffic is excluded from request logs noise.