> ## Documentation Index
> Fetch the complete documentation index at: https://docs.weelkit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manifest

> The bounded JSON document your API serves so Weelkit can discover its content types, capabilities, and endpoints.

The manifest is the single document Weelkit reads to learn what your destination supports. It is fetched over HTTPS, validated against the protocol allowlist and [limits](https://docs.weelkit.com/integrations/custom-api/schema-and-limits.md), and summarized into a schema fingerprint.

## Location

Weelkit fetches the manifest from your connection's **HTTPS base URL** joined with a **manifest path**:

* The default manifest path is `/.well-known/weelkit-publishing.json`.
* A custom path must be **same-origin** and start with `/`. Absolute URLs pointing elsewhere are rejected.

## Example

```json theme={null}
{
  "protocolVersion": "weelkit-custom-publishing.v2",
  "destination": { "id": "acme-site", "name": "Acme Site" },
  "capabilities": { "publish": true, "update": true, "delete": false, "readback": true, "list": true },
  "contentTypes": [ { "id": "article", "name": "Article", "capabilities": { "publish": true, "read": true }, "schema": { "fields": [
    { "path": "title", "type": "string", "required": true, "label": "Title" },
    { "path": "body", "type": "html", "required": true, "representation": "html" },
    { "path": "summary", "type": "text", "description": "Short summary shown in listings." },
    { "path": "topics", "type": "array<string>", "reference": { "targetContentTypeId": "topic", "cardinality": "multiple", "kind": "taxonomy" } },
    { "path": "tier", "type": "string", "options": [ { "label": "Free", "value": "free" }, { "label": "Pro", "value": "pro" } ] }
  ] } }, { "id": "topic", "name": "Topic", "capabilities": { "publish": false, "read": true }, "schema": { "fields": [
    { "path": "name", "type": "string", "required": true },
    { "path": "slug", "type": "string" }
  ] } } ],
  "endpoints": { "publish": "/weelkit/publish", "readback": "/weelkit/articles/{remoteId}", "list": "/weelkit/content/{contentTypeId}" },
  "statuses": { "draft": "draft", "published": "live" },
  "idempotency": { "supported": true }
}
```

## Schema reference

**protocolVersion** `string` *required*

Must be `weelkit-custom-publishing.v2`.

**destination** `object` *required*

Identity of your destination.

**destination properties**

**id** `string` *required*

Stable identifier for the destination.

**name** `string` *required*

Display name shown to administrators.

**capabilities** `object` *required*

What your destination supports. Weelkit only performs operations you declare.

**capabilities properties**

**publish** `boolean`

Your API accepts create dispatches at the publish endpoint.

**update** `boolean`

Your API accepts update dispatches for previously published content.

**delete** `boolean`

Your API supports deletion. Declare `false` if unsupported.

**readback** `boolean`

Your API can return an item's current state from the readback endpoint. Weelkit uses it to verify test drafts and to follow each item's status and public URL after it's sent. Without it, articles sent to your API never change status in Weelkit. See [Publishing](https://docs.weelkit.com/integrations/custom-api/publishing.md#status-and-readback).

**list** `boolean`

Your API can list bounded reference options for explicitly declared reference fields.

**contentTypes** `array` *required*

The content types Weelkit can publish into. An administrator selects one during setup.

**content type properties**

**id** `string` *required*

Stable identifier, echoed back as `contentTypeId` in publish requests.

**name** `string` *required*

Display name shown in the mapping review.

**capabilities** `object`

Per-type capabilities. Set `publish` for types an administrator may select as the primary destination and `read` for types your list endpoint can return.

**schema.fields** `array` *required*

The typed fields of this content type.

**field properties**

**path** `string` *required*

Dot-separated identifier path, e.g. `title` or `seo.metaTitle`. A dotted path is a nested object: Weelkit sends and reads `seo.metaTitle` as `{ "seo": { "metaTitle": "…" } }`. A path cannot also be the parent of another path. Limits in [Schema and limits](https://docs.weelkit.com/integrations/custom-api/schema-and-limits.md).

**type** `string` *required*

One of the allowlisted types: `string`, `text`, `html`, `number`, `boolean`, `date`, `url`, `array<string>`. HTML fields use the `html` or `canonical-html` representation and receive a sanitized semantic HTML fragment.

**required** `boolean`

Whether a value must be mapped before publishing. Defaults to `false`.

**writable** `boolean`

Set `false` for a field Weelkit may show but never writes, such as a computed score. Defaults to `true`.

**label** `string`

Display label, up to 120 characters. Treated as untrusted display text.

**description** `string`

Help text shown in the mapping review, up to 500 characters.

**options** `array`

Enumerated values for the field, each an object with a required `value` and an optional `label` (the `value` is shown when there is none). Up to 50 options, each text at most 200 characters, no repeated `value`.

**constraints** `object`

Limits on the value, checked by Weelkit before anything is sent, so a value outside them never reaches your API. `minLength` and `maxLength` on `string`, `text` and `url`; `minimum` and `maximum` on `number`; `minItems` and `maxItems` on `array<string>`. Lengths and item counts are whole numbers from 0 (1 for `maxLength`) to 10,000,000. A lower limit may not exceed its upper limit.

**reference** `object`

An explicit reference edge. Provide `targetContentTypeId`, `cardinality` (`single` or `multiple`), and a bounded `kind`. A multiple reference must use `array<string>`; a single reference must use `string`.

**endpoints** `object` *required*

Same-origin paths, each starting with `/`.

**endpoints properties**

**publish** `string` *required*

Path that receives create (`POST`) and update (`PUT`) dispatches. When you declare `capabilities.delete`, it also receives delete requests as a `POST` whose `operation` is `delete`, so route on `operation`. See [Publishing](https://docs.weelkit.com/integrations/custom-api/publishing.md#delete).

**readback** `string`

Path for readback, with a `{remoteId}` placeholder. Required only when `capabilities.readback` is `true`. Return every mapped field so it can be verified; see [Status and readback](https://docs.weelkit.com/integrations/custom-api/publishing.md#status-and-readback).

**list** `string`

Path containing `{contentTypeId}` that returns reference options, paged by `offset` and `limit`. Required only when `capabilities.list` is `true`. See [List endpoint](https://docs.weelkit.com/integrations/custom-api/publishing.md#list-endpoint).

**statuses** `object`

Maps Weelkit's status vocabulary onto yours. Weelkit sends your value in the publish request's `status` field, and recognizes it when it reads an item back, without regard to case. When omitted, the values are `draft` and `published`. Values are 1 to 32 letters, digits, `-`, `_` or `.`, and the two must differ. A value outside that alphabet rejects the manifest; it is never replaced by a default.

**statuses properties**

**draft** `string`

Your value for draft content, e.g. `draft`.

**published** `string`

Your value for live content, e.g. `live`.

**idempotency** `object`

**idempotency properties**

**supported** `boolean`

When `true`, Weelkit sends an `Idempotency-Key` header carrying the operation identity with every mutation, and you must deduplicate by it. See [Publishing](https://docs.weelkit.com/integrations/custom-api/publishing.md#idempotency-and-retries).

## Images, limits and nested fields

Images travel as URLs, so a cover image is a `url` field and its alt text is a `string` field beside it. See [Publishing](https://docs.weelkit.com/integrations/custom-api/publishing.md#images).

```json theme={null}
[
  { "path": "title", "type": "string", "required": true, "constraints": { "maxLength": 60 } },
  { "path": "heroImageUrl", "type": "url", "label": "Hero image" },
  { "path": "heroImageAlt", "type": "string", "label": "Hero image alt text", "constraints": { "maxLength": 125 } },
  { "path": "seo.metaTitle", "type": "string", "constraints": { "maxLength": 60 } },
  { "path": "seo.metaDescription", "type": "text", "constraints": { "maxLength": 160 } },
  { "path": "readMinutes", "type": "number", "constraints": { "minimum": 1, "maximum": 120 } },
  { "path": "internalNote", "type": "string", "writable": false }
]
```

## Strict reading

Weelkit reads the manifest exactly or not at all. Text beyond its bound, an option without a value, a repeated option value, a status word outside the allowed alphabet, a limit that is not a number, or a flag that is not `true` or `false` rejects the manifest with a message naming the field. Nothing is shortened, skipped or replaced by a default.

## After discovery

An administrator selects one publishable content type as the primary destination. Weelkit does **not** treat every other content type as a reference. It fetches records only for types targeted by a `reference` declaration on a field in the selected primary type. The target type must declare `read: true`.

Weelkit computes a schema fingerprint over the manifest's normalized structure and pins the saved mapping to it. If you change the manifest later, the fingerprint changes and publishing pauses for a mapping review — see [Schema and limits](https://docs.weelkit.com/integrations/custom-api/schema-and-limits.md#schema-fingerprint-and-drift).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.