Create transition

Moves one content item to a new lifecycle state and, on the move to published, fans it out to the item's channels.

POST /v1/content/{doctype}/{name}/transition

Addresshttps://api.hanzo.ai/v1/content/{doctype}/{name}/transition
MethodPOST
Operationpost_content_by_doctype_by_name_transition
AuthAuthorization: Bearer $HANZO_API_KEY

Moves one content item to a new lifecycle state and, on the move to published, fans it out to the item's channels. The edge must be legal for the item's current state — an illegal move is refused with 409 — and the status write re-validates it at the storage boundary. Distribution is best effort: its honest state is reported on the result and a distribution failure never rolls the status change back.

Request

6 fields, body application/json (required).

FieldInTypeRequiredDescription
doctypepathstringyesDocType is the content type to act on, from the path.
namepathstringyesName is the document to act on, from the path.
doctypebodystring—DocType is the content type to act on, from the path.
namebodystring—Name is the document to act on, from the path.
scheduleAtbodystring—ScheduleAt is an ISO-8601 go-live time handed to the channel's own scheduler; "" distributes now.
tobodystring—To is the lifecycle state to move to.

Response

StatusBodyMeaning
200content.TransitionResultok
defaultproblem-detailsrefused

200 body — 20 fields.

FieldInTypeAlwaysDescription
distributionbodycontent.PublishResult—
distribution.channelsbodystring[]—Channels is the channel list read off the content document — integration ids or provider names, as the item declares them.
distribution.externalIdsbodyobject—ExternalIDs maps channel id → the post id that channel returned, merged with everything earlier publishes recorded.
distribution.externalIds.*bodystring—
distribution.resultsbodycontent.ChannelResult[]—Results is the outcome per channel — which went out, which did not and why — covering the whole fan-out including failures, so partial success is never flattened into one verdict.
distribution.results[].channelbodystring—the social integration id targeted
distribution.results[].errorbodystring—short reason, when it failed
distribution.results[].externalIdbodystring—social post id, when it went out
distribution.results[].providerbodystring—"x" | "instagram" | ...
distribution.results[].statusbodystring—"distributed" | "scheduled" | "failed"
distribution.statusbodystring—Status is the ONE headline, drawn from: "distributed" (something is on record and went out now), "scheduled" (same, handed to the channel's own scheduler for later), "failed" (nothing is on record — this fan-out missed entirely and no earlier one landed), "in_progress" (another publisher holds the item, so this call posted NOTHING and the caller retries), and "not_configured" (no distribution edge is wired; a transition records it instead of failing).
doctypebodystring—DocType is the content type that moved — Campaign, SocialPost or Asset — echoed from the path.
frombodystring—From is the state the item held when it was read.
namebodystring—Name is the document that moved, echoed from the path.
storefrontbodycontent.StorefrontResult—
storefront.imageUrlbodystring—ImageURL is the absolute URL the listing's headerImage now points at.
storefront.slugbodystring—Slug is the product handle the image was attached to.
storefront.statusbodystring—Status is one of "published" (the product image was set), "not_configured" (no commerce edge, no store provisioned for the org, or a token that is not admin on the store — a fail-closed no-op) or "failed" (commerce answered and errored).
storefront.storebodystring—Store is the commerce store id the image landed in, resolved for the org mid-call.
tobodystring—To is the state it holds now.

Failure carries the platform error shape — see Errors.

Examples

hanzo content doctype transition <doctype> <name>
import { Configuration, ContentApi } from 'hanzoai';

const api = new ContentApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postContentByDoctypeByNameTransition({ doctype: 'doctype', name: 'name', doctype: "<doctype>", name: "<name>" });
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import ContentApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = ContentApi(client).post_content_by_doctype_by_name_transition(doctype='doctype', name='name', doctype="<doctype>", name="<name>")
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.ContentAPI.PostContentByDoctypeByNameTransition(context.Background()).Execute()
if err != nil {
	return err
}
use hanzo_client::apis::{configuration::Configuration, content_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = content_api::post_content_by_doctype_by_name_transition(&cfg, Default::default()).await?;
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.ContentApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new ContentApi(client).postContentByDoctypeByNameTransition();
curl -X POST https://api.hanzo.ai/v1/content/<doctype>/<name>/transition \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "doctype": "<doctype>",
       "name": "<name>"
     }'

MCP reaches content through the content tool, which names its 6 operations with its own verbs — this one among them, under a name only MCP declares. describe explains any of them:

curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "get_content_board"
         }
       }
     }'

Content API · All Hanzo APIs · Interactive reference

Was this page useful?