Skip to main content
Castro treats your HTTP status code as the truth. Get the codes right and the Castro user sees exactly what happened; get them wrong and a silent failure looks like a success.

Success responses

The id you return on create is permanent. Castro stores it verbatim and uses it in the path of every later call about that entity. Any string up to 191 characters works: a database id, a UUID, a slug. Just never change it.

List endpoints return a bare array

An { "items": [...] } wrapper is also accepted, but the bare array is the documented shape: prefer it.

Error responses

Any non-2xx response should carry a message:
That message is shown to the Castro user verbatim. Write it for a person, not a log file. "Post not found" is useful. "Error" is not.

What Castro does with each status

Every request and response, including your error body, is recorded in the integration logs, so a user can always see the raw exchange.
Never return 200 for a failure. If a post could not be saved, say so with a 4xx or 5xx. A 200 tells Castro the content is live on your site, and it will be treated that way, including in later updates that will then hit an id that doesn’t exist.

Idempotency

Every payload for the same piece of Castro content carries the same source_id. Use it to recognise a re-publish instead of creating a duplicate:
Store source_id on create and index it. Networks retry; users double-click.

The partial update rule

It’s worth stating once more, because it’s the rule that costs real content:
On every PUT, apply only the fields present in the body. A body that contains just { "content": "..." } must not blank out the title, categories, author or SEO.
Nested objects follow the same rule: merge seo, don’t replace it. The conformance script asserts this, and the troubleshooting guide shows the two-line fix.