Skip to main content

Modules & REST API

This section documents the REST API each vertical exposes. Every operation has its own page with a description, its inputs and outputs, and the sequence diagrams for both topologies (microservices and monolith). The diagrams and payloads are adapted from the platform's sequence material and verified against the controllers in the *-domain modules.

For the structural picture behind these APIs — the topology split, the data model, the cache, i18n, extensibility and audit — see the Architecture section.

Verticals​

VerticalScopeBase path
coreUsers (JIT provisioning, mTLS certificate), OTP / operation authorizations, audit/api/core
engagementCivic questions & answers, security alerts/api/engagement
leisureCity places & routes, public spaces & reservations, events & tickets/api/leisure
mobilityCars, street reservations, sanctions/api/mobility
Migration status

The core vertical is documented. engagement, leisure and mobility are being migrated from documentation/seed-data/back-end/sequence/ next.

Conventions common to every operation​

These apply to all endpoints unless a page says otherwise, so the per-operation pages don't repeat them.

Entry edge and identity​

The client always sends the Auth0 access token as a Bearer JWT. The token is validated at the entry edge, which injects the caller's sub as the X-Auth-Sub header before the request reaches the controller:

  • Microservices — the Gateway (the single OAuth2 Resource Server) validates the JWT (RS256 via JWKS) and routes /api/{vertical}/** by Eureka.
  • Monolith — an in-process security filter (MonolithSecurityConfig + XAuthSubFilterServlet) validates the JWT; MonolithRoutingConfig keeps the /api/<vertical> prefixes.

Controllers declare relative paths (e.g. @RequestMapping("/users")); the /api/<vertical> prefix is applied by the routing layer. See Dual topology.

Role verification​

Endpoints annotated with @ModelCityAccess.* (e.g. @ModelCityAccess.PlatformAdmin) are guarded by the ModelCityAccessAspect @Before advice, which resolves the caller's role through CoreClient before the method body runs. If the role is not allowed it returns 403. The resolution chain differs by topology (HTTP to core in microservices, in-process in the monolith) but the outcome is identical; the diagrams show it as a single ModelCityAccessAspect → CoreClient interaction.

Internationalization​

Localizable reads resolve to the request's Accept-Language (es/en/fr, default es, per-field fallback to es) and echo Content-Language. Writes take translatable fields as language → text maps with es required. See Internationalization.

Pagination​

List endpoints return the standard Spring Data Page envelope (serialized via PageJacksonModule), 20 items per page, with a 0-based page query parameter.

Error format​

Errors use the shared ApiErrorResponse body (the Stripe webhooks are the only exception — they return literal JSON by contract with Stripe):

{
"timestamp": "2026-06-17T10:30:00Z",
"status": 404,
"error": "Not Found",
"path": "/users",
"message": "Neighbourhood not found: el-recreo-norte"
}

Caching and audit as diagram notes​

Caching (Valkey) and audit trails appear in the diagrams as notes (e.g. "served from cache", "invalidates cache …", "audit → <vertical>_trails"). The cache is a no-op when modelcity.cache.enabled=false. See Cache and Audit trails.