curl -X POST 'https://api.anyformat.ai/v3/workflows/0686bb97-8c30-70f0-8000-97669e000eb8/knowledge/ask' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"question": "Which contracts renew before March and what notice do they need?"}'
from anyformat.sdk import Client
client = Client(api_key="YOUR_API_KEY")
answer = client.ask(
"0686bb97-8c30-70f0-8000-97669e000eb8",
"Which contracts renew before March and what notice do they need?",
)
print(answer)
for citation in answer.citations:
print(f" {citation.path} p.{citation.page}: {citation.quote}")
const response = await fetch(
'https://api.anyformat.ai/v3/workflows/0686bb97-8c30-70f0-8000-97669e000eb8/knowledge/ask',
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
question: 'Which contracts renew before March and what notice do they need?',
}),
},
);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const { answer, citations } = await response.json();
console.log(answer);
{
"answer": "Two contracts renew before March. Meridian MSA renews 2026-02-01 and needs ninety days' notice to terminate. Aldrete supply agreement renews 2026-02-14 with thirty days' notice.",
"citations": [
{
"path": "2026-07/meridian-msa-2024.md",
"quote": "Either Party may terminate upon ninety (90) days' notice.",
"file_id": "0192f0c1-a2b3-4c5d-8000-abcdef012345",
"block_id": "block-2",
"page": 2,
"bbox": { "x0": 0.08, "y0": 0.31, "x1": 0.92, "y1": 0.36 }
}
],
"path": [
{ "tool": "kb_grep", "args": { "pattern": "renewal" } },
{ "tool": "kb_read", "args": { "path": "2026-07/meridian-msa-2024.md" } }
],
"steps_used": 2,
"thread_id": null
}
{
"error": "The knowledge base is not enabled.",
"error_code": "KNOWLEDGE_NOT_ENABLED",
"retryable": false,
"request_id": "a1b2c3d4e5f67890abcdef1234567890"
}
{
"error": "The organization has no extraction credit left.",
"error_code": "INSUFFICIENT_CREDIT",
"retryable": false,
"request_id": "a1b2c3d4e5f67890abcdef1234567890"
}
Knowledge
Ask
Answer a question from the content of a workflow’s documents, with citations
POST
/
v3
/
workflows
/
{workflow_id}
/
knowledge
/
ask
curl -X POST 'https://api.anyformat.ai/v3/workflows/0686bb97-8c30-70f0-8000-97669e000eb8/knowledge/ask' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"question": "Which contracts renew before March and what notice do they need?"}'
from anyformat.sdk import Client
client = Client(api_key="YOUR_API_KEY")
answer = client.ask(
"0686bb97-8c30-70f0-8000-97669e000eb8",
"Which contracts renew before March and what notice do they need?",
)
print(answer)
for citation in answer.citations:
print(f" {citation.path} p.{citation.page}: {citation.quote}")
const response = await fetch(
'https://api.anyformat.ai/v3/workflows/0686bb97-8c30-70f0-8000-97669e000eb8/knowledge/ask',
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
question: 'Which contracts renew before March and what notice do they need?',
}),
},
);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const { answer, citations } = await response.json();
console.log(answer);
{
"answer": "Two contracts renew before March. Meridian MSA renews 2026-02-01 and needs ninety days' notice to terminate. Aldrete supply agreement renews 2026-02-14 with thirty days' notice.",
"citations": [
{
"path": "2026-07/meridian-msa-2024.md",
"quote": "Either Party may terminate upon ninety (90) days' notice.",
"file_id": "0192f0c1-a2b3-4c5d-8000-abcdef012345",
"block_id": "block-2",
"page": 2,
"bbox": { "x0": 0.08, "y0": 0.31, "x1": 0.92, "y1": 0.36 }
}
],
"path": [
{ "tool": "kb_grep", "args": { "pattern": "renewal" } },
{ "tool": "kb_read", "args": { "path": "2026-07/meridian-msa-2024.md" } }
],
"steps_used": 2,
"thread_id": null
}
{
"error": "The knowledge base is not enabled.",
"error_code": "KNOWLEDGE_NOT_ENABLED",
"retryable": false,
"request_id": "a1b2c3d4e5f67890abcdef1234567890"
}
{
"error": "The organization has no extraction credit left.",
"error_code": "INSUFFICIENT_CREDIT",
"retryable": false,
"request_id": "a1b2c3d4e5f67890abcdef1234567890"
}
Rate limit tier: submission, 60 requests/min. See Rate limits.
Answers a question about what a workflow’s documents say: contract terms, invoice details, anything that needs reading rather than a field lookup. Extraction answers “what is in this document”. This endpoint answers “what do these documents say about X”, across the workflow’s current corpus.
Every answer carries the exact quotes it rests on. Each quote resolves to a page and a region in the source PDF, so you can show a customer where a number came from.
Requires a knowledge base
The workflow needs a knowledge node. Without one, the endpoint returns409 KNOWLEDGE_NOT_ENABLED. Add the node in Studio, or include it when you create the workflow.
Adding the node makes subsequent completed runs eligible for ingestion. It does not backfill documents that completed earlier. A member starts Index existing documents or Retry indexing from the workflow’s Knowledge tab when needed. A pack that already exists keeps serving while a later upload is re-indexed in the background, so there is no manual “update” action to trigger. These app actions are not public REST or MCP operations.
The corpus is workflow-scoped, not version-scoped. It keeps the current parsed content for each live file across runs and versions. It is not a version history.
Errors
| Status | error_code | Meaning |
|---|---|---|
402 | INSUFFICIENT_CREDIT | The organization has no credits. The API refuses the question before it runs, and charges nothing. |
404 | NOT_FOUND | Unknown workflow, or one belonging to another organization. |
409 | KNOWLEDGE_NOT_ENABLED | The workflow has no Knowledge node. Do not retry: add the node first. |
409 | KNOWLEDGE_NOT_READY | No knowledge snapshot has ever been published for this workflow. Wait if indexing is in progress; otherwise index existing documents from the app’s Knowledge tab. Once a snapshot exists, later ingestion never brings this error back — a stale pack keeps serving while it re-indexes. |
409 | KNOWLEDGE_THREAD_MISMATCH | The thread_id belongs to a different workflow. Use a new id or ask the workflow that owns it. |
409 | KNOWLEDGE_UNSUPPORTED_SNAPSHOT_FORMAT | The published snapshot is in a format this deployment no longer reads. Permanent until an operator republishes it. |
429 | RATE_LIMITED | The model is rate limited. Retry after the delay in Retry-After. |
502 | INTERNAL_ERROR | The model refused the request. Not worth retrying unchanged. |
503 | INTERNAL_ERROR | The model is temporarily unavailable. Retry. |
504 | GATEWAY_TIMEOUT | The ask exceeded the agent time limit. Retry with a narrower question. |
Follow-up questions
Pass athread_id you mint yourself, starting with kb-, to ask in the context of earlier questions in that thread. Omit it and each question stands alone. Reuse the same id to continue a conversation.
Billing
The platform charges per question and meters the text the agent reads. A narrow question over a small corpus therefore costs a fraction of a broad sweep over a large one. A question the organization cannot pay for is refused up front.curl -X POST 'https://api.anyformat.ai/v3/workflows/0686bb97-8c30-70f0-8000-97669e000eb8/knowledge/ask' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"question": "Which contracts renew before March and what notice do they need?"}'
from anyformat.sdk import Client
client = Client(api_key="YOUR_API_KEY")
answer = client.ask(
"0686bb97-8c30-70f0-8000-97669e000eb8",
"Which contracts renew before March and what notice do they need?",
)
print(answer)
for citation in answer.citations:
print(f" {citation.path} p.{citation.page}: {citation.quote}")
const response = await fetch(
'https://api.anyformat.ai/v3/workflows/0686bb97-8c30-70f0-8000-97669e000eb8/knowledge/ask',
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
question: 'Which contracts renew before March and what notice do they need?',
}),
},
);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const { answer, citations } = await response.json();
console.log(answer);
{
"answer": "Two contracts renew before March. Meridian MSA renews 2026-02-01 and needs ninety days' notice to terminate. Aldrete supply agreement renews 2026-02-14 with thirty days' notice.",
"citations": [
{
"path": "2026-07/meridian-msa-2024.md",
"quote": "Either Party may terminate upon ninety (90) days' notice.",
"file_id": "0192f0c1-a2b3-4c5d-8000-abcdef012345",
"block_id": "block-2",
"page": 2,
"bbox": { "x0": 0.08, "y0": 0.31, "x1": 0.92, "y1": 0.36 }
}
],
"path": [
{ "tool": "kb_grep", "args": { "pattern": "renewal" } },
{ "tool": "kb_read", "args": { "path": "2026-07/meridian-msa-2024.md" } }
],
"steps_used": 2,
"thread_id": null
}
{
"error": "The knowledge base is not enabled.",
"error_code": "KNOWLEDGE_NOT_ENABLED",
"retryable": false,
"request_id": "a1b2c3d4e5f67890abcdef1234567890"
}
{
"error": "The organization has no extraction credit left.",
"error_code": "INSUFFICIENT_CREDIT",
"retryable": false,
"request_id": "a1b2c3d4e5f67890abcdef1234567890"
}
Authorizations
API key issued from app.anyformat.ai/api-key. Send as Authorization: Bearer <key>.
Path Parameters
Body
application/json
A question about the content of this workflow's documents.
Minimum string length:
1Example:
"Which contracts renew before March and what notice do they need?"
Optional conversation id, minted by you, to ask a follow-up in context. Must start with kb-. Reuse it to continue; omit it for a fresh question.
Maximum string length:
64Pattern:
^kb-[A-Za-z0-9._-]+$Example:
"kb-renewals-q3"
Response
Successful Response
Show child attributes
Show child attributes
The route the agent took to the answer — auditable, not decorative.
Show child attributes
Show child attributes
Present when the question was asked in a thread.

