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. 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_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