Build and run your first workflow
Discover capabilities, validate a synthetic graph, publish it, start an idempotent run, and inspect its outcome with REST or MCP.
Get access and choose a transport
Use an organization-bound GenHealth API key. The workflow developer boundary accepts API keys, not browser sessions or ordinary JWTs. Request workflow:read for discovery and preflight; add workflow:write, workflow:publish, and workflow:run to create and execute workflows. Your organization also needs the workflows plan feature. Keys and integration connections must be provisioned before an agent can operate independently.
| Transport | Production entry point | Contract |
|---|---|---|
| REST | https://api.umpa.genhealth.ai/developer/v1 | Authorization: Bearer <GENHEALTH_API_KEY> |
| MCP | https://api.umpa.genhealth.ai/developer/mcp | Streamable HTTP with the same bearer header; tool discovery is authenticated |
| OpenAPI | https://api.umpa.genhealth.ai/developer/openapi.json | Live server contract; prefer it over a cached website snapshot |
| Swagger | https://api.umpa.genhealth.ai/developer/docs | Interactive REST reference |
Read the deployed capabilities first
export GENHEALTH_API_BASE="https://api.umpa.genhealth.ai"
# Set GENHEALTH_API_KEY through your secret manager.
curl --fail-with-body "$GENHEALTH_API_BASE/developer/v1/capabilities/v2" \
-H "Authorization: Bearer $GENHEALTH_API_KEY"For MCP, initialize the connection, list tools, then call get_workflow_capabilities_v2. Use its node types, expression syntax, routing ports, lifecycle, and deployment flags. Discover exact handlers with search_workflow_actions and load get_workflow_action before authoring. REST and MCP operate on the same organization-scoped workflows.
Run a synthetic workflow before connecting a healthcare system
This graph routes a synthetic boolean to one of two annotation nodes. It creates no patient, order, claim, or authorization and needs no integration credentials. It tests authoring and execution, not clinical accuracy or payer connectivity. Comment nodes contain annotations only; trigger data comes from trigger.default.
{
"kind": "genhealth.workflow_definition",
"schema_version": 1,
"workflow": {
"name": "Agent quickstart: synthetic routing",
"description": "Synthetic execution check; no healthcare system reads or writes.",
"nodes": [
{
"id": "received",
"type": "comment",
"name": "Synthetic request",
"config": {
"heading": "Start",
"body": "Inputs are supplied in trigger_data."
}
},
{
"id": "route",
"type": "if",
"name": "Ready?",
"config": {
"condition": "{{trigger.default.ready}}"
}
},
{
"id": "ready",
"type": "comment",
"name": "Ready outcome",
"config": {
"heading": "Ready",
"body": "The true branch ran."
}
},
{
"id": "review",
"type": "comment",
"name": "Review outcome",
"config": {
"heading": "Review",
"body": "The false branch ran; no external review task was created."
}
}
],
"edges": [
{
"source_node_id": "received",
"source_output": "default",
"target_node_id": "route",
"target_input": "default"
},
{
"source_node_id": "route",
"source_output": "true",
"target_node_id": "ready",
"target_input": "default"
},
{
"source_node_id": "route",
"source_output": "false",
"target_node_id": "review",
"target_input": "default"
}
]
}
}The canonical import envelope used below.
Explore Download the runnable Python clientPython 3 standard library; preserves workflow IDs and run idempotency across restarts.
Explorecurl --fail-with-body https://genhealth.ai/docs/examples/agent-smoke-test.json -o agent-smoke-test.json
curl --fail-with-body https://genhealth.ai/docs/examples/workflow_agent.py -o workflow_agent.py
# Preflight only. No workflow is created.
python3 workflow_agent.py validate agent-smoke-test.json
# Create, publish, and submit one run; retain this state file for recovery.
python3 workflow_agent.py execute agent-smoke-test.json --state agent-smoke-state.json
# Inspect without resubmitting. Repeat until this run is terminal.
python3 workflow_agent.py inspect --state agent-smoke-state.jsonWhat the client does
| Step | Request | Check before continuing |
|---|---|---|
| Preflight | POST /developer/v1/workflows/validate with {"definition": <envelope>} | HTTP 200 can still mean viable=false. Inspect schema_errors, findings, and readiness. |
| Import | POST /developer/v1/workflows/import with the envelope itself | HTTP 201; workflow.id identifies the inactive workflow and immutable initial version. |
| Draft | POST /developer/v1/workflows/{id}/draft | Create an editable draft before publication or subsequent graph edits. |
| Publish | POST /developer/v1/workflows/{id}/publish with {} | Publishing audits the graph and activates an immutable version. Static success is not runtime proof. |
| Run | POST /developer/v1/workflows/{id}/runs | HTTP 202; save run_id. Acceptance is not completion. |
| Observe | GET /developer/v1/workflows/{id}/runs | Find the exact run_id. completed, failed, and cancelled are terminal. |
A successful smoke test should report completed, execute the true branch for ready=true, and skip the false branch. Inspect individual nodes with GET /developer/v1/workflows/{id}/runs/{run_id}/nodes/{node_id}. Public inspection exposes statuses and value-free shapes, not patient data or raw error text. A completed orchestration does not prove that a business result succeeded; healthcare recipes need explicit business-success branches.