Delivery API
Reading content. With a delivery key it returns what is published; with a preview key, the latest version (see Preview API). General conventions in API.
Every example uses acton-estero as the site, $PLUMA_KEY as the key, and the event type created in the Management API. The curls on this page run in CI, in order, against a test database.
Site
GET /api/v1/spaces/:space_id
curl https://pluma.so/api/v1/spaces/acton-estero -H "Authorization: Bearer $PLUMA_KEY"
{
"sys": { "id": "acton-estero", "type": "Space" },
"name": "Acton Estero",
"default_locale": "es", "prefix_default_locale": false,
"locales": [ { "code": "es", "name": "Español", "default": true, "fallback_code": null } ],
"content_types": [ { "api_id": "event", "name": "Event", "kind": "collection" } ],
"content_menu": { "groups": [ { "group": "collections", "name": "Collections", "content_types": ["event"] } ], "sections": [] }
}
content_types come in the order of the dashboard's Content menu, each with its kind (page, section, collection or settings). content_menu has the same types by group, in the site's group order, and the sections apart (they're edited inside their pages). See How content is organized.
Content types
GET /api/v1/spaces/:space_id/content_types
GET /api/v1/spaces/:space_id/content_types/:id
curl https://pluma.so/api/v1/spaces/acton-estero/content_types/event -H "Authorization: Bearer $PLUMA_KEY"
{
"sys": { "id": "event", "type": "ContentType" },
"name": "Event",
"description": "Calendar events",
"singleton": false,
"display_field": "title",
"url_path": null,
"kind": "collection",
"subtitle_field": null,
"image_field": null,
"position": null,
"entry_order": "-sys.updated_at",
"fields": [
{ "api_id": "title", "name": "Title", "type": "symbol", "required": true, "localized": false },
{ "api_id": "slug", "name": "Slug", "type": "slug", "required": true, "localized": false },
{ "api_id": "host", "name": "Host", "type": "reference", "required": false, "localized": false, "link_content_types": ["person"] }
]
}
Hidden fields don't show up. kind, subtitle_field, image_field and entry_order are the values in effect, set by the model or inferred; see Edit a content type. Fields carry help and group when they have them, options on select and multi_select, and accept (image, video or any) on asset and assets.
Entries
GET /api/v1/spaces/:space_id/entries
GET /api/v1/spaces/:space_id/entries/:id
curl "https://pluma.so/api/v1/spaces/acton-estero/entries?content_type=event&fields.slug=open-house&rich_text=html" \
-H "Authorization: Bearer $PLUMA_KEY"
{
"sys": { "type": "Array" }, "total": 1, "skip": 0, "limit": 100,
"items": [
{
"sys": { "id": "12", "type": "Entry", "content_type": "event", "version": 3, "published_version": 3,
"status": "published", "created_at": "2026-09-28T12:00:00Z", "updated_at": "2026-09-28T12:05:00Z",
"published_at": "2026-09-28T12:05:00Z", "locale": "es" },
"fields": {
"title": "Open House",
"slug": "open-house",
"body": "<h2>Come join us</h2>\n<p>A <strong>great</strong> day.</p>",
"cover": { "sys": { "type": "Link", "link_type": "Asset", "id": "4" } },
"host": { "sys": { "type": "Link", "link_type": "Entry", "id": "7" } }
}
}
]
}
sys.position shows up when the entry has a place in its type's manual order (set in the dashboard or with Order a type's entries).
With your site's URLs and the type's url_path set, sys also carries url (where the entry lives on the live site, once published) and, with a key that reads drafts, preview_url (its page on the staging site). See Staging and previews.
Parameters
| Parameter | What it does | Example |
|---|---|---|
content_type |
Only entries of that type | content_type=event |
fields.<api_id> |
Equal to that value (text, number, yes/no, slug) | fields.slug=open-house |
order |
Order: sys.position, sys.created_at, sys.updated_at, sys.published_at or fields.<api_id>; with a leading -, descending. See Order |
order=-sys.published_at |
limit, skip |
Pagination | limit=10&skip=20 |
locale |
Language, or * for all. Missing values fall back; filters, sorting and sys.url use it too (Languages) |
locale=en |
rich_text |
How rich text comes back: json (default), markdown or html |
rich_text=html |
include |
Include the referenced entries and files, up to 2 levels | include=1 |
Order
- Without
order, entries come newest change first (-sys.updated_at). - With
content_typeand noorder, the type's own order is used if the model set one (itsentry_order, likesys.positionafter someone dragged the entries in the dashboard). A type without one stays-sys.updated_at. order=sys.positionis the manual order: entries placed by hand first, in their order; the ones never placed go last, newest change first.
With include=1 the response adds:
"includes": {
"Entry": [ { "sys": { "id": "7", "type": "Entry", … }, "fields": { "name": "Rosa Caal" } } ],
"Asset": [ { "sys": { "id": "4", "type": "Asset" }, "fields": { "title": "Playground", "alt": "Recess in the playground", "file": { … } } } ]
}
References stay as a Link in fields; you resolve them by looking up their id in includes. That way an entry that shows up twice travels only once.
Files
GET /api/v1/spaces/:space_id/assets
GET /api/v1/spaces/:space_id/assets/:id
{
"sys": { "id": "4", "type": "Asset", "created_at": "…", "updated_at": "…" },
"fields": {
"title": "Playground", "alt": "Recess in the playground", "description": null,
"file": { "url": "https://pluma.so/files/acton-estero/4-k3x9q2m7ab/playground.jpg", "filename": "playground.jpg",
"content_type": "image/jpeg", "size": 61826, "width": 1600, "height": 1000 }
}
}
With a delivery key, only the files used by some published entry show up.
Possible errors
invalid_key, missing_key, wrong_space, not_found, invalid_parameter.