Prompts
Reusable, structured instructions referenced by agents and LLM/extraction tasks.
A prompt is a saved, reusable bundle of instructions — system + user roles, an output
shape, and metadata — that lives in the Prompt Library (/api/prompts). Instead of
hand-writing instructions on every node, you author a prompt once and reference it by
prompt_title from an agent or by prompt_id from an
extraction or LLM task.
Prompts are system-level (shared, Super-Admin owned) or user-level (private to their
owner). Titles are globally unique, so prompt_title is a stable reference.
What makes a prompt work
The durable tactics are model-agnostic and worth keeping in mind whatever you store in the library:
- Be explicit. State the task, the output format, and any hard constraints — treat the model like a capable new hire with no prior context.
- Show examples. A few diverse input/output pairs steer format and tone better than more description (few-shot).
- Give structure. Separate role, instructions, input, and output so the model parses them unambiguously — exactly what RTIO (below) does.
- Add context, not assumptions. Supply the domain facts the model needs; for large bodies of knowledge, retrieve them with RAG rather than pasting them in.
Synthesized from the prompting guides of Anthropic, OpenAI, and Google.
The prompt object
These fields map to the prompt content type. The outputFormat + exampleOutput pair is
what makes a prompt produce consistent structured results — define the JSON shape once and
every run targets it.
| Field | Type | Default | Description |
|---|---|---|---|
title | string | — | Display name. Required and globally unique. |
description | text | null | Human-readable summary of what the prompt does. |
section | string | null | Category used for grouping / filtering in the library. |
roles | json | system/user/developer/assistant stubs | The chat messages: [{ role, prompt }] for system, user, developer, assistant. |
tasks | json | [] | Ordered list of extraction/processing steps the model should perform. |
instructions | json | [] | Output-formatting and edge-case rules (e.g. "use null for missing fields"). |
outputFormat | enum | text | text, json, markdown, or structured. |
exampleOutput | json | {} | A worked example of the expected output — the output schema the model targets. |
version | string | 1.0 | Author-managed version label. |
level | enum | user | user (private to owner) or system (shared; Super Admin only). |
owner | relation | current user | Set automatically to the caller for user-level prompts. |
The synced Prompt API reference describes the request/response bodies in a simplified shape. The field list above is the authoritative content-type schema — prefer it when building payloads, and treat the reference as the endpoint contract.
Example exampleOutput — invoice extraction
A structured prompt that pins the output to an invoice schema:
{
"invoice_number": "INV-2024-0148",
"invoice_date": "2024-03-12",
"vendor_name": "Acme Supplies Ltd",
"total_amount": 4820.50,
"currency": "USD",
"line_items": [
{ "description": "Widget A", "quantity": 10, "unit_price": 42.0, "amount": 420.0 }
]
}The model returns data in this shape; missing fields come back as null, empty lists as [].
CRUD via the API
All calls hit base URL https://apisandbox.turfai.in/api with a JWT bearer token. Create and
list are shown below in three languages — pick whichever matches your stack; they're
equivalent.
Create a prompt — POST /prompts
curl -X POST https://apisandbox.turfai.in/api/prompts \
-H "Authorization: Bearer $TURFAI_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"title": "Invoice Extraction",
"description": "Extract header + line items from invoices",
"section": "finance",
"outputFormat": "structured",
"roles": [
{ "role": "system", "prompt": "You are an expert at reading invoices." },
{ "role": "user", "prompt": "Extract the fields below from {{document_content}}." }
],
"tasks": ["Read the invoice", "Extract header fields", "Extract line items"],
"instructions": ["Return only valid JSON", "Use null for missing fields"],
"exampleOutput": { "invoice_number": "INV-2024-0148", "total_amount": 4820.50 }
}
}'import os, requests
BASE = "https://apisandbox.turfai.in/api"
headers = {"Authorization": f"Bearer {os.environ['TURFAI_TOKEN']}"}
payload = {
"data": {
"title": "Invoice Extraction",
"description": "Extract header + line items from invoices",
"section": "finance",
"outputFormat": "structured",
"roles": [
{"role": "system", "prompt": "You are an expert at reading invoices."},
{"role": "user", "prompt": "Extract the fields below from {{document_content}}."},
],
"tasks": ["Read the invoice", "Extract header fields", "Extract line items"],
"instructions": ["Return only valid JSON", "Use null for missing fields"],
"exampleOutput": {"invoice_number": "INV-2024-0148", "total_amount": 4820.50},
}
}
resp = requests.post(f"{BASE}/prompts", json=payload, headers=headers)
resp.raise_for_status()
print(resp.json())const BASE = "https://apisandbox.turfai.in/api";
const resp = await fetch(`${BASE}/prompts`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TURFAI_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
data: {
title: "Invoice Extraction",
description: "Extract header + line items from invoices",
section: "finance",
outputFormat: "structured",
roles: [
{ role: "system", prompt: "You are an expert at reading invoices." },
{ role: "user", prompt: "Extract the fields below from {{document_content}}." },
],
tasks: ["Read the invoice", "Extract header fields", "Extract line items"],
instructions: ["Return only valid JSON", "Use null for missing fields"],
exampleOutput: { invoice_number: "INV-2024-0148", total_amount: 4820.5 },
},
}),
});
if (!resp.ok) throw new Error(`Create failed: ${resp.status}`);
console.log(await resp.json());List prompts — GET /prompts
Returns system-level prompts plus the caller's own. Supports search, tag, and
pagination[page] / pagination[pageSize] query params.
curl "https://apisandbox.turfai.in/api/prompts?pagination[pageSize]=25" \
-H "Authorization: Bearer $TURFAI_TOKEN"import os, requests
BASE = "https://apisandbox.turfai.in/api"
headers = {"Authorization": f"Bearer {os.environ['TURFAI_TOKEN']}"}
resp = requests.get(f"{BASE}/prompts", params={"pagination[pageSize]": 25}, headers=headers)
resp.raise_for_status()
print([p["title"] for p in resp.json()["data"]])const BASE = "https://apisandbox.turfai.in/api";
const resp = await fetch(`${BASE}/prompts?pagination[pageSize]=25`, {
headers: { Authorization: `Bearer ${process.env.TURFAI_TOKEN}` },
});
if (!resp.ok) throw new Error(`List failed: ${resp.status}`);
const { data } = await resp.json();
console.log(data.map((p: { title: string }) => p.title));PUT /prompts/:id and DELETE /prompts/:id round out CRUD — both are owner-checked (or Super
Admin for system-level prompts). See the
Prompt API reference for full endpoint contracts.
RTIO structure
TurfAI structures extraction prompts as RTIO — Role, Task, Input, Output:
- Role — who the model is (the
systemrole): "You are an expert at reading invoices." - Task — what to extract (
tasks+ theuserrole). - Input — the document content, injected via the
{{document_content}}placeholder. - Output — the target shape (
outputFormat+exampleOutput+ formattinginstructions).
When you run a structured extraction, the platform assembles these into a single template (Role / Task / Output Format / Rules) before sending it to the model.
AI enhancement
The Prompt Lab can take a rough prompt and an output schema and return a polished RTIO
structure (roles / tasks / instructions) via POST /prompt-lab/enhance-rtio. There's
also POST /prompts/generate-rtio, which infers a full extraction prompt from a sample
document and its classification.
Coming soon. The internal scoring/ranking algorithm behind AI enhancement and
document-driven RTIO generation isn't documented yet — these run as asynchronous LLM jobs in
the processor. This page will cover the request/response contracts for enhance-rtio and
generate-rtio once they're stable in the public reference.
How prompts plug in
From an agent — set prompt_title to the prompt's (unique) title when creating the agent:
{
"data": {
"name": "Invoice Bot",
"goal": "Extract and validate invoice data",
"prompt_title": "Invoice Extraction"
}
}From an extraction task — reference the saved prompt by prompt_id in the node config:
{
"task_type": "extraction",
"config": {
"document_id": 1234,
"prompt_id": 42
}
}An llm task works the same way — supply a saved prompt_id or an inline prompt_text. See
Task types for the full node config.
Reference
- Prompt API — endpoints and request/response bodies.
- Agents — reference a prompt from an agent via
prompt_title. - Task types — extraction and
llmnodes that consumeprompt_id.