Skip to content

API reference

The canonical contract is the lexicons — the dev.antiphony.* records every endpoint reads and writes. The REST surface is the transport over those records.

A generated, per-endpoint view of the live OpenAPI spec lives at /api/reference — Scalar-rendered from apps/core-api’s Zod schemas. Treat it as a lookup aid; the lexicons are the contract you design against.

This page covers the high-level shape of the surface and the auth + envelope conventions every endpoint follows.

Every endpoint in the reference lives in apps/core-api — the open-core service. Apps built on the core may add their own product-specific endpoints on top; those aren’t part of this open core and aren’t documented here.

The canonical resources:

  • /posts — Create an audio post, get one by id, list the viewer’s posts, list a post’s replies (the thread). One record type; reply presence is prompt-vs-reply.
  • /audio — Upload audio (authenticated and anonymous-pending), and resolve a stored ref to a short-lived signed playback URL.
  • /users — Profile read, current-user write, handle claim/availability.
  • /actors / /resolve — Actor profiles and handle resolution.
  • /atproto — AT Protocol identity linking (connect/disconnect — about the actor’s DID).

Internal/utility routes (system-auth glue, ingestion plumbing) intentionally stay out of the public reference — they’re service-to-service plumbing a third-party client wouldn’t call.

All non-public endpoints require a bearer token in the Authorization header:

Authorization: Bearer <id_token_or_session_cookie>

core-api accepts both Firebase ID tokens (mobile, embed, browser) and Firebase session cookie values (server-side rendered apps) interchangeably. An anonymous Firebase token is enough to write and read your own posts — see the reference app. Public projections accept missing/invalid tokens and return a public-safe shape.

Every JSON response wraps its payload:

  • Success: { success: true, data: T }
  • Failure: { success: false, error: { message, code?, issues? }, requestId }

Paginated lists nest the cursor inside data:

{
"success": true,
"data": {
"items": [...],
"nextCursor": "the-id-of-the-last-item-or-null"
}
}

The requestId correlation ID appears in every error response and as the X-Request-ID response header on every request — propagate it from your client (X-Request-ID: <uuid>) for end-to-end tracing across core-api and downstream logs.

The reference is generated at build time from the Zod request/response schemas declared in apps/core-api/src/adapters/inbound/rest/*.ts. When a route’s contract changes there, npm run gen:openapi -w @antiphony/core-api regenerates openapi.json and this site rebuilds. Those same schemas mirror the lexicons, so the wire format and the portable records stay in lockstep.