Quickstart
Wiring a workflow end to end: an invoice arrives, the agent reads it, and a payable is created in your ERP with the original PDF attached.
Four steps, none of which involve deploying anything on your side.
1. Store the credential
The agent will reference it by name, so the value never appears in a prompt.
curl -X POST https://api.inbox.kobana.com.br/v1/secrets \
--cert ./client.crt --key ./client.key \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"key": "FINANCE_TOKEN",
"value": "erp-service-account-token",
"notes": "ERP service account — rotates every 90 days"
}'
{
"data": {
"id": "f1e2d3c4-b5a6-4978-8899-aabbccddeeff",
"key": "FINANCE_TOKEN",
"notes": "ERP service account — rotates every 90 days",
"last_used_at": null
}
}
The response has no value, and neither will any later read: the value is write-only. Rotating it later is PUT /v1/secrets with the same key — no id lookup, no agent change.
2. Teach the agent to emit a workflow
The platform executes whatever the agent returns; it does not write it. That belongs in the agent's system_message:
curl -X PATCH https://api.inbox.kobana.com.br/v1/agents/$AGENT_ID \
--cert ./client.crt --key ./client.key \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"system_message": "You read inbound invoices and register them in the ERP.\n\nAnswer with a single JSON object with two keys:\n\n- `result`: the data you extracted (supplier, amount, due_date, document number).\n- `workflow`: the requests needed to register it, or omit the key when no action is required.\n\nEach workflow step is:\n{\"type\":\"request\",\"method\":\"POST\",\"url\":\"…\",\"headers\":{…},\"body\":{…},\"expected_status\":201}\n\nRules:\n- Authenticate with `${{secrets.FINANCE_TOKEN}}`. NEVER write a credential literally.\n- Create the payable first, then attach the document to the id the first call returned, using `${{steps.0.response.body.data.id}}`.\n- Include `${{kobana.email_id}}` in the payable body so the record points back at the e-mail.\n- If the invoice is a duplicate or you are not confident, return `result` only, with no `workflow`."
}
JSON
Every PATCH that changes system_message bumps Agent.version and snapshots the prompt, so each run records exactly which instructions produced its workflow.
3. Send a test e-mail
Either send a real message to the inbox address, or submit an .eml through the API — it takes the same path, filters, agent and webhooks included:
curl -X POST "https://api.inbox.kobana.com.br/v1/emails?inbox_id=$INBOX_ID" \
--cert ./client.crt --key ./client.key \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: message/rfc822" \
--data-binary @invoice.eml
4. Read what happened
curl "https://api.inbox.kobana.com.br/v1/workflow-runs?email_id=$EMAIL_ID" \
--cert ./client.crt --key ./client.key \
-H "Authorization: Bearer $JWT"
Then open the run to see every step, the request as sent and the response received:
curl "https://api.inbox.kobana.com.br/v1/workflow-runs/$RUN_ID" \
--cert ./client.crt --key ./client.key \
-H "Authorization: Bearer $JWT"
{
"data": {
"status": "success",
"summary": { "total": 2, "succeeded": 2, "error": 0 },
"duration_ms": 812,
"steps": [
{
"position": 0,
"status": "success",
"request": {
"method": "POST",
"url": "https://erp.example.com/payables",
"headers": { "Authorization": "Bearer [REDACTED]" }
},
"response": {
"status": 201,
"expected_status": 201,
"body": "{\"data\":{\"id\":\"pay_42\"}}"
}
},
{
"position": 1,
"status": "success",
"request": { "url": "https://erp.example.com/payables/pay_42/attachments" },
"response": { "status": 200 }
}
]
}
}
Note pay_42 in the second step's URL: the agent wrote ${{steps.0.response.body.data.id}} and the platform resolved it from the first response.
5. React in real time (optional)
Instead of polling, subscribe to the terminal events:
curl -X POST https://api.inbox.kobana.com.br/v1/webhooks \
--cert ./client.crt --key ./client.key \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"label": "workflow outcomes",
"url": "https://ops.example.com/hooks/kobana",
"subscribed_events": ["workflow.run.succeeded", "workflow.run.failed"]
}'
workflow.run.failed carries data.failed_step, data.failed_steps (every step that failed) and data.error, plus the usual email and agent_run snapshots — enough to open a ticket without calling us back.
Doing the same from an AI client
Every step above exists as an MCP tool: secrets_create, agents_update, workflow_runs_list and workflow_runs_get. Submitting a test .eml has no tool — it is a raw-body upload, so use the HTTP endpoint above or emails_reprocess on a message you already received.
Where to go next
- The workflow did not do what you expected → Troubleshooting.
- You need a field you have not seen here → Steps and placeholders.