Conventions

These rules apply to every endpoint in the API. Reading them once will save you
from surprises on individual resources.

JSON in, JSON out

Send Content-Type: application/json on requests with a body. Responses are
always JSON.

Field naming

Request bodies accept either camelCase or snake_case — spaceId and
space_id are equivalent. Responses include both forms for each field, plus
an id, so you can read whichever your code prefers:

{
  "id": "b1a2…",
  "spaceId": "9f7e…",
  "space_id": "9f7e…",
  "sortOrder": 3,
  "sort_order": 3,
  "created_at": "2026-08-11T09:30:00Z"
}

Identifiers

All resource ids are UUID strings. Slugs are the human-readable alternative and
are unique within their parent — a space slug per workspace, an article slug per
space, a chapter slug among its siblings — but endpoints address rows by id.

Pagination

List endpoints are offset-based:

Parameter Meaning Default Range
limit Page size 50 1–200
offset Rows to skip 0 0+

A list response wraps the rows with the total count and the echoed paging
window:

{
  "data": [ { "id": "…" }, { "id": "…" } ],
  "total": 137,
  "limit": 50,
  "offset": 0
}

To page through everything, keep requesting with offset += limit until
offset + len(data) >= total.

Parameter Purpose
spaceId Required on the chapter and article lists — which space to read
collectionId Narrow an article list to one chapter
status Filter by lifecycle state (article, ticket or FAQ status)
q Free-text search (article slug, ticket subject or number, FAQ question)
locale Which language to read or write, on the content endpoints

Example:

curl "https://api-v1.zingasuite.com/papi/v1/solve/articles?spaceId=<uuid>&status=published" \
  -H "Authorization: Bearer zk_live_xxx"

Timestamps

Timestamps are ISO-8601 in UTC. Where present, createDate / updateDate (and
resource-specific fields such as placedAt) reflect create and last-modified
times.

Idempotency & retries

Writes are not automatically deduplicated, but the two that matter most are
naturally safe: creating a space, chapter, article or FAQ with a slug that already
exists returns 409 slug_taken rather than a duplicate, and publishing
byte-identical content does not mint a new version. A resilient importer therefore
looks a slug up first and publishes into whatever it finds.

Was this helpful?