Rack Maker

Docs
API reference

HTTP API

The public, read-only HTTP endpoints for the catalog, model files, listings and read-only project links, with parameters, responses and examples.

Before you start

Unversioned

These endpoints are what the Rack Maker app itself uses. They are not versioned and may change without notice. Don't build anything that can't cope with a field being added, renamed or removed.

  • The endpoints on this page are read-only, need no account, and are safe to call from a script or curl.
  • Every other endpoint (saving projects, drafting and publishing entries, uploading files, reporting, signing in, syncing between browsers, moderation) is for the app itself. They need a signed-in browser session and aren't documented here.
  • Using an AI agent? Connect it to the MCP server instead of calling this API. The MCP server signs your agent in as you and gives it tools made for the job. See Agents.

All paths are relative to https://rack-maker.cbnsndwch.dev.

Responses and errors

Answers are JSON (content-type: application/json), unless noted. An error has an HTTP status and a body like this:

{ "error": "no such entry" }

Some errors add a detail field. Unknown paths answer 404 with { "error": "not found" }.

Caching and limits

JSON answers are sent with cache-control: no-store: the server doesn't cache them, and nor should anything between you and it. If you poll, cache on your side and keep it gentle, say once every few minutes. The only cacheable answers are files (model files and link-preview images), noted below.

There is no search endpoint. The catalog page searches in your browser: to search, fetch the snapshot or the entry list and filter it yourself.

Catalog

Catalog ids are <namespace>/<slug>: the namespace is lowercase letters, digits and dashes; the slug may also contain dots. In paths, the namespace and slug are two segments. See Namespaces.

Catalog data is CC BY-SA 4.0: if you republish it, credit its authors and share alike. See Licences and credits.

GET /api/catalog/entries

One summary per entry, sorted by id.

curl https://rack-maker.cbnsndwch.dev/api/catalog/entries
[
    {
        "id": "cbnsndwch/shelf-10in",
        "name": "10″ shelf",
        "kind": "part",
        "category": "shelf",
        "latestPublished": 1,
        "hidden": false
    }
]
FieldMeaning
id, name, kind, categorythe entry; kind is part or assembly
latestPublishedthe newest published revision number, or null if nothing is published yet
hiddentrue when a moderator (or enough reports) has hidden it; see Reports

The list includes every entry, including ones with no published revision and hidden ones. Filter on latestPublished and hidden for what the catalog page shows.

GET /api/catalog/published

When each entry's newest published revision was published, and by whom: their handle (by), display name (name) and user id (user, the id entries' credits use). Hidden entries are left out. Newest first.

curl https://rack-maker.cbnsndwch.dev/api/catalog/published
[
    {
        "id": "alice/mini-pc-tray",
        "rev": 2,
        "at": "2026-09-20T14:03:11.000Z",
        "by": "alice",
        "name": "Alice Chen",
        "user": "github:1234567"
    }
]

Entries that ship with the app show system as by. at, by, name and user can be null.

GET /api/catalog/snapshot

Every published revision of every entry, with its full definition. This is what the catalog loads, and the easiest way to get everything at once.

curl https://rack-maker.cbnsndwch.dev/api/catalog/snapshot
{
    "entries": [{ "id": "cbnsndwch/shelf-10in", "rev": 1, "kind": "part", "name": "10″ shelf", "…": "…" }],
    "statuses": { "cbnsndwch/shelf-10in@1": "published" },
    "hidden": ["bob/spam-part"]
}
FieldMeaning
entriesfull entry definitions, one per revision (older revisions included), sorted by id and then revision
statuseseach revision's status, keyed <id>@<rev>; without an account, always published
hiddenids of hidden entries. Their revisions are still in entries (projects that use them must still resolve), but don't offer them to people

The fields of an entry are described in Authoring parts. To show "the" revision of each entry, take the highest published rev per id and skip hidden ids.

GET /api/catalog/entries/:namespace/:slug

The entry's revisions, newest first, without their definitions.

curl https://rack-maker.cbnsndwch.dev/api/catalog/entries/cbnsndwch/shelf-10in
{
    "id": "cbnsndwch/shelf-10in",
    "canDraft": false,
    "revisions": [
        {
            "id": "cbnsndwch/shelf-10in",
            "rev": 1,
            "status": "published",
            "sha256": "9f2c…",
            "authorId": "…",
            "forkedFrom": null,
            "createdAt": "2026-09-01T00:00:00.000Z",
            "updatedAt": "2026-09-01T00:00:00.000Z",
            "submittedAt": null,
            "publishedAt": "2026-09-01T00:00:00.000Z",
            "can": { "change": false, "review": false }
        }
    ]
}
FieldMeaning
revisions[].statusreview, published or rejected (drafts are only shown to their author)
revisions[].sha256a hash of the revision's definition
revisions[].forkedFrom<id>@<rev> it was copied from, if any
revisions[].authorIdan opaque account id, not a handle
canDraft, canwhat the caller may do; always false without an account

Answers 404 when there is no such entry.

GET /api/catalog/entries/:namespace/:slug/:rev

One revision, with its full definition in entry. The other fields are those of a revision in the list above, without can.

curl https://rack-maker.cbnsndwch.dev/api/catalog/entries/cbnsndwch/shelf-10in/1
{
    "id": "cbnsndwch/shelf-10in",
    "rev": 1,
    "status": "published",
    "publishedAt": "2026-09-01T00:00:00.000Z",
    "…": "…",
    "entry": { "id": "cbnsndwch/shelf-10in", "rev": 1, "kind": "part", "name": "10″ shelf", "…": "…" }
}

Without an account, only published revisions can be read. Anything else, or a rev that isn't a whole number from 1 up, answers 404.

Model files

Model files are the GLB and STL files catalog entries are drawn from. Each keeps its own licence: see Licences and credits. An entry that uses one has "geometry": { "kind": "mesh", "asset": { "asset": "<id>" } } in its definition, where the id is the file's SHA-256.

The files that ship with the app aren't in this API. Their ids start with bundled/, and they are served as static files from /models/, for example /models/rack-19in-12u.stl. Their credits are on the Credits page.

GET /api/assets

Without parameters: every model file that hasn't been taken down, newest first, up to 500. With ids: those files, taken down or not.

ParameterMeaning
idsoptional: up to 200 file ids, separated by commas
curl "https://rack-maker.cbnsndwch.dev/api/assets?ids=3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
[
    {
        "id": "3a7bd3e2…",
        "kind": "mesh-glb",
        "license": "CC-BY-4.0",
        "bytes": 1843200,
        "source": {
            "origin": "third-party",
            "provider": "Sketchfab",
            "title": "Some switch",
            "author": "someone",
            "authorUrl": "https://…",
            "url": "https://…",
            "changes": "Scaled to fit the part's envelope.",
            "acknowledgements": "…",
            "retrievedAt": "2026-09-20T14:03:11.000Z"
        },
        "meta": { "format": "glb", "…": "…" },
        "uploader": "alice",
        "createdAt": "2026-09-20T14:03:11.000Z",
        "hidden": false
    }
]
FieldMeaning
kindmesh-glb or mesh-stl
licensean SPDX-style id: CC0-1.0, CC-BY-4.0, CC-BY-SA-4.0, CC-BY-3.0, CC-BY-SA-3.0, MIT or Apache-2.0
source.originown (the uploader made it) or third-party
sourcewhere it comes from and whom to credit; optional fields may be null
metawhat the server read from the file when it was uploaded
uploaderthe uploader's handle
hiddentrue when it was taken down after a report

GET /api/assets/:id

One file's details, as a single object shaped like an item of the list above. 404 when there is no such file.

curl https://rack-maker.cbnsndwch.dev/api/assets/3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b

GET /api/assets/:id/file

The file itself, as model/gltf-binary (GLB) or model/stl (STL).

curl -o model.glb https://rack-maker.cbnsndwch.dev/api/assets/3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b/file
  • Cached publicly for a day (cache-control: public, max-age=86400). A file never changes under the same id, but it can be taken down.
  • 410 when it was taken down after a report; 404 when there is no such file.
  • Up to 15 MB.

Before you share the file, check its licence and credits with GET /api/assets/:id.

Listings

GET /api/listings

Where to get catalog entries: online shops and physical stores, each with its latest price and stock report. Hidden listings are left out.

ParameterMeaning
idscatalog entry ids, separated by commas, up to 200. Without it, the answer is {}
curl "https://rack-maker.cbnsndwch.dev/api/listings?ids=cbnsndwch/shelf-10in,cbnsndwch/cage-nut-m6"
{
    "cbnsndwch/shelf-10in": [
        {
            "id": "V1StGXR8_Z5jdHi6B-myT",
            "catalogId": "cbnsndwch/shelf-10in",
            "vendor": "Some shop",
            "url": "https://…",
            "channel": "online",
            "location": null,
            "sku": null,
            "region": null,
            "kind": "new",
            "packQty": 1,
            "price": { "amount": 24.9, "currency": "EUR", "at": "2026-09-20T14:03:11.000Z" },
            "stock": { "status": "in-stock", "at": "2026-09-20T14:03:11.000Z" }
        }
    ]
}
FieldMeaning
(keys)the catalog ids that have listings; ids without any are left out
channelonline (with its product page in url) or store (a physical store at location; url may be null)
kindnew, used, print-service or self-print
packQtyitems per purchase
pricethe latest price with its three-letter currency and date, or null
stockthe latest stock report (in-stock, low or out-of-stock) with its date, or null

Prices and stock are reported by contributors and dated. The app treats a price older than 90 days as stale. See BOM & quote.

A project's owner can share a read-only link, /v/<token>, where the token is 21 characters of letters, digits, _ and -. See Sharing. These endpoints read what such a link shows. They never reveal the project's own id, which is what grants editing.

GET /api/view/:token

The project behind a read-only link, as it was last saved.

curl https://rack-maker.cbnsndwch.dev/api/view/Uakgb_J5m9g-0JDMbcJqL
{
    "project": {
        "id": "",
        "name": "Office rack",
        "createdAt": "2026-09-10T09:00:00.000Z",
        "updatedAt": "2026-09-20T14:03:11.000Z",
        "claimed": true,
        "mine": false
    },
    "state": {
        "id": 0,
        "version": 1790000000000,
        "updatedAt": "2026-09-20T14:03:11.000Z",
        "doc": { "…": "…" }
    }
}
FieldMeaning
project.id, state.idalways empty or 0 here
project.namemay be null
statenull when nothing has been saved yet
state.versionchanges on every save; compare it to see whether the project changed
state.docthe project: its racks and parts, each pointing at a catalog entry and revision

404 with { "error": "no such link" } when the token matches no project.

GET /api/view/:token/og.jpg

The link-preview picture of a read-only link: a 1200 × 630 JPEG of the project in 3D. The owner's browser makes it while they have the project open, so a project may not have one yet. HEAD works too.

ParameterMeaning
voptional: the picture's version, as it appears in the page's og:image tag
curl -o preview.jpg https://rack-maker.cbnsndwch.dev/api/view/Uakgb_J5m9g-0JDMbcJqL/og.jpg
  • With the current v, the answer is cached for a year (immutable): a new picture gets a new version. Without it, or with an old one, it is cached for 5 minutes.
  • It carries an ETag.
  • 404 when there is no such link or no picture yet. Link previews then use the site's default picture.

The easiest way to get the current URL, with its version, is the og:image tag in the HTML of /v/<token>.

On this page