Skip to main content

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​