edit.pink
Pink Editor docs

Payloads

The article, question and notify payloads, field by field.

All bodies are JSON (application/json; charset=utf-8). Ignore fields you don't know; never reject a payload for having them.

Article

POST {publish_url}/articles

FieldTypeRequiredNotes
slugstringyesThe upsert key. One lowercase segment, see Slugs.
titlestringyesDisplay title
bodyarray of blocksyesThe page, structured
excerptstring or nullShort summary for cards and as a meta description fallback
copystring or nullThe page's markdown source. Store it as is; Pink reads it back through the GET endpoint. It may contain internal-link markers such as [text](page:12), so never render it to visitors: render body.
keywordsarray of stringFree-form keywords
meta_titlestringDefaults to title
meta_descriptionstring or nullDefaults to excerpt
audiencestring or array of stringThe audience the page is written for
goalstring or nullThe page's goal, e.g. "convert" or "educate"
categorystring or nullOne category tag
cover_imagestring (URL) or nullHero image
canonical_urlstring or nullAbsolute canonical URL
noindexbooleanDefault false
schema_typestringSchema.org type, default "Article"
related_article_idsarray of stringYour ids of related articles
related_question_idsarray of stringYour ids of related questions
status"draft" or "published"What Pink asks for. Store it, and report what you stored.
ai_generatedbooleanDefault true
ai_modelstring or nullThe model that wrote the prose
updated_atstring (ISO 8601)Defaults to your now()
site_idintegerIf present, must match the site your key belongs to, otherwise 403 site_mismatch
{
  "slug": "best-time-to-visit-lisbon",
  "title": "The Best Time to Visit Lisbon",
  "excerpt": "May, June and September give you warm days without August's crowds.",
  "audience": ["first-time-visitor"],
  "goal": "educate",
  "keywords": ["lisbon weather by month", "when to visit lisbon"],
  "meta_title": "When to Visit Lisbon: A Month-by-Month Guide",
  "body": [
    { "_type": "heading", "level": 2, "text": "Spring is the sweet spot" },
    { "_type": "paragraph", "text": "From April to June the city is warm, green and not yet crowded." },
    {
      "_type": "statBar",
      "stats": [
        { "value": "24 °C", "label": "Average high, June" },
        { "value": "14 hrs", "label": "June daylight" }
      ]
    }
  ],
  "copy": "## Spring is the sweet spot\n\nFrom April to June the city is warm, green and not yet crowded.\n…",
  "status": "published"
}

Question

POST {publish_url}/questions: one Q&A page.

FieldTypeRequiredNotes
slugstringyesThe upsert key, derived from the question text
questionstringyesThe question as displayed
answerarray of blocksyesThe answer, structured
sourcesarray of source objects[{ "id": "src-1", "title": "…", "url": "https://…", "accessed_at": "2026-05-19" }]
topicsarray of stringTopic tags
meta_titlestringDefaults to question
meta_descriptionstring or null
related_question_idsarray of string
related_article_idsarray of string
status"draft" or "published"Defaults to "published"
ai_modelstring or null
updated_atstring (ISO 8601)
site_idintegerSame check as for articles

Citations. Only answers carry sources. A citation in an answer (a sourceCitation inline node, or a literal [src-2] in a list item) renders only when sources has an entry with that id; otherwise drop the marker and the space before it. Articles never have sources, so render no citation markers in an article.

Answers sites. If your site keeps several answers per question (votes, community replies), store Pink's answer as one answer, replaced whole on each publish, with its sources. Pink never writes the question page's summary.

Notify (your site → Pink)

POST https://app.edit.pink/api/content/notify, with the same X-API-Key Pink sends you.

Call it whenever a page Pink published changes on your site: an edit, a status change, a delete. Pink uses it to stop linking other pages to a page readers can no longer reach.

FieldTypeRequiredNotes
idstringyesYour id for the page, as you returned it at publish
type"article" or "question"yes
status"published" or "draft"The state you now store. Send it whenever you know it: Pink trusts it over action.
action"edited", "published", "unpublished" or "deleted"What happened. deleted counts as unpublished.
slugstring
updated_atstring (ISO 8601)

With neither status nor action, Pink assumes the page is still live.

Response:

{ "ok": true, "matched": true, "relink": "queued" }

matched: false means Pink has no page with that id, which is normal for pages Pink never published. relink says whether Pink started updating the links that point at the page: "queued" when its published state changed, "skipped" otherwise (the usual answer to an edited call). You don't need to read it.

On this page