← API reference

Crate

Records and artists somebody suggested that you do not own — the one place in Tapedeck that names music outside the collection.

Tapedeck does not recommend; it records recommendations made to you. The vision rule governs what Tapedeck generates (Rediscovery is built entirely from your own history and stays that way); this stores what an assistant said, the way notes store what you wrote. It is its own table, its own endpoints and its own page, and never appears in a history or statistics readout.

4 of 4 · v0.120.0
GET /api/v1/crate #
Token reador Session

Things somebody suggested that you do not own.

Scope: read (since v0.120). Each entry carries first_played_at, derived from the listens rather than stored — whether the suggestion actually landed. That is the thing only a scrobbler can answer, and it is what makes this more than a wantlist: a recommendation is a prediction, and Tapedeck is the only party that can score it.

landed counts how many entries have since turned up in the history.

Responses

200

The crate.

application/json

object

Everything in the crate, and how much of it landed.

crate array required
each item
object

A crate entry with the bit only Tapedeck can supply: whether the recommendation actually landed.

A recommendation is a prediction, and a scrobbler is the only thing in the room that can score it. first_played_at is derived from the listens rather than stored, so it cannot drift from them.

id integer · int64 required
kind string required

artist, album or track.

artist string required
name string | null
mbid string | null
reason string | null
because string | null
origin string required

user, or the name of the connection that suggested it.

status string required

open, acquired or dismissed.

created_at integer · int64 required
acted_at integer | null · int64
first_played_at integer | null · int64

When this first turned up in the listening history, if it ever did. Derived from the listens, not stored, so it cannot drift from what it summarises.

plays integer · int64 required
open integer required

Entries still open.

landed integer required

How many suggestions were actually played.

401

No valid session cookie or token. Also returned when a token is presented to a session-only endpoint — the endpoint does not accept tokens at all, so the scope is irrelevant.

application/json

object

Every error body in the API has this shape.

code integer · int32 required

Mirrors the HTTP status.

error string required

Human-readable. Not a stable identifier — do not branch on it.

{
  "code": 401,
  "error": "Authentication required. Log in to access this endpoint."
}
POST /api/v1/crate #
Session

Add something to the crate.

Session-only for this endpoint; an assistant uses the MCP add_to_crate tool, which shares the same validation.

Two refusals, both deliberate. because is required — what in your own listening prompted this — which is the vision doc's pipeline (analytics, candidate selection, explanation) enforced at the door rather than asked for in a prompt. And anything already in the history is refused with its play count: that is not a suggestion, it is rediscovery, and letting it through would turn the crate into a worse copy of a screen that already exists.

Request body required

application/json

object

What a hand-filed crate entry says, plus where it came from.

kind string required

artist, album or track.

artist string required
name string | null

Album or track title. Omitted for an artist, whose name is already in artist.

mbid string | null
reason string | null

Why you would like it, in the suggester's words.

because string required

Required. What in your own listening prompted the suggestion. A recommendation with no grounding in the history is free association, and is refused.

from string | null

Optional. The username of a deck you are patched into — the Reel's "into my crate" button. Resolved and checked server-side, and a deck you cannot read is a 403: the Crate groups by origin and shows "suggested by X", so a client writing that string itself would be asserting a provenance rather than earning one. The patch must point from you to them; somebody who follows you has told you nothing. Omit it for something you found yourself, which files under the origin user.

Responses

200

Filed. created is false when it was already there and the reason was updated.

application/json

object
id integer · int64 required
created boolean required

False when it was already there and its reason was updated.

400

Missing grounding, malformed, or already in the history.

application/json

object

Every error body in the API has this shape.

code integer · int32 required

Mirrors the HTTP status.

error string required

Human-readable. Not a stable identifier — do not branch on it.

401

No valid session cookie or token. Also returned when a token is presented to a session-only endpoint — the endpoint does not accept tokens at all, so the scope is irrelevant.

application/json

object

Every error body in the API has this shape.

code integer · int32 required

Mirrors the HTTP status.

error string required

Human-readable. Not a stable identifier — do not branch on it.

{
  "code": 401,
  "error": "Authentication required. Log in to access this endpoint."
}
403

from named a deck you are not patched into.

application/json

object

Every error body in the API has this shape.

code integer · int32 required

Mirrors the HTTP status.

error string required

Human-readable. Not a stable identifier — do not branch on it.

PATCH /api/v1/crate/{id} #
Session

Mark an entry acquired, dismissed, or open again.

Parameters

id path required
integer · int64

Request body required

application/json

object
status string required

open, acquired or dismissed.

Responses

200

Updated.

application/json

object
ok boolean required
400

Unknown status.

application/json

object

Every error body in the API has this shape.

code integer · int32 required

Mirrors the HTTP status.

error string required

Human-readable. Not a stable identifier — do not branch on it.

401

No valid session cookie or token. Also returned when a token is presented to a session-only endpoint — the endpoint does not accept tokens at all, so the scope is irrelevant.

application/json

object

Every error body in the API has this shape.

code integer · int32 required

Mirrors the HTTP status.

error string required

Human-readable. Not a stable identifier — do not branch on it.

{
  "code": 401,
  "error": "Authentication required. Log in to access this endpoint."
}
404

No such entry.

application/json

object

Every error body in the API has this shape.

code integer · int32 required

Mirrors the HTTP status.

error string required

Human-readable. Not a stable identifier — do not branch on it.

DELETE /api/v1/crate/{id} #
Session

Remove an entry.

Parameters

id path required
integer · int64

Responses

200

Removed.

application/json

object
deleted boolean required
401

No valid session cookie or token. Also returned when a token is presented to a session-only endpoint — the endpoint does not accept tokens at all, so the scope is irrelevant.

application/json

object

Every error body in the API has this shape.

code integer · int32 required

Mirrors the HTTP status.

error string required

Human-readable. Not a stable identifier — do not branch on it.

{
  "code": 401,
  "error": "Authentication required. Log in to access this endpoint."
}
404

No such entry.

application/json

object

Every error body in the API has this shape.

code integer · int32 required

Mirrors the HTTP status.

error string required

Human-readable. Not a stable identifier — do not branch on it.