Quickstart
From zero to a governed operational workflow in 15 minutes.
Who This Is For
Operations lead — "My team spends hours investigating exceptions manually. I need AI that works within our approval process." → Skip to Your First Governed Workflow
Platform engineer — "We need to embed governed agent execution into our product." → Start at The Graduated Pipeline
Developer — "Just show me the API." → Skip to API Fast Path
What You'll Build
A working governed workflow that demonstrates the core pattern: deterministic rules handle clear cases, a bounded AI agent investigates exceptions, a human reviewer makes the final call on edge cases, and every decision is logged.
We'll use invoice-to-payment reconciliation as the example — but the same architecture applies to incident response, contract review, employee onboarding, claims processing, or any operational process where you need autonomous AI within boundaries.
The Graduated Pipeline
Every Hyphen deployment follows this architecture:
Rules handle the clear cases. AI handles the ambiguous middle. Humans handle the edge cases. Every layer feeds the next. Nothing falls through.
This pattern works because it matches how real operations teams already work — experienced staff handle the obvious cases, specialists investigate the tricky ones, managers approve the exceptions. Hyphen encodes that same graduated judgment into infrastructure.
Your First Governed Workflow
Step 1: Prepare Your Data
Two datasets — invoices and payments — with real-world messiness:
Invoices:
[
{ "invoice_id": "INV-001", "vendor": "Acme Corp", "amount": 10000.00, "date": "2026-01-15" },
{ "invoice_id": "INV-002", "vendor": "Globex Inc", "amount": 4500.00, "date": "2026-01-18" },
{ "invoice_id": "INV-003", "vendor": "Initech", "amount": 7250.00, "date": "2026-01-20" },
{ "invoice_id": "INV-004", "vendor": "Umbrella Ltd", "amount": 15000.00, "date": "2026-01-22" },
{ "invoice_id": "INV-005", "vendor": "Stark Industries", "amount": 3200.00, "date": "2026-01-25" }
]
Payments:
[
{ "invoice_id": "INV-001", "vendor": "Acme Corp", "amount": 10000.00, "date": "2026-01-16" },
{ "invoice_id": "INV-002", "vendor": "Globex Inc", "amount": 4480.00, "date": "2026-01-19" },
{ "invoice_id": "INV-004", "vendor": "Umbrela Ltd", "amount": 15000.00, "date": "2026-01-23" },
{ "invoice_id": "INV-006", "vendor": "Wayne Enterprises", "amount": 8800.00, "date": "2026-01-27" }
]
Notice: INV-002 has a $20 discrepancy, INV-004 has a vendor typo ("Umbrela"), INV-003 and INV-005 have no payments, and INV-006 is a payment without an invoice.
Step 2: Create the Workflow
/workflowsCreate a workflow with matching, AI investigation, human approval, and audit logging.
curl -X POST http://localhost:3009/workflows \
-H "X-Org-Id: your-org" \
-H "Content-Type: application/json" \
-d '{
"name": "invoice_payment_reconciliation",
"definition": {
"actions": [
{
"type": "matcher",
"properties": {
"left": "@input.invoices",
"right": "@input.payments",
"matchOn": ["invoice_id"],
"tolerance": 0.02,
"dateWindowDays": 3,
"fuzzyThreshold": 85,
"descriptionKey": "vendor",
"outputMatched": "matched",
"outputUnmatchedLeft": "unmatched_invoices",
"outputUnmatchedRight": "unmatched_payments"
}
},
{
"type": "loop",
"filter": {
"condition": {
"greaterThan": [{ "length": "@unmatched_invoices" }, 0]
}
},
"properties": {
"mode": "react",
"objective": "Investigate these unmatched invoices. For each, determine the most likely reason (timing delay, data entry error, duplicate, or missing payment). Recommend: wait, follow up with vendor, or escalate.",
"tools": [
{ "type": "action", "name": "lookup_vendor_history" }
],
"max_iterations": 10,
"on_stuck": { "iterations": 3, "action": "escalate" },
"result_key": "investigation"
}
},
{
"type": "PbotApproval",
"filter": {
"condition": {
"greaterThan": [{ "length": "@unmatched_invoices" }, 0]
}
},
"properties": {
"comment": "AI investigated unmatched invoices. Review findings and approve recommended actions.",
"request_payload": {
"matched_count": "@matched.length",
"unmatched_invoices": "@unmatched_invoices",
"ai_investigation": "@investigation"
}
}
},
{
"type": "custom-table",
"properties": {
"table": "reconciliation_log",
"operation": "write",
"keys": ["run_id", "timestamp"],
"values": ["@__run_id", "@now"],
"fields": {
"matched_count": "@matched.length",
"exception_count": "@unmatched_invoices.length",
"status": "completed"
}
}
}
]
}
}'
Note on tools: Built-in agent tools (__complete__, __pause_for_human__, __store_memory__, __retrieve_memory__, __log_progress__) are automatically injected into every ReAct agent — you don't need to declare them. Only declare your custom action tools and workflow tools.
| Step | Primitive | What Happens |
|---|---|---|
| 1 | matcher |
Compares invoices to payments: exact invoice_id, 2% amount tolerance, ±3 day date window, 85% fuzzy vendor match |
| 2 | loop (react) |
AI agent investigates unmatched invoices — bounded to 10 iterations with stuck detection |
| 3 | PbotApproval |
Human reviewer sees results + AI reasoning — makes final call |
| 4 | custom-table |
Logs the run to an audit table |
Step 3: Execute
/workflows/:id/executeRun the workflow with your invoice and payment data.
curl -X POST http://localhost:3009/workflows/{workflow_id}/execute \
-H "X-Org-Id: your-org" \
-H "Content-Type: application/json" \
-d '{
"invoices": [
{ "invoice_id": "INV-001", "vendor": "Acme Corp", "amount": 10000.00, "date": "2026-01-15" },
{ "invoice_id": "INV-002", "vendor": "Globex Inc", "amount": 4500.00, "date": "2026-01-18" },
{ "invoice_id": "INV-003", "vendor": "Initech", "amount": 7250.00, "date": "2026-01-20" },
{ "invoice_id": "INV-004", "vendor": "Umbrella Ltd", "amount": 15000.00, "date": "2026-01-22" },
{ "invoice_id": "INV-005", "vendor": "Stark Industries", "amount": 3200.00, "date": "2026-01-25" }
],
"payments": [
{ "invoice_id": "INV-001", "vendor": "Acme Corp", "amount": 10000.00, "date": "2026-01-16" },
{ "invoice_id": "INV-002", "vendor": "Globex Inc", "amount": 4480.00, "date": "2026-01-19" },
{ "invoice_id": "INV-004", "vendor": "Umbrela Ltd", "amount": 15000.00, "date": "2026-01-23" },
{ "invoice_id": "INV-006", "vendor": "Wayne Enterprises", "amount": 8800.00, "date": "2026-01-27" }
]
}'
Response:
{ "id": "run_abc123", "status": "running" }
Step 4: Check Results
/runs/:runId/statusPoll for status. The run will pause at PbotApproval waiting for human review.
curl http://localhost:3009/runs/run_abc123/status \
-H "X-Org-Id: your-org"
Expected matcher output:
| Record | Result | Why |
|---|---|---|
| INV-001 | ✅ Matched | Exact match, 1-day date offset |
| INV-002 | ✅ Matched | $4,500 vs $4,480 — within 2% tolerance |
| INV-004 | ✅ Matched | "Umbrella" vs "Umbrela" — 87% fuzzy match |
| INV-003 | ❌ Unmatched | No payment found |
| INV-005 | ❌ Unmatched | No payment found |
| INV-006 | ❌ Unmatched payment | No invoice found |
The matcher handled 3 of 5 invoices automatically — including the amount discrepancy and vendor typo. No AI cost. Near-instant.
The 2 unmatched invoices flow to the ReAct agent. Sample reasoning trace:
Iteration 1:
Thought: "INV-003 from Initech — no payment match. Dated Jan 20,
only 16 days ago. Standard terms are net-30."
Action: __log_progress__
Input: { "message": "INV-003 likely within payment terms" }
Iteration 3:
Thought: "Both INV-003 and INV-005 are recent. Recommend: monitor
for 30 days, then follow up if still unmatched."
Action: __complete__
Input: {
"answer": "2 unmatched invoices — both within payment terms. Recommend: wait 30 days.",
"confidence": 0.85
}
Step 5: Approve
The workflow pauses at PbotApproval. The reviewer sees matched records, exceptions, and the AI investigation.
/approvals/:runId/:stepIndexSubmit the human decision. It becomes part of the permanent audit trail.
curl -X POST http://localhost:3009/approvals/run_abc123/2 \
-H "X-Org-Id: your-org" \
-H "Content-Type: application/json" \
-d '{
"approved": true,
"comments": "Agree with AI recommendation. Monitor and follow up in 30 days.",
"data": { "reviewer": "[email protected]" }
}'
The workflow resumes, logs to the audit table, and completes.
What just happened. One API call matched 60% of records automatically, got AI investigation of exceptions, routed edge cases to a human with full context, and logged everything. Manual process: 4+ hours. Hyphen: ~30 seconds of compute.
API Fast Path
For developers who want the five-minute tour.
Setup
BASE_URL=http://localhost:3009
ORG_ID=your-org
1. Health Check
:::api GET /health :::
curl $BASE_URL/health
# → { "status": "ok" }
2. Register an Action
/actionsRegister a reusable operation — HTTP, LLM, DB, matcher, or custom-table.
curl -X POST $BASE_URL/actions \
-H "X-Org-Id: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{
"action_name": "fetch_customer",
"kind": "http",
"url": "https://api.example.com/customers/{{customer_id}}",
"http_method": "GET",
"passthrough": true
}'
# → { "id": "act_abc123", "action_name": "fetch_customer" }
3. Create a Workflow
:::api POST /workflows :::
curl -X POST $BASE_URL/workflows \
-H "X-Org-Id: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "my_first_workflow",
"definition": {
"actions": [
{ "type": "fetch_customer", "properties": { "customer_id": "@input.id" } },
{ "type": "custom-table", "properties": {
"table": "audit_log", "operation": "write",
"keys": ["action"], "values": ["customer_lookup"]
}}
]
}
}'
# → { "id": "wf_xyz789" }
4. Execute
:::api POST /workflows/:id/execute :::
curl -X POST $BASE_URL/workflows/wf_xyz789/execute \
-H "X-Org-Id: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{ "id": "cust-12345" }'
# → { "id": "run_abc", "status": "running" }
5. Check Status
:::api GET /runs/:runId/status :::
curl $BASE_URL/runs/run_abc/status -H "X-Org-Id: $ORG_ID"
# → { "status": "completed", "context": { ... } }
6. Run a Standalone Agent
/agents/executeExecute an AI agent outside of a workflow — agent-as-trigger or agent-as-orchestrator pattern.
curl -X POST $BASE_URL/agents/execute \
-H "X-Org-Id: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{
"objective": "Analyze this support ticket and draft a response",
"tools": [
{ "type": "action", "name": "fetch_customer" },
{ "type": "action", "name": "gmail_send" }
],
"config": {
"model": "gpt-4",
"max_iterations": 10,
"on_stuck": { "iterations": 3, "action": "escalate" }
}
}'
7. Get the Reasoning Trace
/agents/:id/traceFull audit trail — every thought, action, and observation.
curl $BASE_URL/agents/{agent_run_id}/trace -H "X-Org-Id: $ORG_ID"
Next Steps: Connect Your Systems
Register actions to connect your systems, then reference them as agent tools using typed declarations.
HTTP action (any internal API):
curl -X POST $BASE_URL/actions \
-H "X-Org-Id: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{
"action_name": "lookup_record",
"kind": "http",
"url": "https://your-system.com/api/records/{{record_id}}",
"http_method": "GET",
"headers": { "Authorization": "Bearer orgconfig:api:system_token" }
}'
LLM action (AI analysis):
curl -X POST $BASE_URL/actions \
-H "X-Org-Id: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{
"action_name": "analyze_exception",
"kind": "llm",
"template": "Analyze this operational exception and recommend a resolution:\n\n{{exception_data}}",
"model": "gpt-4",
"max_tokens": 300
}'
Then use them as typed tool references in any agent:
{
"mode": "react",
"objective": "Investigate this exception and notify the responsible party",
"tools": [
{ "type": "action", "name": "lookup_record" },
{ "type": "action", "name": "analyze_exception" },
{ "type": "action", "name": "gmail_send" },
{ "type": "workflow", "id": "wf_escalation_process" }
]
}
Note: Built-in tools (__complete__, __pause_for_human__, __store_memory__, __retrieve_memory__, __log_progress__) are automatically injected — you never need to list them.
Same Architecture, Different Domains
The reconciliation example above demonstrates the graduated pipeline. Here's how the same pattern applies across industries:
| Domain | What plays the "Matcher" role | What the Agent investigates | Who reviews |
|---|---|---|---|
| IT Security | Correlate alerts against known-benign indicators | Enrich with threat intel, assess severity, recommend containment | SOC analyst |
| Legal | Compare extracted contract terms against standard playbook | Classify deviation risk, search precedent, draft redlines | Legal counsel |
| People Ops | N/A — agent orchestrates directly | Coordinate IT provisioning, benefits, training, equipment | HR coordinator |
| Healthcare | Match claims to policies, detect duplicates | Analyze denial codes, check medical necessity, draft appeals | Clinical reviewer |
Three Things to Remember
1. You don't need AI for everything. The matcher handles the majority of operational data work with zero AI cost. Start with deterministic rules. Add AI only for exceptions that require judgment.
2. Governance is structural, not policy. The agent can only use tools you've declared, can only iterate up to the cap you set, and escalates automatically when stuck. This is architecture, not a policy document.
3. Every decision is auditable. Matcher results, agent reasoning traces, human approval decisions — all captured, all queryable, all persistent.
Continue learning: Core Concepts explains the six building blocks. Your First Workflow walks through building a more complex pipeline step by step. Templates show production-ready patterns across finance, IT, legal, healthcare, and people operations.