List items in a space

Embed
Preview of the card
<a href="https://forumulate.com/reference/forumulate-api-item-list"><img src="https://forumulate.com/reference/_api/public/orgs/046a9bc0-d530-43ae-9bae-af7945008cda/spaces/8042f004-e3d9-445f-b7a4-b6c1f86836e6/pages/ad267baa-812b-49c9-830e-5dab60c733cb/social-card.svg?v=3e7ae33eec8b" alt="List items in a space" width="600" height="315"></a>
GEThttps://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/items

Every piece in a space under one shape, whatever the space’s type calls them — articles, topics, releases, roadmap cards, pages. The endpoint to build a cross-type integration against instead of learning six per-type doors. Each row carries locale, the language declared for that piece (never the space default), and an id that is the same value its kind’s own routes use — a page item’s id is its GET …/pages id.

Requires token scope: read (the coarse method gate) for Atlas key (ak_), Personal Access Token (cft_) or OAuth (cfo_) auth — in addition to any catalog scope (GET /pats/scopes) the route’s capability needs. Session/cookie auth is governed by RBAC capabilities instead.

Parameters
orgIdstringpathrequired
spaceIdstringpathrequired
limitintegerquery
Rows per page. Up to 200, or 50 when include asks for content — every row then carries a whole piece. Asking for more is capped, not refused.
= 50
cursorstringquery
The page.next_cursor of the previous response. Opaque: store it, send it back, never parse it.
updated_sincestringquery
Only pieces changed after this instant. Pass back the sync.checkpoint you stored rather than a clock of your own. An unparseable value is a 422, never a silent full list.
include_deletedstringquery
Carry tombstones (deleted: true) for pieces removed in the last 30 days, so a removal is discoverable without a full list.
true | 1 | yes | on | false | 0 | no | off
includestring[]query
Comma-separated relations to fold in: sections (markdown per named slot) and body (the whole piece as markdown). Either one drops the page cap to 50.
fieldsstring[]query
Comma-separated fields to return; everything else is left out. id always comes back. Composes with include: ask for include=body&fields=id,contentHash,body and you get exactly those.
forumulate-versionstringheader
API version negotiation. Send forumulate-version: 2026-12-01 on every request from a new integration; it is optional only so that integrations written before versioning keep working. Each version includes everything before it:
Code samples
cURL
curl -X GET "https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/items?limit=&cursor=&updated_since=&include_deleted=&include=&fields=" \
  -H "forumulate-version: <value>"
TypeScript
const res = await fetch('https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/items?limit=&cursor=&updated_since=&include_deleted=&include=&fields=', {
  method: 'GET',
  headers: {
    'forumulate-version': '<value>',
  },
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/items?limit=&cursor=&updated_since=&include_deleted=&include=&fields=",
    headers={
    "forumulate-version": "<value>",
    },
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/items?limit=&cursor=&updated_since=&include_deleted=&include=&fields=", nil)
	req.Header.Set("forumulate-version", "<value>")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/items?limit=&cursor=&updated_since=&include_deleted=&include=&fields=');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['forumulate-version: <value>']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/items?limit=&cursor=&updated_since=&include_deleted=&include=&fields=')
req = Net::HTTP::Get.new(uri)
req['forumulate-version'] = '<value>'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/items?limit=&cursor=&updated_since=&include_deleted=&include=&fields="))
    .header("forumulate-version", "<value>")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Responses
200 Two shapes, chosen by the version you state. State Forumulate-Version and you get the pieces, the walk (page) and the watermark (sync). State nothing and you get { items } alone — the legacy shape, served with a Deprecation header (RFC 9745: an @<unix-seconds> date, not a boolean) and a Sunset date, and marked deprecated here so which half is going away is visible on the schema itself.
Example
{
  "items": [
    {
      "id": "string",
      "kind": "page",
      "title": "string",
      "slug": "string",
      "published": true,
      "group": "string",
      "state": "string",
      "locale": "pt-BR",
      "updatedAt": "2024-01-01T00:00:00Z",
      "url": null,
      "contentHash": "string",
      "deleted": true,
      "sections": {},
      "markdown": "string",
      "contentIn": "sections",
      "freshness": null
    }
  ]
}
ItemListLegacyDto
itemsItemSummaryDto[]required
The pieces, and nothing else. No cursor, no total, no watermark — this shape cannot express a walk, which is why it is the one being retired.
Show child parameters
idstringrequired
The piece's own id, the same value its kind's own routes use — so /items joins to them on id. A page item's id IS the page id: the id of the matching PageListRow from GET /orgs/{orgId}/spaces/{spaceId}/pages, and the {pageId} of every …/pages/{pageId} route (a language twin is its own page, with its own id, in both lists). A topic item's id is the topic id the blog, forum, changelog and roadmap routes take (…/blog/{topicId}, …/forum/{topicId}); topics are not in …/pages. An incident item's id is the {incidentId} of …/status/incidents/{incidentId}.
kindstringrequired
What backs this piece in storage.
page | topic | incident
titlestringrequired
slugstring
The name this piece answers to in an address.
publishedbooleanrequired
Whether a reader with no account can see it.
groupstring
The collection a page sits in, where the space has more than one.
statestring
An incident's own state, which published cannot express.
localestring
The language this piece is DECLARED to be written in, as canonical BCP-47: language lowercase, script title case, region uppercase (es, pt-BR, zh-Hant, es-419) — never an underscore form. null when nobody declared a language for this piece; it is never filled in from the space's or the organization's default, so a value is always a fact about this piece. A page reports what was declared for it, else its translation's language when it is a language twin (twins of the primary version are listed as items of their own); a source page is null until declared. A topic (post, forum topic, release, roadmap card) and an incident report what was declared for them — their translations are served under the piece's own id, not listed as items. Correct it with PATCH …/items/{itemId} { "locale": "es" }: that moves updatedAt and never changes contentHash. Absent on a tombstone.
updatedAtstringrequired
When this piece last changed. What the walk is ordered by, and what updated_since compares against.
urlobject
Where a reader can see it, or null when the space is not published to an address. Never guess this: a null means "not published", which is a different thing from "we guessed wrong".
contentHashstring
A hash of the content itself, present when include was asked for. Diff a whole space from one list request without transferring a body.
deletedboolean
Set on a piece that has been removed. See include_deleted.
sectionsobject
Markdown per named slot, when include=sections was asked for.
markdownstring
The whole piece as markdown, when include=body was asked for.
contentInstring
WHICH of the two fields above holds this piece's content. Present on every row that carries content. sections is populated only for a piece written against a shape; a free-form piece returns sections: {}, which a client cannot otherwise tell from a piece that is genuinely empty. Check this rather than assuming: asking for include=sections alone on a space of free-form pieces yields nothing and looks like success.
sections | markdown
freshnessFreshnessDto
Whether this is still known to be true. Absent on a tombstone and on an incident, which is a record of something that happened and does not go stale.
Show child parameters
verifiedAtstringrequired
When somebody last said this is still correct. Null means nobody ever has.
ageDaysnumberrequired
Days since that, or since it last changed when it has never been verified.
stalebooleanrequired
Whether that exceeds the space's staleness policy.
confidencenumberrequired
How much to trust it, 0 to 1. A number rather than a flag because it is meant to be multiplied into your own ranking: recent content should outrank old content without the old disappearing.
{
  "items": [
    {
      "id": "string",
      "kind": "page",
      "title": "string",
      "slug": "string",
      "published": true,
      "group": "string",
      "state": "string",
      "locale": "pt-BR",
      "updatedAt": "2024-01-01T00:00:00Z",
      "url": {},
      "contentHash": "string",
      "deleted": true,
      "sections": {},
      "markdown": "string",
      "contentIn": "sections",
      "freshness": {
        "verifiedAt": null,
        "ageDays": null,
        "stale": null,
        "confidence": null
      }
    }
  ]
}
ItemPageDto
itemsItemSummaryDto[]required
Show child parameters
idstringrequired
The piece's own id, the same value its kind's own routes use — so /items joins to them on id. A page item's id IS the page id: the id of the matching PageListRow from GET /orgs/{orgId}/spaces/{spaceId}/pages, and the {pageId} of every …/pages/{pageId} route (a language twin is its own page, with its own id, in both lists). A topic item's id is the topic id the blog, forum, changelog and roadmap routes take (…/blog/{topicId}, …/forum/{topicId}); topics are not in …/pages. An incident item's id is the {incidentId} of …/status/incidents/{incidentId}.
kindstringrequired
What backs this piece in storage.
page | topic | incident
titlestringrequired
slugstring
The name this piece answers to in an address.
publishedbooleanrequired
Whether a reader with no account can see it.
groupstring
The collection a page sits in, where the space has more than one.
statestring
An incident's own state, which published cannot express.
localestring
The language this piece is DECLARED to be written in, as canonical BCP-47: language lowercase, script title case, region uppercase (es, pt-BR, zh-Hant, es-419) — never an underscore form. null when nobody declared a language for this piece; it is never filled in from the space's or the organization's default, so a value is always a fact about this piece. A page reports what was declared for it, else its translation's language when it is a language twin (twins of the primary version are listed as items of their own); a source page is null until declared. A topic (post, forum topic, release, roadmap card) and an incident report what was declared for them — their translations are served under the piece's own id, not listed as items. Correct it with PATCH …/items/{itemId} { "locale": "es" }: that moves updatedAt and never changes contentHash. Absent on a tombstone.
updatedAtstringrequired
When this piece last changed. What the walk is ordered by, and what updated_since compares against.
urlobject
Where a reader can see it, or null when the space is not published to an address. Never guess this: a null means "not published", which is a different thing from "we guessed wrong".
contentHashstring
A hash of the content itself, present when include was asked for. Diff a whole space from one list request without transferring a body.
deletedboolean
Set on a piece that has been removed. See include_deleted.
sectionsobject
Markdown per named slot, when include=sections was asked for.
markdownstring
The whole piece as markdown, when include=body was asked for.
contentInstring
WHICH of the two fields above holds this piece's content. Present on every row that carries content. sections is populated only for a piece written against a shape; a free-form piece returns sections: {}, which a client cannot otherwise tell from a piece that is genuinely empty. Check this rather than assuming: asking for include=sections alone on a space of free-form pieces yields nothing and looks like success.
sections | markdown
freshnessFreshnessDto
Whether this is still known to be true. Absent on a tombstone and on an incident, which is a record of something that happened and does not go stale.
Show child parameters
verifiedAtstringrequired
When somebody last said this is still correct. Null means nobody ever has.
ageDaysnumberrequired
Days since that, or since it last changed when it has never been verified.
stalebooleanrequired
Whether that exceeds the space's staleness policy.
confidencenumberrequired
How much to trust it, 0 to 1. A number rather than a flag because it is meant to be multiplied into your own ranking: recent content should outrank old content without the old disappearing.
pageobjectrequired
Show child parameters
limitnumberrequired
The limit this page was built with — what was asked for, capped. It is NOT the number of rows returned: a final page under the limit is normal, and has_more is the only thing that says whether to keep walking.
hasMorebooleanrequired
Whether another page follows this one.
nextCursorobjectrequired
Pass back as cursor to continue. Null on the last page.
has_morebooleandeprecated
The same value as hasMore. The only snake_case keys in this API are these two. Sent to callers who state 2026-09-01 or no version at all; ABSENT from 2026-11-01 onwards. Read hasMore instead — it is sent on every version.
next_cursorobjectdeprecated
The same value as nextCursor. Absent from 2026-11-01 onwards; read nextCursor.
totalnumber
Rows in the whole collection — the size of the set, not of this page, and not of what you have seen so far. ABSENT where the source cannot count the collection: the append-only logs (staff actions, automation runs, connector activity, ingested questions, chat history) grow without bound and are not counted on every page view. Walk on hasMore, which is exact on every answer; read total only to show a size, and handle its absence.
syncobjectrequired
Show child parameters
checkpointstringrequired
Store verbatim and send back as updated_since. The server defines the watermark so no client has to reason about clock skew.
dataItemSummaryDto[]required
The same rows as the key named after them (topics, articles, pages, monitors, …), under a key that is the same on every paged list — so one parser reads every collection. The SAME array, not a different selection: read either. Present whenever page is, i.e. when you state Forumulate-Version (or send a cursor); the unversioned shape does not carry it.
Show child parameters
idstringrequired
The piece's own id, the same value its kind's own routes use — so /items joins to them on id. A page item's id IS the page id: the id of the matching PageListRow from GET /orgs/{orgId}/spaces/{spaceId}/pages, and the {pageId} of every …/pages/{pageId} route (a language twin is its own page, with its own id, in both lists). A topic item's id is the topic id the blog, forum, changelog and roadmap routes take (…/blog/{topicId}, …/forum/{topicId}); topics are not in …/pages. An incident item's id is the {incidentId} of …/status/incidents/{incidentId}.
kindstringrequired
What backs this piece in storage.
page | topic | incident
titlestringrequired
slugstring
The name this piece answers to in an address.
publishedbooleanrequired
Whether a reader with no account can see it.
groupstring
The collection a page sits in, where the space has more than one.
statestring
An incident's own state, which published cannot express.
localestring
The language this piece is DECLARED to be written in, as canonical BCP-47: language lowercase, script title case, region uppercase (es, pt-BR, zh-Hant, es-419) — never an underscore form. null when nobody declared a language for this piece; it is never filled in from the space's or the organization's default, so a value is always a fact about this piece. A page reports what was declared for it, else its translation's language when it is a language twin (twins of the primary version are listed as items of their own); a source page is null until declared. A topic (post, forum topic, release, roadmap card) and an incident report what was declared for them — their translations are served under the piece's own id, not listed as items. Correct it with PATCH …/items/{itemId} { "locale": "es" }: that moves updatedAt and never changes contentHash. Absent on a tombstone.
updatedAtstringrequired
When this piece last changed. What the walk is ordered by, and what updated_since compares against.
urlobject
Where a reader can see it, or null when the space is not published to an address. Never guess this: a null means "not published", which is a different thing from "we guessed wrong".
contentHashstring
A hash of the content itself, present when include was asked for. Diff a whole space from one list request without transferring a body.
deletedboolean
Set on a piece that has been removed. See include_deleted.
sectionsobject
Markdown per named slot, when include=sections was asked for.
markdownstring
The whole piece as markdown, when include=body was asked for.
contentInstring
WHICH of the two fields above holds this piece's content. Present on every row that carries content. sections is populated only for a piece written against a shape; a free-form piece returns sections: {}, which a client cannot otherwise tell from a piece that is genuinely empty. Check this rather than assuming: asking for include=sections alone on a space of free-form pieces yields nothing and looks like success.
sections | markdown
freshnessFreshnessDto
Whether this is still known to be true. Absent on a tombstone and on an incident, which is a record of something that happened and does not go stale.
Show child parameters
verifiedAtstringrequired
When somebody last said this is still correct. Null means nobody ever has.
ageDaysnumberrequired
Days since that, or since it last changed when it has never been verified.
stalebooleanrequired
Whether that exceeds the space's staleness policy.
confidencenumberrequired
How much to trust it, 0 to 1. A number rather than a flag because it is meant to be multiplied into your own ranking: recent content should outrank old content without the old disappearing.
{
  "items": [
    {
      "id": "string",
      "kind": "page",
      "title": "string",
      "slug": "string",
      "published": true,
      "group": "string",
      "state": "string",
      "locale": "pt-BR",
      "updatedAt": "2024-01-01T00:00:00Z",
      "url": {},
      "contentHash": "string",
      "deleted": true,
      "sections": {},
      "markdown": "string",
      "contentIn": "sections",
      "freshness": {
        "verifiedAt": null,
        "ageDays": null,
        "stale": null,
        "confidence": null
      }
    }
  ],
  "page": {
    "limit": 0,
    "hasMore": true,
    "nextCursor": {},
    "has_more": true,
    "next_cursor": {},
    "total": 0
  },
  "sync": {
    "checkpoint": "string"
  },
  "data": [
    {
      "id": "string",
      "kind": "page",
      "title": "string",
      "slug": "string",
      "published": true,
      "group": "string",
      "state": "string",
      "locale": "pt-BR",
      "updatedAt": "2024-01-01T00:00:00Z",
      "url": {},
      "contentHash": "string",
      "deleted": true,
      "sections": {},
      "markdown": "string",
      "contentIn": "sections",
      "freshness": {
        "verifiedAt": null,
        "ageDays": null,
        "stale": null,
        "confidence": null
      }
    }
  ]
}
400 The request could not be understood — a malformed header, path or query value (request.malformed). A value that was understood but is not acceptable is a 422 validation.failed.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
401 No credential, or one that is expired or revoked (auth.required). Send a Bearer token or the session cookie.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
403 Authenticated, and not allowed — always rbac.forbidden, whether what is missing is the capability, the token scope, or a resource the token is pinned away from. The message names the capability and, for a scope refusal, the scopes that would grant it. A refusal because of the PLAN is a 402 with quota.exceeded, not this.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
404 No such thing — one of the ids in the path does not resolve, or resolves to something this caller may not see (*.not_found).
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
429 Rate limited — see the RateLimit-* headers.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
default Error — the stable { error: { code, message } } envelope.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
The Forumulate teamUpdated