# Read and edit

One call reads any post, one call edits it, whatever its format.

`GET /posts/:id` reads any of the six formats and `PATCH /posts/:id` edits it. You do not need to know the format beforehand: the answer tells you, in `format`, and puts what belongs to that format in `content`.

| `format` | What `content` carries | What you can change |
| --- | --- | --- |
| `carousel` | `slides`: each slide's id, layout and text fields | The caption, plus the slide endpoints |
| `caption_reel` | The three text blocks, font, alignment, colors, sizes, clip and track | The caption and `reel` |
| `animated_audio` | `script`, `hook`, `speed` and the illustrated `scenes` | The caption and `narration` |
| `narrated_photos` | `script`, `hook`, `speed` and the photo `scenes` | The caption and `narration` |
| `premium_carousel` | `slides`: six AI-drawn pages | The caption, plus `POST /slides/:id/reimagine` |
| `infographic` | `slides`: one AI-drawn piece | The caption, plus `POST /slides/:id/reimagine` |

> `content` comes back `null` while the post is still generating. That is a real state, not an error: the post exists and its content does not exist yet. Read `status`.

## Reading

## Read a post you just created

The same two calls work for every format. Nothing here branches on what you made.

### 1. Read it. `format` tells you what it is.

```bash
curl -H "Authorization: Bearer $POSTTAR_KEY" "https://api.posttar.com/v1/posts/b713e349-..."
```

```json
{
  "id": "b713e349-...",
  "format": "caption_reel",
  "status": "draft",
  "projectId": "c85848ba-...",
  "textContent": "Your niche is not the topic you like...",
  "mediaUrls": [{ "url": "https://.../out.mp4", "type": "video" }],
  "content": {
    "blocks": ["Your niche is not the topic you like", "it is the problem you can solve again", "Answer the 3 questions in the caption"],
    "frames": [0, 60, 150],
    "font": "Inter",
    "alignment": "center",
    "boxStyle": "rounded"
  }
}
```

## Editing

`caption` works on all six. `reel` only on `caption_reel`, `narration` only on the two narrated ones. Sending the wrong one is refused with the field's name in the message, never ignored: ignoring it would let you believe you had saved.

Change the caption and the reel's hook in one call.

```bash
curl -X PATCH -H "Authorization: Bearer $POSTTAR_KEY" -H "Content-Type: application/json" \
  -d '{"caption":"the new caption",
       "reel":{"block1":"A sharper hook"}}' \
  "https://api.posttar.com/v1/posts/b713e349-..."
```

Change a narrated script. It does NOT re-record the audio: the video keeps the voice that is already there, and the post is flagged as having stale media.

```bash
curl -X PATCH -H "Authorization: Bearer $POSTTAR_KEY" -H "Content-Type: application/json" \
  -d '{"narration":{"script":"[calm] Look at this. [break] Three things change."}}' \
  "https://api.posttar.com/v1/posts/8c64bee5-..."
```

> A scene is `{ start, end, type, fields }`, and each `type` only accepts the fields it draws. Read the current ones in `content.scenes` and send the list back complete: it replaces, it does not merge. The [Reference](/docs/api/reference/posts) lists all thirteen types.

## The reel's clip and track

The background clip and the music are their own catalogs, so they have their own endpoints: `GET /posts/:id/clips` and `GET /posts/:id/tracks` list what this post can use, and `POST /posts/:id/clip` and `POST /posts/:id/track` pick one. They only apply to `caption_reel`.

`startSeconds` is optional, and `trackId: null` mutes the reel.

```bash
curl -X POST -H "Authorization: Bearer $POSTTAR_KEY" -H "Content-Type: application/json" \
  -d '{"trackId":"94917ea8-...","startSeconds":19}' \
  "https://api.posttar.com/v1/posts/b713e349-.../track"
```
