Temso Docs
Publishing

Webhook

The contract v1 payload Temso sends when an article publishes, and how to confirm it back.

Point Temso at any HTTPS endpoint and it POSTs the finished article there when it publishes. This is what the Zapier app uses under the hood, and it's how you'd wire up Make or your own service.

Connect one under Settings → Integrations → Webhook in the Temso app.

The delivery

Temso sends a POST with content-type: application/json. Any 2xx response means you accepted it, and the publication is marked succeeded. A non-2xx is retried after 5 minutes, then 15 minutes, then an hour.

{
  "contractVersion": "v1",
  "publicationId": "6a4d1670485f7083447bf344",
  "pieceId": "6a4d166f485f7083447bf342",
  "callbackUrl": "https://api.temso.ai/v1/integrations/publish-callback?token=...",
  "title": "The article title",
  "slug": "the-article-title",
  "html": "<h1>The article title</h1><p>Body copy.</p>",
  "markdown": "# The article title\n\nBody copy.",
  "targetState": "published",
  "seo": {
    "metaTitle": "The article title",
    "metaDescription": "A short summary.",
    "canonicalUrl": "https://example.com/blog/the-article-title",
    "robots": "index,follow",
    "openGraph": {
      "title": "The article title",
      "description": "A short summary.",
      "imageUrl": "https://storage.googleapis.com/.../og.webp"
    },
    "twitter": {
      "card": "summary_large_image",
      "title": "The article title",
      "description": "A short summary.",
      "imageUrl": "https://storage.googleapis.com/.../twitter.webp"
    }
  },
  "featuredImage": {
    "url": "https://storage.googleapis.com/.../featured.webp",
    "alt": "Alt text for the image"
  },
  "scheduledAt": 1784482973000,
  "scheduledTimezone": "Europe/Madrid"
}

Fields

FieldTypeNotes
contractVersionstringAlways "v1". Branch on this if the payload ever changes.
publicationIdstringStable id for this publication. Echo it back when confirming.
pieceIdstringThe Temso content piece the article came from.
callbackUrlstringWhere to confirm the result. Carries its own token, so no auth headers needed.
titlestringArticle title.
slugstringURL-safe handle.
htmlstringBody as HTML, ready to publish.
markdownstringSame body as Markdown.
targetStatestring"draft" or "published" — what the article should be at your end.
seoobjectMeta tags, canonical, robots, Open Graph and Twitter cards. All fields optional.
featuredImageobjectOptional. url plus optional alt. Images are served from Temso storage.
scheduledAtnumberOptional. Epoch milliseconds, present for scheduled publishes.
scheduledTimezonestringOptional. IANA timezone the schedule was set in.
externalIdstringOptional. Present when updating a post Temso published before.

Treat unknown fields as additive: new ones can appear within v1 without warning, so don't reject a payload for having extra keys.

Confirming the result (optional)

Publishing already succeeds on delivery. Confirming just records the live URL and your post's id against the article in Temso.

POST to the callbackUrl from the payload — the token is already in the URL:

curl -X POST "$CALLBACK_URL" \
  -H 'content-type: application/json' \
  -d '{
    "idempotencyKey": "cms-post-42",
    "remoteState": "published",
    "externalId": "cms-post-42",
    "externalUrl": "https://example.com/blog/the-article-title"
  }'
FieldRequiredNotes
idempotencyKeyyesStable id for this confirmation — your post id works well. Repeating the same key is a no-op.
remoteStateyes"draft" or "published" — what you actually created.
externalIdnoYour CMS's id for the post.
externalUrlnoThe public URL. Recorded on the article.

A success looks like:

{
  "ok": true,
  "publicationId": "6a4d1670485f7083447bf344",
  "operationState": "succeeded",
  "remoteState": "published"
}

Re-sending a different idempotencyKey for a publication that was already confirmed returns 409.

Notes

  • The endpoint must be HTTPS and reachable from the public internet.
  • A project publishes to one destination at a time.
  • Respond quickly. Do the slow work after you've accepted the payload.

On this page