Skip to content

Content List

Retrieves a list of content items from a project.

This endpoint is useful for retrieving all content or filtering by a specific model. For example, if you have a model named post, you can use a query param to retrieve all content of that model.

Endpoint

shell
curl https://api.contentisland.net/api/1.0/contents --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'

Query Params

This endpoint accepts the following query parameters:

interface ContentListQueryParams {
id?: ClientFilter<string>;
contentType?: ClientFilter<string>;
language?: string;
`fields.${string}`?: ClientFilter; // Allows filtering by specific field values
// For example: 'fields.slug': 'my-post'
includeRelatedContent?: boolean | number | 'all'; // How many levels of related content to expand. `false` / `0` → off; `true` / `1` → 1 level (legacy); `2..15` → N levels; `'all'` → cap (15). See "Related content expansion" below.
pagination?: {
take?: number; // Number of items to retrieve
skip?: number; // Number of items to skip
},
sort?: {
contentType?: 'asc' | 'desc'; // Sort by content type in ascending or descending order
lastUpdate?: 'asc' | 'desc'; // Sort by last update time
`fields.${string}`?: 'asc' | 'desc'; // Sort by specific field values
}
}
NameDescription
idThe id field of the content to retrieve. Useful for retrieving specific items by ID.
Example: /contents?id[in]=1,2,3
contentTypeThe model of the content you want to retrieve.
Example: /contents?contentType=post
languageThe language of the content to retrieve.
Only fields in the selected language will be returned.
Example: /contents?language=es
fields.${string}Allows filtering by specific field values.
Examples:
/contents?fields.slug=my-post
/contents?fields.title[in]=hello%20world,hola%20mundo
Retrieves content with fields matching the specified values.
includeRelatedContentControls how many levels of related content the server expands in a single response. Accepts false, true (legacy 1 level), 0..15, or 'all' (alias of the depth cap, 15). See the Related content expansion section for limits, partial responses, and headers.
Examples:
/contents?includeRelatedContent=true — legacy 1 level.
/contents?includeRelatedContent=3 — 3 levels.
/contents?includeRelatedContent=all — up to 15 levels.
paginationAn object to control pagination of the results.
- take: Number of items to retrieve.
- skip: Number of items to skip.
Example: client.getContentList({ pagination: { take: 10, skip: 20 } }) retrieves 10 items, skipping the first 20.
sortAn object to define sorting of the results.
- contentType: Sort by content type in ascending or descending order.
- lastUpdate: Sort by last update time.
- fields.${string}: Sort by specific field values.
Example: client.getContentList({ sort: { 'fields.title': 'asc' } }) sorts by the title field in ascending order.
type ClientFilter<Type = string | boolean | number> =
| Type
| {
in?: Type[];
ne?: Type;
nin?: Type[];
};
NameDescription
stringFilters content where the parameter equals the specified value.
Example: /contents?contentType=post
Retrieves content where the model is equal to post.
inFilters content where the parameter matches any of the provided values.
Example: /contents?language[in]=es,en
Retrieves content fields matching es and/or en.
neFilters content where the parameter does not equal the specified value.
Example: /contents?contentType[ne]=page
Retrieves content where the model is not page.
ninFilters content where the parameter does not match any of the provided values.
Example: /contents?contentType[nin]=page,post
Retrieves content where the model is neither page nor post.

Example:

shell
// Retrieve a list of content items filtered by model and language
curl https://api.contentisland.net/api/1.0/contents?contentType=post&language[in]=es,en --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'

Response

The response is an array of JSON objects containing content information. Each object has the following structure:

export interface Content {
id: string;
contentType: { id: string; name: string };
lastUpdate: Date;
fields: Field[];
}
export interface Field {
id: string;
name: string;
value: any;
type: FieldType;
isArray: boolean;
language: string;
}
  • id: The content ID.
  • contentType: The model to which the content belongs. Contains an id and a name.
  • lastUpdate: The timestamp of the last update.
  • fields: An array of objects representing the content fields.

Example:

[
{
"id": "1",
"contentType": {
"id": "100",
"name": "post"
},
"lastUpdate": "2023-10-01T12:00:00Z",
"fields": [
{
"id": "111",
"name": "title",
"value": "Hola Mundo",
"type": "short-text",
"isArray": false,
"language": "es"
},
{
"id": "222",
"name": "body",
"value": "Este es el cuerpo del post en markdown.",
"type": "long-text",
"isArray": false,
"language": "es"
},
{ "id": "333", "name": "order", "value": 1, "type": "number", "isArray": false, "language": "es" }
]
}
]

The includeRelatedContent query param walks the related-content graph from each returned item up to N hops in a single response.

ValueBehaviour
omitted, false, 0No expansion. Related fields keep their raw id string value.
true (legacy)Expand 1 level (same as includeRelatedContent=1).
1, 2, … 15Expand N levels.
allAlias for the depth cap (15).
anything else (foo, -1, 1.5, 16, TRUE, …)400 Bad Request with { error: "includeRelatedContent must be one of: false, true, 0..15, all" }.

Limits

  • Maximum depth: 15. Defensive cap — real-world graphs rarely exceed 4–5 levels.
  • Per-request budget: 500 contents resolved. If opening the next level would push the total over 500, the level is not opened (cut on a whole-level boundary). Unresolved related ids stay as raw string values in the response body.

Partial responses

Every response carries:

  • X-Related-Content-Resolved-Depth: integer, the depth actually reached (0 when no expansion happened).
  • X-Related-Content-Partial: present and set to true only when the response was truncated — either by the budget cap or because the requested depth was exhausted while the graph still had more reachable content.

The response body is always a plain Content[] — there is no envelope. To detect unresolved references, check whether a field.value of related-model type is a raw string id instead of an object.

Example with multi-level expansion

Terminal window
curl 'https://api.contentisland.net/api/1.0/contents?includeRelatedContent=2' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
HTTP/1.1 200 OK
X-Related-Content-Resolved-Depth: 2

If the graph reaches a third level, the same call returns the same body but adds X-Related-Content-Partial: true.

Cycles

The expansion deduplicates ids globally as it walks the graph, so a cycle A → B → A with depth ≥ 2 loads each content exactly once: B appears expanded inside A’s field, and inside B the field pointing back to A keeps A’s id as a string.

Status Codes

CodeDescription
200The request was successfully processed and the content list was returned.
400Bad request. A query parameter failed validation — e.g. includeRelatedContent out of range, or a malformed id.
401Unauthorized. The access token is invalid or has expired.
500Internal server error. An error occurred while processing the request.

Error responses follow the uniform contract documented in Errors{ "error": { "code", "message", "requestId", "details?" } }.