Content
Browse libraries, read today's scheduled content, and CRUD user-owned items.
Clients can read any library item (admin-authored content), author their own items within a library (rows stamped with owner_app_user_id = session user), and update / delete only the items they own.
Source: apps/api/src/routes/client/content.ts.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /client/content/today | Items delivered today by the CONTENT_DELIVERY workflow. |
| GET | /client/content/libraries/:libraryId | Paginated library browse. |
| POST | /client/content/libraries/:libraryId/items | Create an item owned by the caller. |
| PATCH | /client/content/items/:itemId | Update — only if owner_app_user_id matches the caller. |
| DELETE | /client/content/items/:itemId | Delete — ownership-scoped. |
| GET | /client/content/items/:itemId | Fetch a single active item. |
GET /client/content/today
Today's delivered items (UTC date) joined to their content_schedules and content_items rows.
Response 200
Errors
500 FETCH_FAILED.
Try it:
/client/content/todaycurl -X GET 'https://api.amba.dev/client/content/today'Curl:
GET /client/content/libraries/:libraryId
Paginated list of active items ordered by sort_order.
Query
| Param | Default | Description |
|---|---|---|
limit | 50 | |
offset | 0 | |
category | — | Optional filter. |
Response 200
Try it:
/client/content/libraries/%7B%7BlibraryId%7D%7Dcurl -X GET 'https://api.amba.dev/client/content/libraries/%7B%7BlibraryId%7D%7D'Curl:
POST /client/content/libraries/:libraryId/items
Create an item with ownership stamped from the session user. sort_order is computed server-side via the shared advisory-lock helper (MAX+1 within the library). is_premium and is_active are not settable by clients.
Request
| Field | Type | Required |
|---|---|---|
body | string | yes |
title | string | null | no |
media_url | string | null | no |
category | string | null | no |
tags | string[] | no |
metadata | object | no |
Response 201
Full inserted row including id, owner_app_user_id, sort_order, is_active = true.
Errors
400 INVALID_INPUT— body missing or not JSON.404 NOT_FOUND— library does not exist.500 CREATE_FAILED.
Try it:
/client/content/libraries/%7B%7BlibraryId%7D%7D/itemscurl -X POST 'https://api.amba.dev/client/content/libraries/%7B%7BlibraryId%7D%7D/items'Curl:
PATCH /client/content/items/:itemId
Allowed fields: title, body, media_url, category, tags, metadata, is_active.
Ownership enforced in the UPDATE — zero rows affected → 404 NOT_FOUND whether the item doesn't exist or is owned by someone else (existence not leaked).
Errors
400 INVALID_INPUT.404 NOT_FOUND.500 UPDATE_FAILED.
Try it:
/client/content/items/%7B%7BitemId%7D%7Dcurl -X PATCH 'https://api.amba.dev/client/content/items/%7B%7BitemId%7D%7D'Curl:
DELETE /client/content/items/:itemId
Ownership-scoped; returns 404 NOT_FOUND on a miss without distinguishing the cause.
Response 200
Errors
404 NOT_FOUND.500 DELETE_FAILED.
Try it:
/client/content/items/%7B%7BitemId%7D%7Dcurl -X DELETE 'https://api.amba.dev/client/content/items/%7B%7BitemId%7D%7D'Curl:
GET /client/content/items/:itemId
Returns the item only if it's is_active = true.
Errors
404 NOT_FOUND.500 FETCH_FAILED.
Try it:
/client/content/items/%7B%7BitemId%7D%7Dcurl -X GET 'https://api.amba.dev/client/content/items/%7B%7BitemId%7D%7D'Curl: