Workflow Intent Quickstart
This is the smallest end-to-end workflow intent flow: declare a workflow, attach the workflow id to governed calls, then complete the workflow.
Direct REST
export KEEL_API_KEY="keel_sk_your_project_key"
export WORKFLOW_ID="invoice-batch-2026-05-13"curl -sS https://api.keelapi.com/v1/workflows \
-H "Authorization: Bearer $KEEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"workflow_id": "'"$WORKFLOW_ID"'",
"intent": {
"expected_calls": 10,
"max_calls": 12,
"expected_model": "gpt-5-mini",
"expected_input_tokens_per_call": 1200,
"expected_output_tokens_per_call": 300,
"max_duration_seconds": 3600
},
"budget_envelope_id": null
}'Attach the workflow id to each governed request in the run. Hosted Keel also requires a current X-Keel-Timestamp and a new X-Keel-Nonce on each governed request; see Request Freshness.
curl -sS https://api.keelapi.com/v1/execute \
-H "Authorization: Bearer $KEEL_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Keel-Timestamp: $(date +%s)" \
-H "X-Keel-Nonce: $(openssl rand -hex 16)" \
-H "Idempotency-Key: wf-exec-001" \
-H "X-Keel-Workflow-Id: $WORKFLOW_ID" \
-d '{
"provider": "openai",
"model": "gpt-5-mini",
"input": {
"messages": [
{"role": "user", "content": "Summarize invoice INV-1001 in one sentence."}
],
"max_tokens": 80
}
}'Complete the workflow:
curl -sS -X POST https://api.keelapi.com/v1/workflows/$WORKFLOW_ID/complete \
-H "Authorization: Bearer $KEEL_API_KEY"Python SDK
from keel_sdk import KeelClient
from keel_sdk.workflows import workflow as workflow_context
from keel_sdk.providers.openai import OpenAI
keel = KeelClient()
openai = OpenAI()
workflow = keel.workflows.declare(
workflow_id="invoice-batch-2026-05-13",
intent={
"expected_calls": 10,
"max_calls": 12,
"expected_model": "gpt-5-mini",
"expected_input_tokens_per_call": 1200,
"expected_output_tokens_per_call": 300,
"max_duration_seconds": 3600,
},
)
with workflow_context(workflow["workflow_id"]):
response = openai.chat.completions.create(
model="gpt-5-mini",
messages=[
{
"role": "user",
"content": "Summarize invoice INV-1001 in one sentence.",
}
],
max_tokens=80,
)
print(response["choices"][0]["message"]["content"])
keel.workflows.complete(workflow["workflow_id"])Expected behavior
- Calls above
expected_callsare allowed unless another policy denies them. Keel records drift. - Calls after
max_callsare denied before provider dispatch. completecloses the workflow and reconciles actual calls against the declaration and amendments.
For direct API integrations, see the header convention. For every field on the workflow endpoints, see the API reference.
Last updated on Edit this page on GitHub