Common headers (all content routes)
HeaderNotes
AuthorizationRequired. Bearer <token>
X-Tenant-IdRequired.
Image fields (imaginary / imaginary_array)

Backed by the external Imaginary image service. Send a data:image/... string in data to upload a new image (only the returned code is stored, never the base64); send a bare string to reuse an existing image_code; or resubmit the object this field returns on read (below) to leave the image unchanged. imaginary_array applies this per element, up to 10 items.

Every read endpoint on this page expands the stored code

Unlike content/content_array (which only expand on /resolved), image fields expand unconditionally — list, single, /resolved, and a model's content sub-listing all return this shape:

{
  "code": "abc123XYZ789",
  "url": "https://imaginary.magicrunez.com/abc123XYZ789",
  "srcset": "https://imaginary.magicrunez.com/w_400/abc123XYZ789 400w, https://imaginary.magicrunez.com/w_800/abc123XYZ789 800w, https://imaginary.magicrunez.com/w_1200/abc123XYZ789 1200w",
  "sizes": "(max-width: 400px) 400px, (max-width: 800px) 800px, 1200px"
}

Default widths are [400, 800, 1200]; override per-field via validationRules.widths/validationRules.quality on the model's field definition.

Upload errors

StatusCause
400Invalid image value, or more than 10 items in an imaginary_array.
413Image exceeds Imaginary's ~5MB upload limit.
429Imaginary's rate limit (30 uploads/min) was hit.
502Imaginary was unreachable or returned an unexpected response.

An upload failure aborts the entire write — no content row is created or modified.

GET
/content
List content

Returns paginated content items for the tenant.

Query parameters

ParameterNotes
pageDefault 1.
pageSizeDefault 20, max 100.
modelIdOptional. Filter by model.
statusOptional. Filter by status.
searchOptional. Matches title or slug.

Response

{
  "content": [
    {
      "id": 1,
      "tenantId": "tid",
      "modelId": 1,
      "title": "Hello",
      "slug": "hello",
      "status": "draft",
      "data": {},
      "createdAt": null,
      "modifiedAt": null
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "total": 1
  }
}
GET
/content/:id
Get a content item

Returns a single content item. Returns 404 if not found.

GET
/content/:id/resolved
Get resolved content

Returns the content item with all content and content_array field references recursively hydrated (up to 5 levels deep).

GET
/content/:id/references
Get content references

Returns all parent content items that reference this content item via a content or content_array field.

Response

{
  "references": [
    {
      "contentId": 5,
      "modelId": 2,
      "fieldId": 3,
      "fieldKey": "hero",
      "position": 0
    }
  ]
}
POST
/content
Create a content item

Creates a new content item and syncs its content relationships. Requires admin or content_creator role. Returns 422 if required model fields are missing.

Request body

FieldNotes
modelIdRequired. Number.
dataRequired. Object matching the model's fields.
titleOptional.
slugOptional.
statusOptional. Default draft.
PUT
/content/:id
Replace a content item

Replaces a content item's data and re-syncs relationships. data is required. Requires admin or content_creator role. Returns 422 if validation fails.

Request body

FieldNotes
dataRequired.
titleOptional.
slugOptional.
statusOptional.
DELETE
/content/:id
Delete a content item

Deletes the content item and its outbound relationships. Returns 409 if other content references this item. Requires admin or content_creator role.