Upsert markdown by a stable UID whenever the source data changes. The UID is yours, so re-pushing the same document updates it rather than adding a duplicate, and re-pushing unchanged content costs nothing.

```bash
curl -X PUT "https://context-link.ai/api/v1/custom_connections/$CONN_ID/posts/funnel-report-2026-08" \
  -H "Authorization: Bearer $ACME_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "title": "August funnel report", "body": "## Conversion...\n..." }'
```

```json
{
  "status": "created",
  "post": {
    "uid": "funnel-report-2026-08",
    "title": "August funnel report",
    "chunk_count": 7,
    "will_index": true,
    "created_at": "2026-08-31T10:20:11Z",
    "updated_at": "2026-08-31T10:20:11Z"
  }
}
```

## Request fields

| Field | Type | Description |
|---|---|---|
| `connection_id` | integer | Required, in the path. The `CONN_ID` returned when you [created the connection](/docs/white-label/create-connection). |
| `uid` | string | Required, in the path. Your own stable id for the document, 1 to 255 characters of `a-z`, `0-9`, hyphen, underscore or dot. Re-using it updates that document rather than adding another. |
| `title` | string | Required. The document's title, up to 255 characters. |
| `body` | string | Required. The document as markdown, up to 100KB. An empty body is a `422`: delete the post instead. |

## Response fields

| Field | Type | Description |
|---|---|---|
| `status` | string | What the upsert did: `created`, `updated`, or `unchanged` when the content matched what was already indexed. |
| `post` | object | The post as it now stands. |
| `post.uid` | string | The stable UID you addressed the post with. |
| `post.title` | string | The title you sent with this upsert. |
| `post.chunk_count` | integer | Embedded passages the body was split into. |
| `post.will_index` | boolean | Whether the post is included in the index; an excluded post is a `409` rather than an upsert. |
| `post.created_at` | timestamp | When the post was first pushed. |
| `post.updated_at` | timestamp | When the post was last written. |

A `201` means the post was created; an existing uid answers `200` with `status` of `updated`, or `unchanged` when the content already matched.

## No polling step

Chunking and embedding happen inside the request, so once you have a `201` that content is already searchable by [`/context`](/docs/white-label/query-customer) and [`/question`](/docs/white-label/ask-question).

For small ad-hoc notes you want back word for word rather than retrieved by meaning, use a [namespace](/docs/white-label/namespaces) instead of a document.

## Quotas

Standard custom-connection quotas apply: 1,000 posts and 100MB per connection, 100KB per post body, up to 6 custom connections per API account.
