Update knowledge document
Updates a document’s title, description, body, or writing-style attachment. Body edits are saved immediately but do not re-trigger chunking or embedding on their own — call Resync knowledge document afterward to apply them to retrieval.
Rejected for PDF documents except title and user_description — their text is model-extracted,
not directly editable.
Requires the write:knowledge_base scope, and the workspace must be enabled for API writes.
PATCH /v1/brands/{brand_id}/knowledge-documents/{document_id}Authorization
| Header | Type | Required |
|---|---|---|
Authorization | Bearer asky_sk_… | required |
Idempotency-Key | string | required |
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
brand_id | uuid | required | From List brands |
document_id | uuid | required | From List knowledge documents |
Body
application/json
| Field | Type | Required | Description |
|---|---|---|---|
title | string, 1-200 chars | optional | |
user_description | string, up to 2000 chars, nullable | optional | null (or an empty string) clears it |
body_html | string | optional | Rich HTML body. Rejected for PDF documents |
writing_style_id | uuid, nullable | optional | Attach as a writing-style reference document instead of general brand knowledge. null detaches it |
At least one of these fields must be present. Sending none of them returns 400 invalid_request.
Request
cURL
curl --request PATCH \
--url 'https://api.askylabs.com/v1/brands/242546de-4cee-4a7d-952e-f6aa60c63ef8/knowledge-documents/b4f7e2a1-9c3d-4e6f-8a1b-2c5d7e9f0a3b' \
--header 'Authorization: Bearer <api-key>' \
--header 'Idempotency-Key: 5b0e77d2-13a9-4f6a-8ce1-9a3f5e21c0aa' \
--header 'Content-Type: application/json' \
--data '{"title": "Product Positioning FAQ (updated)", "body_html": "<h2>What makes us different?</h2><p>Asky tracks AI search visibility across ChatGPT, Perplexity and Google AI Overviews...</p>"}'Response
200
{
"data": {
"document": {
"id": "b4f7e2a1-9c3d-4e6f-8a1b-2c5d7e9f0a3b",
"brand_id": "242546de-4cee-4a7d-952e-f6aa60c63ef8",
"title": "Product Positioning FAQ (updated)",
"user_description": "Internal FAQ used to ground content about our differentiation.",
"source_type": "paste",
"raw_text": "## What makes us different?\n\nAsky tracks AI search visibility across ChatGPT, Perplexity and Google AI Overviews...",
"body_html": "<h2>What makes us different?</h2><p>Asky tracks AI search visibility across ChatGPT, Perplexity and Google AI Overviews...</p>",
"status": "ready",
"error_message": null,
"char_count": 5104,
"chunk_count": 6,
"token_count": 1180,
"needs_reembed": true,
"file_name": null,
"page_count": null,
"file_size_bytes": null,
"mime_type": null,
"material_type": null,
"writing_style_id": null,
"style_prompt_dismissed": false,
"created_by": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"created_at": "2026-08-18T11:02:04.000Z",
"updated_at": "2026-08-27T16:41:09.000Z"
}
},
"request_id": "req_a58f21c0aa47b1490d2e"
}Response fields
The full document, in the same shape Get knowledge document returns.
| Field | Type | Description |
|---|---|---|
data.document.id | uuid | required |
data.document.brand_id | uuid | required |
data.document.title | string | required |
data.document.user_description | string | null | required |
data.document.source_type | string | required. One of paste, pdf, mcp |
data.document.raw_text | string | null | required |
data.document.body_html | string | null | required |
data.document.status | string | required. One of processing, ready, failed — unchanged by this call |
data.document.error_message | string | null | required |
data.document.char_count | integer | required |
data.document.chunk_count | integer | required. Not recomputed here — see Notes |
data.document.token_count | integer | required. Not recomputed here — see Notes |
data.document.needs_reembed | boolean | required. true when a real body_html edit was applied and retrieval is now stale |
data.document.file_name | string | null | PDF-sourced documents only |
data.document.page_count | integer | null | PDF-sourced documents only |
data.document.file_size_bytes | integer | null | PDF-sourced documents only |
data.document.mime_type | string | null | PDF-sourced documents only |
data.document.material_type | string | null | Optional user-assigned classification of the source material |
data.document.writing_style_id | uuid | null | Set when this document belongs to a writing style rather than general brand knowledge |
data.document.style_prompt_dismissed | boolean | required |
data.document.created_by | uuid | required |
data.document.created_at / data.document.updated_at | timestamptz | required |
request_id | string | required. Also returned as the x-request-id header. Quote it when contacting support |
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_request | Unknown field, none of the four fields given, a body_html edit sent for a PDF document, the derived body over 1,000,000 characters, or a writing_style_id that doesn’t exist, belongs to another brand, or is already at its per-style document cap |
| 401 | invalid_token | The key is missing, malformed, or does not exist |
| 401 | token_expired | The key passed its expiry date |
| 401 | token_revoked | The key was revoked |
| 403 | insufficient_scope | The key does not carry write:knowledge_base |
| 403 | plan_required | This workspace is not enabled for API writes |
| 403 | quota_exceeded | The body_html edit would push the workspace over its 50MB knowledge base storage limit |
| 404 | not_found | The brand does not exist, this key is not allowed to reach it, or document_id does not belong to this brand |
| 429 | rate_limited | Over 60 requests per minute |
Notes
A body_html edit does not re-embed on its own. It is saved immediately and needs_reembed
flips to true, but chunking and embedding only run when you call
Resync knowledge document afterward. chunk_count and
token_count stay at their pre-edit values in the meantime.
PDF documents can only have title or user_description updated. Their raw_text is
model-extracted from the file, not user-authored, so a body_html field in the request returns
400 invalid_request for a PDF document — update the title or description instead.
A cosmetic-only HTML change is not treated as an edit. If the derived markdown normalizes to
exactly what is already stored — same content, different markup — raw_text, char_count and
needs_reembed are all left untouched, and it does not count against your 50MB storage cap.
A user_description change can silently re-trigger an AI summary in the background. If the
document’s status is already ready, changing user_description queues a summary_only ingest
pass that regenerates its AI summary — not a full re-embed, since chunks are usage-agnostic and
don’t need one. This is fire-and-forget: it does not affect this call’s response, and a dispatch
failure does not undo the update you already received.
Idempotency-Key is required. See Idempotency.