Connect your agent

COLVO speaks one small HTTP contract to your agent: a POST with the customer, context and conversation; a JSON reply with the agent’s answer. To act, the agent proposes an operation back to COLVO with the key included in the request.

Written from the code · updated 26 Sep 2026 · Something wrong or missing? Tell us

The request COLVO sends

POST to your endpoint URL, content-type: application/json, plus the auth header you configured on the build (sent verbatim as authorization). Timeout 30 seconds. The body:

{
  "attempt_id": "5f1c…",                         // one per scenario attempt (idempotency anchor)
  "customer": { "id": "cus_01", "email": "[email protected]", "name": "Ada Northloop" },
  "context": {
    "subscriptions": [{ "id": "sub_01", "plan": "pro", "current_period_end": "2026-10-31T00:00:00Z",
                        "status": "active", "cancel_at_period_end": false, "pending_invoice_minor": 0 }],
    "payments": [{ "id": "pi_01", "amount_minor": 5000, "currency": "eur", "subscription_id": "sub_01" }]
  },
  "messages": [{ "role": "customer", "content": "Please refund my last payment and cancel at the end of the period." }],
  "colvo": {
    "operations_url": "https://colvo.app/v1/operations",
    "agent_key": "cak_…",                         // scoped to this attempt; propose with it
    "mandate_id": "9b2e…",
    "source_request_id": "ticket_demo_01"
  }
}

In production (Guard) your own backend builds this request; the shape is the same, with a real mandate id and your agent key.

The reply COLVO expects

{ "reply": "Done — I refunded €50 to your card and your plan stays active until 31 October.", "done": true, "notes": "optional" }
  • reply — the text the customer would see. Max 4,000 characters.
  • done — true (default) when the turn is complete. false lets multi-turn scenarios continue.
  • Non-2xx, a body over 64 KB or no usable text fail the attempt with a clear reason; they never count as PASS.

Reply path (any JSON shape works)

If your agent returns a different shape, set a reply path on the build: dots and brackets, e.g. data.answer, choices[0].message.content, messages[-1].content. Without a path COLVO auto-detects these keys, in order:

reply, answer, text, output, response, message, content, result,
data.reply, data.answer, data.text, data.output, data.message, data.content,
output.text, message.content, result.text, result.output,
choices.0.message.content, choices.0.text, outputs.0.text, items.0.text, messages.-1.content

Arrays of text blocks ([{"type":"text","text":"…"}]) and bare string bodies are accepted too.

Acting: propose an operation

When the agent decides to refund or cancel, it does not call Stripe. It calls COLVO:

POST {operations_url}
Authorization: Bearer {agent_key}
Idempotency-Key: {source_request_id}:refund
Content-Type: application/json

{ "mandate_id": "{mandate_id}", "source_request_id": "{source_request_id}",
  "action": "refund.create",
  "parameters": { "payment_id": "pi_01", "amount_minor": 5000, "currency": "eur" },
  "context": { "user_message": "…", "agent_reply": "…" } }

COLVO answers 202 with the operation and its decision. The agent should reflect the decision honestly in its reply: a DENY means nothing happened; a REVIEW means a human will decide. Full reference: Guard API.

Network rules

  • Your endpoint must be reachable from COLVO over HTTPS on a public host. Localhost, private ranges and cloud metadata addresses are refused by the egress policy; DNS is pinned and redirects re-checked.
  • Keep p95 latency under a few seconds; the hard timeout is 30 s per call.
  • The auth header is stored encrypted and never shown again after you save it.

Probe before you save

The project page’s Test connection sends exactly the request above (with a sample customer) and shows: HTTP status, latency, the resolved reply and the path that found it, the first 4 KB of the raw body, and one of these specific errors: egress blocked, timeout, non-2xx, body not JSON and not text, no reply text at the path, reply too long. Nothing is stored until you save the build.

Presets: Flowise and Voiceflow

For agents built on Flowise or Voiceflow, pick the platform in Connect your agent and COLVO speaks that platform’s own API — you don’t implement the contract above. The agent still never holds provider keys: COLVO passes the same colvo values as variables, and the agent proposes with them.

  • Flowise — POST {flowise}/api/v1/prediction/{chatflow_id} with question and overrideConfig: { sessionId, vars }; a new session per attempt; the reply is text. Create the four colvo_* Flowise variables and allow override config for sessionId and vars. Guide: Test a Flowise refund agent.
  • Voiceflow — Dialog API with your VF.DM. key: PATCH /state/user/{attempt}/variables (the colvo_* values, colvo_customer, colvo_context), launch on the first turn, then a text action per customer message; the reply is the text traces joined. Guide: Connect a Voiceflow assistant.

By default COLVO adds the customer’s account facts (ids, amounts) under each customer message so the model can use them; turn that off on the build if your flow reads colvo_context instead.

Step-by-step checks (OpenTelemetry)

State checks say what happened in Stripe; step checks say how the agent got there. Add them on a scenario (open any attempt of it → Step checks): a tool is called before another, at most N times, never, the agent replies only after COLVO decided, no step ended in an error. They are deterministic and can only add a FAIL — never turn a FAIL into a PASS.

Proposals are always counted by COLVO itself. For checks on your own tools, export your agent’s trace during the test with the per-test key:

POST {app}/v1/otel/traces          (also /v1/otel/v1/traces)
Authorization: Bearer {agent_key}
Content-Type: application/json      // OTLP/HTTP JSON; protobuf not yet
  • Follow the OpenTelemetry GenAI conventions: chat … spans for model calls, execute_tool {name} (or gen_ai.tool.name) for tools. On your propose call set colvo.action.
  • COLVO keeps span names, timings, models, token counts and error status — never prompts, replies or tool arguments. Up to 500 spans per attempt, 1 MiB per batch.
  • No trace? Checks on your own tools show as not checked, never as a FAIL. With the OpenAI preset COLVO records every step itself.

Reference: n8n

  1. Webhook node (POST) — this is your endpoint URL.
  2. Your model / logic nodes, using {{ $json.messages }} and {{ $json.context }}.
  3. HTTP Request node → {{ $json.colvo.operations_url }} with header Authorization: Bearer {{ $json.colvo.agent_key }} when an action is needed.
  4. Respond to Webhook node → { "reply": "…" }.
Connect your agent · Docs · COLVO