docs
API

Typed clients and LLM access

Generate a typed client from the OpenAPI document, and point models at the contract as plain text.

An OpenAPI document is a file that describes an API in a format tools can read. Ours is the contract: everything the API accepts and returns. It's built from the running code and published at api.affiliaterail.com/v1/openapi.json. Anything that reads OpenAPI 3.1 can use it, so you rarely need to write request types by hand.

A typed TypeScript client

We use two tools ourselves. openapi-typescript makes the types, and openapi-fetch makes the calls. openapi-fetch is a thin fetch wrapper with full types. The only generated file is one .d.ts.

npm install openapi-fetch
npm install -D openapi-typescript
npx openapi-typescript https://api.affiliaterail.com/v1/openapi.json -o rail-api.d.ts
import createClient from "openapi-fetch";
import type { paths } from "./rail-api";

const rail = createClient<paths>({
  baseUrl: "https://api.affiliaterail.com",
  headers: { Authorization: `Bearer ${process.env.RAIL_API_KEY}` },
});

const { data, error } = await rail.GET("/v1/partners", {
  params: { query: { program_id: "prg_...", limit: 5 } },
});
// data is typed: { data: Partner[]; has_more: boolean; total_count: number }

Every path, parameter and response body gets its type from the same document the interactive reference renders. So your compiler and the docs can never disagree. Run the generate command again when you want new endpoints. Changes that only add things never break the calls you already make.

The same document works with code generators for other languages, through any OpenAPI 3.1 tool. Each time we build, we check that the published copy is valid against the spec's schema.

LLM access

If a model is reading, give it plain text and skip the HTML:

Paste one into a prompt, or point a coding assistant at it. Then it works from the exact contract.

If the assistant should read your data, use the MCP server. It's a live link to your own program, limited to the scopes you allow, and you can cut it off.