One build, fourteen apps: see what users made of Memory Tin

Documentation

API: SDK routes

Documentation menu

Every route on this page takes x-tweaklane-key: tl_pk_… and Authorization: Bearer <user token>. A request reads and writes only the data of the user in the token's sub, in that app.

Reading

Route Response
GET /state[?screen=id] {layouts, killSwitch, theme, userScreens, navigation, designs, designIndex, versions}; without screen, everything the user has
GET /layouts[?screen=id] {layouts: [...]}
GET /kill-switches {killSwitch: {engaged, screens, components}}

A layout entry:

Field Meaning
screen screen id
document the layout document; null after a reset
deleted true after a reset (kept so other devices learn of it)
serverVersion the version to send as baseVersion on the next write
schemaVersion, appVersion as written
editedAt, updatedAt edit time on the device, write time on the server

Writing documents

Route Body
PUT /layouts/:screen {document, baseVersion, catalogHash?, appVersion?, editedAt?}
DELETE /layouts/:screen?baseVersion=n[&editedAt=…] resets the screen to your default
PUT /theme, DELETE /theme the app theme document, same body and query
PUT /user-screens, DELETE /user-screens the order of the user's own screens and the start screen
PUT /navigation, DELETE /navigation the navigation document
PUT /designs, DELETE /designs the active design
PUT /designs/:id, DELETE /designs/:id one named design; ids are 1–40 of a–z 0–9 -

User screens are written with PUT /layouts/<prefix><id>, validated in user-screen mode.

Optimistic concurrency. baseVersion is the serverVersion you last saw, 0 for a screen the server has never stored. On success the API answers 200 {layout} with the new serverVersion. If the server has moved on, it answers 409 {error: "conflict", message, current} with the server copy; resolve and write again on top of current.serverVersion.

Every document is validated against the catalog manifest named by catalogHash. Without it, the pinned catalog of appVersion is used, else the newest catalog this user uploaded, else the answer is 422 catalog_missing.

Versions

Route Body / response
POST /versions {version, snapshot, catalogHash, appVersion?} → 201 {id, pruned}; 409 for an existing id
GET /versions/:id[?catalogHash=…] {version, snapshot, check?}; check lists the snapshot's issues against that catalog

Version ids are UUIDs and versions are append-only. Past the limit, the oldest versions that are neither named nor a design's head are pruned.

Catalogs

POST {TWEAKLANE_URL}/catalogs
x-tweaklane-catalog-hash: <sha256 hex of the body>

The body is the catalog manifest. Catalogs are content-addressed by the sha256 of their bytes and immutable: 201 {hash, created: true} for a new one, 200 for a known one, 409 catalog_pinned when the app version's catalog is pinned, 422 invalid_catalog.

AI

Route Body
GET /ai/consent, PUT /ai/consent, DELETE /ai/consent see AI
POST /ai/patch {screen, prompt, document, catalogHash, appVersion?, theme?}
POST /ai/navigation {prompt, navigation, userScreens, catalogHash, appVersion?}
POST /ai/designs {prompt, screen, document, designs, versions, undo?, redo?, catalogHash, appVersion?}

200 {status: "proposed", …, provider, model} with the proposed document or operations, or {status: "rejected", reasons}. Proposals may carry notes that explain a substitution. Errors: 403 consent_required or ai_disabled, 429 rate_limited, 502/503/504 when the model doesn't answer.

Next: API: server routes.