Skip to Content
Workflow IntentQuickstart

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:

curl -sS https://api.keelapi.com/v1/execute \ -H "Authorization: Bearer $KEEL_API_KEY" \ -H "Content-Type: application/json" \ -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 https://api.keelapi.com/v1/workflows/$WORKFLOW_ID/complete \ -H "Authorization: Bearer $KEEL_API_KEY" \ -H "Content-Type: application/json" \ -d '{"reason_provided": "batch finished"}'

Python SDK

from keel_sdk import Keel from keel_sdk.providers.openai import OpenAI keel = Keel() 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 keel.workflows.workflow(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, reason_provided="batch finished", )

Expected behavior

  • Calls above expected_calls are allowed unless another policy denies them. Keel records drift.
  • Calls after max_calls are denied before provider dispatch.
  • complete closes 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