Mobile + Service APIs

The only surface that doesn’t emit HTML. Three controllers covering JSON endpoints for the iOS app and a small set of service-to-service integrations (webhooks in, webhooks out).

By the freeze, the iOS app had been unpublished from the App Store for about two years, so the /api/v1/* surface mostly served whatever legacy installations were still running. The service-API layer was actively used through to the freeze.

What it covers

Representative routes

API routes — JSON only, no Twig views.
Method Path Handler Notes
POST /api/v1/auth/login ApiAuthController.login Email + password; returns bearer token.
POST /api/v1/auth/refresh ApiAuthController.refresh Refresh long-lived session token.
GET /api/v1/boards ApiBoardController.list Boards the authed user has access to.
GET /api/v1/boards/:id ApiBoardController.detail
GET /api/v1/boards/:id/posts ApiBoardController.posts Paginated; cursor in `since` param.
POST /api/v1/boards/:id/posts ApiBoardController.createPost Plain-text body.
GET /api/v1/profile ApiProfileController.show
PATCH /api/v1/profile ApiProfileController.update
POST /api/svc/transcribe/callback SvcController.transcribeCallback In-house Whisper job posts result back.
POST /api/svc/hunter/callback SvcController.hunterCallback Email-enrichment results.
POST /api/svc/stripe/webhook SvcController.stripeWebhook Connect transfer status updates.

Headline flow: iOS login → board feed

Step 1: User opens iOS app; app POSTs /api/v1/auth/login with stored credentials.
Step 2: ApiAuthController.login verifies SHA-256 password hash, issues a
        bearer token (random 48-byte hex), persists session row.
Step 3: App makes GET /api/v1/boards with the bearer token.
Step 4: ApiBoardController.list returns JSON list of boards the user can see.
Step 5: User taps a board; app GETs /api/v1/boards/:id and
        /api/v1/boards/:id/posts in parallel.
Step 6: User posts a reply; app POSTs /api/v1/boards/:id/posts with text.
Step 7: Server fans out notifications (push and email) via dispenserd lane
        `notify`.