Kontena API Reference
Kontena's public REST API — every endpoint, parameter, and header you need to read content.
TODO: translate to Indonesian. English source is authoritative; render it into Indonesian below.
The Kontena public API is read-only and returns published content only.
Base URL
https://api.sawala.cloud/public/kontenaAuthentication
Send your API key on every request:
X-API-Key: pk_live_xxxThe Authorization: Bearer <key> form is also accepted.
- A public key (
pk_live_…) is read-only and browser-safe — it's all you need for every endpoint here. - A secret key (
sk_live_…) is read/write and server-side only. It is rejected if sent with a browserOrigin, and it does not unlock drafts or preview — the public API returns published content regardless of key type.
Endpoints
Collection (multiple entries)
| Method | Path | Description |
|---|---|---|
GET | /projects/{projId}/content/collection/{schemaSlug} | List entries in a collection |
GET | /projects/{projId}/content/collection/{schemaSlug}/{id} | Fetch one entry by ID |
Single (one entry per locale)
| Method | Path | Description |
|---|---|---|
GET | /projects/{projId}/content/single/{schemaSlug} | Fetch the single entry |
Schemas
| Method | Path | Description |
|---|---|---|
GET | /projects/{projId}/schemas | List all schemas |
GET | /projects/{projId}/schemas/{schemaId} | Fetch one schema definition |
Query parameters
These apply to the collection list endpoint.
| Param | Values | Description |
|---|---|---|
locale | id, en, … | Filter by entry locale |
q | string | Case-insensitive substring filter over slug and data.title |
limit | integer (default 25, max 100) | Entries per page |
cursor | string | Cursor for the next page (from meta.pagination.nextCursor) |
Response shape
The list endpoint returns a top-level data array plus pagination under meta. Each entry's own fields live inside that entry's data object — for example a post's title is data.title, not a top-level field.
{
"data": [
{
"id": "ent_abc",
"documentId": "doc_abc",
"slug": "hello-world",
"locale": "en",
"status": "published",
"data": { "title": "Hello World", "body": "<p>...</p>", "coverImage": { "url": "https://..." } },
"publishedAt": "2026-05-01T10:00:00Z",
"createdAt": "2026-05-01T10:00:00Z",
"updatedAt": "2026-05-01T10:30:00Z"
}
],
"meta": {
"pagination": { "limit": 25, "hasMore": true, "nextCursor": "ZW50X3h5eg" }
}
}Paginate by passing meta.pagination.nextCursor back as the cursor parameter while hasMore is true.
The @sawala/kontena-client SDK unwraps the top-level data into items and returns { items, pagination }, so SDK code reads items while raw fetch/curl must read data.
Error responses
Errors are flat { "error": "..." } objects.
| HTTP | Body | Cause |
|---|---|---|
400 | { "error": "<validation message>" } | Invalid parameter |
401 | { "error": "Unauthorized" } | Missing or invalid API key |
403 | { "error": "Forbidden" } / { "error": "Forbidden: ..." } | No access to the project, or a secret key sent with a browser Origin |
404 | { "error": "NOT_FOUND" } / { "error": "SCHEMA_NOT_FOUND" } | Entry, project, or schema doesn't exist |
SDK
import { createKontenaClient } from '@sawala/kontena-client';
const kontena = createKontenaClient({
baseUrl: 'https://api.sawala.cloud/public/kontena',
projectId: 'proj_xxx',
publicApiKey: 'pk_live_xxx',
});
const { items, pagination } = await kontena.listCollection('post', { locale: 'en', limit: 25 });See CLI and SDK for installation and the wider SDK surface.