API routes

Launchway comes with a public API that your users can use to interact with your product. The public documentation page is visible at the /api/public/v1/docs route.

The documentation page is autogenerated using OpenAI Specification (opens in a new tab) and presented using Redocly (opens in a new tab). Redocly is just reading the static JSON that describes your API and can easily be swapped out for other OpenAPI documentation generators such as Swagger UI (opens in a new tab) or RapiDoc (opens in a new tab).

Authentication

The API uses a separate authentication mechanism to the rest of the app. Rather than stateful cookie-based user sessions, the API routes authenticate using a stateless X-API-Key header. The API keys themselves are managed by the user in the /dashboard/settings/api route and are stored in the api_keys table.

The plain-text value of an API key is only ever visible once, at the time of generation, after which it is stored in the table with its hashed value. This ensures the plain-text value is never persisted anywhere. To ensure a user can identify a specific key in their API keys list, should they ever wish to delete it for example, the last four characters of the plain-text key are stored. This allows them to be presented in a similar manner to credit card e.g. *******...3879

Routes

All routes are prefixed with /api/public/v1/ to distinguish them from other internal API routes you may need. API routes are no different to any other routes as they are just regular loader() and action() methods.

If you are adding any new routes or changing the schema definitions, make sure to add the definition to the app/routes/api.public.v1.schema[.json].ts file so consumers are aware of it.

Guidance

Unlike any internal APIs or endpoints, the public API must be stable and resistant to breaking changes so as not to break and integrations your consumers may have. There are a couple of conventions already in place to help with this.

  • Versioning the API (e.g. /v1/) allows you to make major changes by releasing new versions while not breaking the old one
  • Defining separate request and response Zod schemas (app/services/public-api/schemas.ts) so that the consumer can always expect the same response. It's highly recommend to use these rather than returning direct query results from your database as it will ensure the same responses as your database models grow.