API reference contents
API reference
Documentation
The OpenAPI document
The whole API is described by an OpenAPI 3.1 document served from the same process that answers the requests. It needs no key.
The document
https://outcomedev.com/api/v1/openapi.json
curl -s https://outcomedev.com/api/v1/openapi.json | head -20
{
"openapi": "3.1.0",
"info": {
"title": "OutcomeDev API",
"version": "v1",
"summary": "The desk, without a browser.",
"description": "OutcomeDev reads a business, works out everything it has to keep running, and works that list. This is the same desk, reachable by anything that can hold a key.\n\nEvery route here calls the same module the interface calls, so a row's action, its prepared message, its waiting state and its permissions are the ones a person sees.\n\n**One key, one desk.** There is no route that takes a desk as a parameter, by design: a leaked key is a key to one customer rather than to every customer.\n\n**Nothing sends itself.** Messages go out only where the owner approved them or granted the desk permission for that class of work.",
"contact": { "name": "OutcomeDev", "url": "https://outcomedev.com", "email": "support@outcomedev.com" },
"license": { "name": "Proprietary" }
},
"servers": [{ "url": "https://outcomedev.com", "description": "This deployment" }],
"security": [{ "bearerKey": [] }],
"tags": [
{ "name": "Meta", "description": "The API, the key, and the desk's own vocabulary" },
{ "name": "Work", "description": "What is in flight, and what can be done about it" }
],
"paths": { }
}
No key is needed to fetch it. This is the only route in the API that answers without one, and it is deliberate. A description of an API is not a secret, and an editor or a code generator has to be able to read it before it has a key — that is the entire point of pointing a tool at this URL.
Using it with a generator
Any OpenAPI 3.1 generator can read the document. The command below writes a TypeScript client; swap the generator for the language in use.
npx openapi-typescript https://outcomedev.com/api/v1/openapi.json -o outcomedev.d.ts
npx @hey-api/openapi-ts \
-i https://outcomedev.com/api/v1/openapi.json \
-o ./src/client \
-c @hey-api/client-fetch
Two things a generated client will not do for you, and which are worth handling by hand.
-
Set the key. The document declares a bearer scheme named
bearerKey, so a generator emits a place to put it. Most will not read it from an environment variable; set the header yourself. -
Generate an
Idempotency-Keyper intent. The header is declared, so a generated method will accept it, and the generator cannot know that a retry must reuse the same value. See Idempotency.
The document is also the fastest way to check a claim on these pages. Every path, every parameter and every error status is in it, and it is generated by the same code that serves the routes.
Using it with an editor
Point an OpenAPI-aware editor or a scratch pad at the URL and it will offer every path and field with autocomplete, and can send a request with the key attached.
| Tool | How |
|---|---|
| Bruno, Insomnia, Postman | Import from a URL. Give the collection a bearer token of od_... and every request inherits it. |
| Stoplight Studio, Swagger Editor | Open the URL directly. Useful for reading the document as a tree rather than as JSON. |
| VS Code | Any OpenAPI extension can load the URL as a workspace document; the JSON Schema behind it gives completion while editing a request. |
| Scalar or Redoc | Standalone renderers can be pointed at the URL to produce a browsable reference from the live document. |
Because the document is served live rather than built, an editor pointed at it always shows the API as it is today, including any field added since the editor's cache was filled.
What is in the document
| Section | Contents |
|---|---|
paths | All twenty routes, with parameters, request bodies and the error statuses each can return. |
components.schemas.WorkItem | The full work item, including the action object and its eight types. |
components.schemas.DeskSection | One block of the desk's screen. |
components.schemas.Error | The error body: code, message and optional details. |
components.securitySchemes.bearerKey | An HTTP bearer scheme, described as an od_ key created from inside the product, shown once. |
tags | Six groups: Meta, Work, Arrangements, Record, Desk, Chat. |
What the document does not tell you
A schema is a shape, and some of the things that matter most about this API are not shapes. All of the following are true, and none of them can be expressed in OpenAPI:
-
kindis an open string. It is the desk's own word for a sort of work, so the document cannot enumerate its values.GET /deskreports the kinds a particular desk uses. -
action.labelshould be shown as it arrives. The label is the same word the product's screen puts on the button, and it changes with the situation. The type is the enum; the label is copy. -
A
403does not tell you which403it is. The status is shared byno_deskandnot_permitted, and the difference is in the body'scode. -
Some
200s are refusals.drafted: false,ok: falseandtimed_out: trueare all successful responses carrying unwelcome news. -
Timing is not in the schema.
/work/{id}/runtakes minutes and/chatcan take four, and no schema has a field for that.
This is why the document is written by hand rather than derived by reflecting over the
handlers. Reflection cannot express which fields are computed, which values are the desk's
vocabulary rather than the API's, or what a 403 from
/work/{id}/run means. The risk of a hand-written document is drift, and the
mitigation is a check in the build that asserts every documented path exists and every
path that exists is documented.
Related
- API overview — the same surface as a table.
- MCP server — the same endpoints as sixteen tools, if a client is not the goal.
- Errors — the bodies the document can only summarise.