REST API Reference
The Ycode public v1 API gives programmatic access to collections, items, forms, and submissions, plus visitor analytics on Ycode Cloud. Use it to build custom integrations, sync data from other systems, or power external applications.
Base URL
https://yoursite.ycode.website/ycode/api/v1Use your project’s own domain: its ycode.website subdomain or a custom domain on Ycode Cloud, or your server’s domain when self-hosting.
Authentication
Every request needs an API key in the Authorization header:
Authorization: Bearer YOUR_API_KEYGenerate keys in the builder under Integrations → Ycode API. See API keys for details.
Request Format
- Send request bodies as JSON with
Content-Type: application/json - All responses are JSON
Errors
Errors return an HTTP status code and a JSON body with a message and a code:
{
"error": "Item not found",
"code": "NOT_FOUND"
}| Status | Code | Meaning |
|---|---|---|
| 400 | INVALID_REQUEST | The request body or parameters are invalid |
| 401 | UNAUTHORIZED | The API key is missing or invalid |
| 403 | FORBIDDEN | The project is suspended (Ycode Cloud); only reads are allowed |
| 404 | NOT_FOUND | The collection, item, form, or submission does not exist |
| 500 | INTERNAL_ERROR | Something went wrong on the server |
Collections
| Method | Endpoint | Description |
|---|---|---|
| GET | /collections | List all collections |
| GET | /collections/:id | Get a collection and its fields |
| GET | /collections/:id/items | List items |
| GET | /collections/:id/items/:itemId | Get an item |
| POST | /collections/:id/items | Create an item |
| PUT | /collections/:id/items/:itemId | Replace an item |
| PATCH | /collections/:id/items/:itemId | Update some fields of an item |
| DELETE | /collections/:id/items/:itemId | Delete an item |
The API works with published collections and items: what visitors see on the live site. A collection or field that has never been published is not available yet.
Writes take effect on the live site immediately, with no publish step, and update the CMS in the builder at the same time. Pages that show the collection are refreshed automatically.
List Collections
GET /ycode/api/v1/collections{
"collections": [
{
"id": "5f0c…",
"displayName": "Blog Posts",
"singularName": "Blog Post",
"slug": "blog-posts"
}
]
}Get Collection
GET /ycode/api/v1/collections/:idReturns the collection with its fields. Use the field slug values as keys when filtering, sorting, and writing items. isRequired is true for fields you can write and false for fields Ycode sets automatically (ID, Created Date, Updated Date).
{
"id": "5f0c…",
"displayName": "Blog Posts",
"singularName": "Blog Post",
"slug": "blog-posts",
"fields": [
{ "id": "e5f6…", "displayName": "ID", "slug": "id", "type": "number", "isRequired": false },
{ "id": "a1b2…", "displayName": "Name", "slug": "name", "type": "text", "isRequired": true },
{ "id": "c3d4…", "displayName": "Read Time", "slug": "read-time", "type": "number", "isRequired": true }
]
}Item Format
Items are returned as flat objects keyed by field display name, plus an _id:
{
"_id": "f299…",
"ID": 3,
"Name": "Hello world",
"Slug": "hello-world",
"Created Date": "2026-11-09T08:44:25.257Z",
"Updated Date": "2026-11-09T08:44:28.355Z",
"Read Time": 4,
"Author": { "_id": "9a8b…", "Name": "Jane Doe" }
}_idis the item’s unique identifier. Use it in item URLs (:itemId) and as the value of reference fields.IDis the item’s sequential number in the collection.- Fields without a value are left out.
- Reference fields are expanded into the referenced item, and multi-reference fields into an array of items, up to 6 levels deep.
List Items
GET /ycode/api/v1/collections/:id/items| Parameter | Description |
|---|---|
page | Page number. Default 1 |
per_page | Items per page. Default 100, max 1000 |
limit | Return at most this many items (max 1000), instead of per_page |
sort_by | Field slug to sort by |
order_by | asc (default) or desc, used with sort_by |
filter[field_slug] | Only return items whose field exactly equals this value. Repeat for several fields |
fields[Collection Name] | Comma-separated display names of the fields to return. Use fields[Collection Name.Reference Field] to limit the fields of expanded references |
Field slugs are matched case-insensitively. Unknown slugs in sort_by and filter are ignored.
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://yoursite.ycode.website/ycode/api/v1/collections/:id/items?sort_by=read-time&order_by=desc&filter[category]=news&per_page=50"{
"items": [
{ "_id": "f299…", "ID": 3, "Name": "Hello world", "Slug": "hello-world" }
],
"pagination": {
"page": 1,
"per_page": 50,
"total": 12
}
}Get Item
GET /ycode/api/v1/collections/:id/items/:itemIdReturns one item in the item format. Deleted items return 404.
Writing Field Values
POST, PUT, and PATCH take a JSON object with field values directly at the top level (no wrapper):
{
"name": "Hello world",
"slug": "hello-world",
"read-time": 4
}- Use each field’s
slugfrom Get Collection as the key; matching is case-insensitive. - Keys that don’t match a field are ignored without an error, so check the slug if a value doesn’t change.
- Values are stored as text. Numbers and booleans can be sent as JSON values or strings.
- For a reference field, send the referenced item’s
_id. For a multi-reference field, send a JSON-encoded array of_idvalues as a string, for example"[\"9a8b…\",\"7c6d…\"]". ID,Created Date, andUpdated Dateare set automatically and can’t be written.Updated Dateis refreshed on every update.
Create Item
POST /ycode/api/v1/collections/:id/itemsCreates an item and publishes it immediately. Returns the new item with status 201.
curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Hello world", "slug": "hello-world", "read-time": 4}' \
"https://yoursite.ycode.website/ycode/api/v1/collections/:id/items"Update Item (Partial)
PATCH /ycode/api/v1/collections/:id/items/:itemIdUpdates only the fields in the request body and leaves every other field unchanged. This is the endpoint to use for recurring updates, such as refreshing a value every few minutes. Returns the updated item.
curl -X PATCH \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"temperature": "21.5"}' \
"https://yoursite.ycode.website/ycode/api/v1/collections/:id/items/:itemId"Replace Item
PUT /ycode/api/v1/collections/:id/items/:itemIdReplaces the item’s values. Every writable field that is not in the request body, including Name and Slug, is cleared. Use PATCH unless you mean to overwrite the whole item. Returns the updated item.
curl -X PUT \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Hello again", "slug": "hello-again", "read-time": 5}' \
"https://yoursite.ycode.website/ycode/api/v1/collections/:id/items/:itemId"Delete Item
DELETE /ycode/api/v1/collections/:id/items/:itemIdRemoves the item from the live site and the CMS.
curl -X DELETE \
-H "Authorization: Bearer YOUR_API_KEY" \
"https://yoursite.ycode.website/ycode/api/v1/collections/:id/items/:itemId"{
"deleted": true,
"_id": "f299…"
}Forms
| Method | Endpoint | Description |
|---|---|---|
| GET | /forms | List forms |
| GET | /forms/:formId | Get a form’s submission counts |
| GET | /forms/:formId/submissions | List submissions |
| POST | /forms/:formId/submissions | Create a submission |
| GET | /forms/:formId/submissions/:submissionId | Get a submission |
| PATCH | /forms/:formId/submissions/:submissionId | Change a submission’s status |
| DELETE | /forms/:formId/submissions/:submissionId | Delete a submission |
:formId is the form’s ID (for example contact-form), as returned by List Forms. Forms are listed from their submissions, so a form appears in the API once it has at least one.
Submission Format
{
"id": "8c7b…",
"formId": "contact-form",
"payload": { "name": "Jane", "email": "jane@example.com", "message": "Hello!" },
"metadata": { "source": "api", "user_agent": "curl/8.7.1" },
"status": "new",
"createdAt": "2026-11-09T08:45:25.497Z"
}status is one of new, read, archived, or spam.
List Forms
GET /ycode/api/v1/forms{
"forms": [
{
"id": "contact-form",
"submissionCount": 42,
"newCount": 5,
"latestSubmission": "2026-11-09T08:45:25.497Z"
}
]
}Get Form
GET /ycode/api/v1/forms/:formId{
"id": "contact-form",
"submissionCount": 42,
"statusCounts": { "new": 5, "read": 30, "archived": 7, "spam": 0 },
"latestSubmission": "2026-11-09T08:45:25.497Z"
}List Submissions
GET /ycode/api/v1/forms/:formId/submissions| Parameter | Description |
|---|---|
page | Page number. Default 1 |
per_page | Submissions per page. Default 50, max 100 |
status | Only return submissions with this status |
{
"submissions": [ { "id": "8c7b…", "formId": "contact-form", "payload": { … }, "status": "new", … } ],
"pagination": {
"page": 1,
"perPage": 50,
"total": 42
}
}Create Submission
POST /ycode/api/v1/forms/:formId/submissionsSend the submitted fields inside payload. metadata is optional; source: "api" and the request’s user agent are added to it automatically. Returns the new submission with status 201.
curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"payload": {"name": "Jane", "email": "jane@example.com", "message": "Hello!"}, "metadata": {"page_url": "/contact"}}' \
"https://yoursite.ycode.website/ycode/api/v1/forms/contact-form/submissions"Submissions created through the API are only stored: they don’t send email notifications, run apps, or trigger webhooks.
Get Submission
GET /ycode/api/v1/forms/:formId/submissions/:submissionIdReturns one submission in the submission format.
Update Submission Status
PATCH /ycode/api/v1/forms/:formId/submissions/:submissionIdcurl -X PATCH \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "read"}' \
"https://yoursite.ycode.website/ycode/api/v1/forms/contact-form/submissions/:submissionId"Only status can be changed. Returns the updated submission.
Delete Submission
DELETE /ycode/api/v1/forms/:formId/submissions/:submissionIdDeletes the submission and returns 204 No Content.
Analytics
Analytics is available on Ycode Cloud only. On self-hosted Ycode this endpoint returns 404.
| Method | Endpoint | Description |
|---|---|---|
| GET | /analytics | Visitor analytics for the published site |
GET /ycode/api/v1/analytics| Parameter | Description |
|---|---|
period | today, yesterday, 7d, 30d, 90d, or 12m. Defaults to 30d |
from, to | A custom range as YYYY-MM-DD, inclusive. Send both; they override period |
breakdowns | Comma-separated top-10 lists, up to 5. Defaults to page,referrer |
path | Only count views of this page path, for example /pricing |
Available breakdowns: page, entry_page, exit_page, referrer, utm_source, utm_medium, utm_campaign, country, device, browser, os, item (CMS items), and event (tracked clicks and form submissions).
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://yoursite.ycode.website/ycode/api/v1/analytics?period=7d&breakdowns=page,country"{
"from": "2026-11-05",
"to": "2026-11-11",
"timezone": "UTC",
"historyDays": 90,
"clamped": false,
"visitors": 1240,
"pageviews": 3815,
"visits": 1592,
"bounceRate": 0.42,
"avgVisitSeconds": 96,
"liveVisitors": 7,
"interval": "day",
"series": [
{ "start": "2026-11-05", "visitors": 168, "pageviews": 512 }
],
"breakdowns": [
{
"dimension": "page",
"rows": [
{ "label": "/", "visitors": 812, "total": 1430 }
]
}
]
}- Days are in UTC.
bounceRateis a share from 0 to 1.bounceRateandavgVisitSecondsarenullwhen there were no visits.liveVisitorscounts visitors in the last 5 minutes.intervalisday,week, ormonth, depending on the length of the range.- In breakdown rows,
totalis pageviews; visits forentry_pageandexit_page; and events forevent. - The range is shortened to the plan’s history window. When that happens,
clampedistrueandhistoryDaysshows the window.
Invalid parameters return 400 with code VALIDATION_ERROR.