# Create transition

URL: https://docs.hanzo.ai/docs/openapi/content/post-content-by-doctype-by-name-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`

> [Content →](https://docs.hanzo.ai/docs/openapi/content) · [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|               |                                                               |
| ------------- | ------------------------------------------------------------- |
| **Address**   | `https://api.hanzo.ai/v1/content/{doctype}/{name}/transition` |
| **Method**    | `POST`                                                        |
| **Operation** | `post_content_by_doctype_by_name_transition`                  |
| **Auth**      | `Authorization: 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).

| Field        | In   | Type   | Required | Description                                                                                       |
| ------------ | ---- | ------ | -------- | ------------------------------------------------------------------------------------------------- |
| `doctype`    | path | string | yes      | DocType is the content type to act on, from the path.                                             |
| `name`       | path | string | yes      | Name is the document to act on, from the path.                                                    |
| `doctype`    | body | string | —        | DocType is the content type to act on, from the path.                                             |
| `name`       | body | string | —        | Name is the document to act on, from the path.                                                    |
| `scheduleAt` | body | string | —        | ScheduleAt is an ISO-8601 go-live time handed to the channel's own scheduler; "" distributes now. |
| `to`         | body | string | —        | To is the lifecycle state to move to.                                                             |

## Response

| Status    | Body                     | Meaning |
| --------- | ------------------------ | ------- |
| `200`     | content.TransitionResult | ok      |
| `default` | problem-details          | refused |

`200` body — 20 fields.

| Field                               | In   | Type                     | Always | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ----------------------------------- | ---- | ------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `distribution`                      | body | content.PublishResult    | —      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `distribution.channels`             | body | string\[]                | —      | Channels is the channel list read off the content document — integration ids or provider names, as the item declares them.                                                                                                                                                                                                                                                                                                                                                |
| `distribution.externalIds`          | body | object                   | —      | ExternalIDs maps channel id → the post id that channel returned, merged with everything earlier publishes recorded.                                                                                                                                                                                                                                                                                                                                                       |
| `distribution.externalIds.*`        | body | string                   | —      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `distribution.results`              | body | content.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[].channel`    | body | string                   | —      | the social integration id targeted                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `distribution.results[].error`      | body | string                   | —      | short reason, when it failed                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `distribution.results[].externalId` | body | string                   | —      | social post id, when it went out                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `distribution.results[].provider`   | body | string                   | —      | "x" \| "instagram" \| ...                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `distribution.results[].status`     | body | string                   | —      | "distributed" \| "scheduled" \| "failed"                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `distribution.status`               | body | string                   | —      | 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). |
| `doctype`                           | body | string                   | —      | DocType is the content type that moved — Campaign, SocialPost or Asset — echoed from the path.                                                                                                                                                                                                                                                                                                                                                                            |
| `from`                              | body | string                   | —      | From is the state the item held when it was read.                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `name`                              | body | string                   | —      | Name is the document that moved, echoed from the path.                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `storefront`                        | body | content.StorefrontResult | —      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `storefront.imageUrl`               | body | string                   | —      | ImageURL is the absolute URL the listing's headerImage now points at.                                                                                                                                                                                                                                                                                                                                                                                                     |
| `storefront.slug`                   | body | string                   | —      | Slug is the product handle the image was attached to.                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `storefront.status`                 | body | string                   | —      | 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.store`                  | body | string                   | —      | Store is the commerce store id the image landed in, resolved for the org mid-call.                                                                                                                                                                                                                                                                                                                                                                                        |
| `to`                                | body | string                   | —      | To is the state it holds now.                                                                                                                                                                                                                                                                                                                                                                                                                                             |

Failure carries the platform error shape — see [Errors](https://docs.hanzo.ai/docs/errors).

## Examples

**CLI**

```bash
hanzo content doctype transition <doctype> <name>
```

**SDK**

**.ts**

```ts
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>" });
```

**.py**

```python
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>")
```

**.go**

```go
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
}
```

**.rs**

```rust
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?;
```

**.java**

```java
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();
```

**HTTP**

```bash
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**

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:

```bash
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](https://docs.hanzo.ai/docs/openapi/content) · [All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
