API

A JSON API over your own kitchen.

Everything the app can reach, your code can reach. Same recipes, same permissions, same answers — a token carries your own access and nothing beyond it.

Getting started

Two things: the address, and a token in the header.

Base URL

https://recipejam.com/api/v1

Every request

Authorization: Bearer YOUR_TOKEN
Accept: application/json
Content-Type: application/json

You will need an account and a token. Tokens are made under Tokens and connections once you are signed in, and are shown once, at the moment you create them.

The reference

Every endpoint, with its parameters, its body and the exact shape it answers with.

Conventions

True of every endpoint, so the reference pages do not repeat it.

Ids are opaque
Never database numbers. They are the same ids the app uses in its own URLs, so an id from a share link works here. Treat them as strings and do not try to order or arithmetic them.
Everything is wrapped in data
A single object comes back under a `data` key, not at the top level. So does a listing, alongside `links` and `meta`.
Partial updates
PATCH changes only what you send. A field you leave out keeps its value; a list you send replaces that list entirely rather than merging into it.
Timestamps are ISO 8601
With an offset, in UTC. `createdAt` and `updatedAt` are on every object that has them.
Absent is not null
A relation you did not ask for is missing from the response rather than null — `steps` is absent from a listing, not empty. Check for the key, not for a value.
Your access, exactly
A token carries the permissions of the person who made it, and every request is authorised per record by the same policies the app uses. There is no token that sees more.

Paging through a list

Every listing is paginated, 25 at a time by default and 100 at most.

Field Type Notes
data array The page of results.
links.first string URL of the first page.
links.last string URL of the last page.
links.prev string, or null Null on the first page.
links.next string, or null Null on the last page. The presence of this is the only reliable way to know there is more.
meta.current_page integer Which page this is, from 1.
meta.last_page integer How many pages there are.
meta.per_page integer How many were asked for.
meta.total integer How many there are altogether.
meta.from integer, or null Index of the first row on this page. Null on an empty page.
meta.to integer, or null Index of the last row on this page.

Follow `links.next` until it is null rather than counting pages yourself — that way a page arriving while you read does not make you miss a row or fetch one twice.

When it goes wrong

Every failure is JSON with a `message`. A 422 also carries `errors`, keyed by field.

  • 400 The request itself was malformed — usually a body that is not valid JSON.
  • 401 No token, a token that has been revoked, or one sent in the wrong header.
  • 403 A real token, but not for this. A recipe shared with you can be read and edited; it cannot be deleted. A viewer cannot compile a book.
  • 404 No such id — or an id belonging to somebody else, which answers the same way on purpose. Told apart, an id becomes a way to probe for other people's recipes.
  • 405 The right path, the wrong verb.
  • 422 Understood and refused. `errors` names the fields and says what was wrong with each.
  • 500 Ours. Worth retrying once; if it persists, it is a bug rather than your request.

A 422, in full

{
    "message": "The name field is required.",
    "errors": {
        "name": [
            "The name field is required."
        ]
    }
}

Or skip the code

If what you want is to ask questions about your recipes rather than build something, the MCP connector does that without a token or a line of code.