DonutworkHelp Center
Donutwork documentation

AI Gateway guided examples

Build a chat assistant, add lexical retrieval, request a typed decision, and create embeddings.

AI Gateway guided examples

These examples run from a trusted backend. They use fictional content and placeholder IDs; replace them with resources from the company associated with your API key. Set DONUTWORK_API_KEY in your server environment without putting a real key in source code or shell history. The URLs below use API version 2026-02-01.

You need active AI Gateway connections before starting: one with purpose: generation for chat, one with purpose: decision for typed decisions, and one with purpose: embedding for vectors. Configure provider credentials through your secure provisioning flow; the API never returns them. See the connection reference. Inference and embeddings call a provider and may consume your monthly budget.

List available connections and note their IDs and purposes (ai_connections:read):

curl 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/connections.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY"

1. Create a generation assistant and ask a question

Scopes: ai_prompts:write, ai_assistants:write, ai_inference:write.

Create a published prompt and save its id as PROMPT_ID. The prompt is stored for the authenticated company; keep secrets and customer data out of it.

curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/prompts.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"name":"Example product helper","content":"Answer using approved information. If the answer is unavailable, say so clearly."}'

Create an assistant with an active generation connection and the returned prompt. Save the assistant id as ASSISTANT_ID.

curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/assistants.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"name":"Example product helper","connection_id":"GENERATION_CONNECTION_ID","prompt_id":"PROMPT_ID"}'

Ask a question without retrieval. The response includes answer, request_id, usage, and any applicable citation metadata. Choose a new idempotency key for each logical request; reuse it only when retrying the identical request.

curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/assistants/ASSISTANT_ID/chat.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: example-chat-request-0001' \
  --data '{"message":"What can this assistant help with?","retrieval":{"mode":"none"}}'

If the connection or prompt becomes unavailable, chat can return 409. A hard monthly budget can return 402; provider failure can return 502. See the assistant endpoint reference.

2. Ground answers in approved text

Scopes: ai_knowledge_bases:write, ai_assistants:write, ai_inference:write.

A lexical knowledge base needs no vector store or embedding connection. Create one, then save the returned id as KNOWLEDGE_BASE_ID.

curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/knowledge-bases.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"name":"Example policies","description":"Approved public policy text","retrieval_mode":"lexical"}'

Add approved text. An omitted ACL makes the document searchable by callers within this company's knowledge base. Add access principals when a document needs narrower visibility; your backend is responsible for passing the user's principals during retrieval.

curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/knowledge-bases/KNOWLEDGE_BASE_ID/documents.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"name":"Example return policy","content":"Example purchases can be returned within 30 days of delivery.","metadata":{"language":"en","section":"Returns"}}'

Create a second generation assistant linked to the same prompt and connection plus this knowledge base. Save its id as RETRIEVAL_ASSISTANT_ID.

curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/assistants.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"name":"Example policy helper","connection_id":"GENERATION_CONNECTION_ID","prompt_id":"PROMPT_ID","knowledge_base_ids":["KNOWLEDGE_BASE_ID"]}'
curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/assistants/RETRIEVAL_ASSISTANT_ID/chat.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: example-policy-request-0001' \
  --data '{"message":"What is the example return period?","retrieval":{"mode":"assistant","limit":3}}'

Inspect answer, citations, and retrieval.results_count. Citations depend on whether the assistant actually used a retrieved passage. For vector retrieval, see the knowledge base reference for its additional vector store and embedding connection prerequisites.

3. Ask for a typed decision

Scopes: ai_assistants:write, ai_inference:write.

Decision assistants use an active purpose: decision connection. Their questions are saved on the assistant and cannot be overridden during invocation. They do not use a prompt, retrieval, chat, or web search.

curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/assistants.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"name":"Example ticket router","connection_id":"DECISION_CONNECTION_ID","decision_questions":{"team":{"type":"choice","instructions":"Choose the team for this example ticket.","criteria":{"billing":"Payment or invoice issue","support":"Other product question"}}}}'

Save the returned assistant id as DECISION_ASSISTANT_ID, then send only the current state. The response includes an answers object keyed by question name, plus usage and request_id; the fields inside each answer depend on the decision provider.

curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/assistants/DECISION_ASSISTANT_ID/decisions.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: example-decision-request-0001' \
  --data '{"state":{"ticket_type":"billing","topic":"invoice copy"}}'

Use POST /ai-gateway/decisions.json when the caller must supply connection_id, state, and questions on each request. See the decision endpoint reference.

4. Create embeddings for your own index

Scope: ai_embeddings:write.

Use an active purpose: embedding connection. input_type and dimensions are provider-specific, so omit them unless your selected provider supports them. The response contains vectors in data[].embedding and normalized usage; keep the vectors in your own authorized index if you need them later.

curl -X POST 'https://api.hub.donutwork.com/2026-02-01/ai-gateway/embeddings.json' \
  -H "Authorization: Bearer $DONUTWORK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"connection_id":"EMBEDDING_CONNECTION_ID","input":["Example return policy","Example shipping policy"]}'

The request accepts at most 64 input passages and a 1 MB total payload. A model mismatch, if you supply model, returns 409. See embeddings and usage for limits and cost visibility.

On this page