Outside agents
Bring an assistant you run elsewhere into Coline as a crew member with its own name.
An outside agent is an assistant that runs somewhere else and joins your workspace's crew. People @mention it, DM it and add it to channels like any crew member. Coline never runs it: when someone talks to it, Coline sends the message to its webhook, and the agent replies through the Agent API with its own token.
Use this when the assistant should be a teammate in conversations. To let an assistant act as you across mail, tasks and calendar, connect it to the MCP server instead.
Connect one
- Open Kairo → Crew and choose Connect an agent.
- Give it a name, say what it does, and add its webhook URL (you can add the URL later).
- Copy the agent token and the webhook signing secret. Coline shows them once.
Anyone whose role can create crew members can connect one. Its owner and people whose role can manage agents can change it. The agent's page shows its connection, recent deliveries and a Send test event button. From there you can set a new token or signing secret, which stops the old one at once, or remove the agent.
When it gets a message
Coline sends a message.created event when a person:
- @mentions the agent in a channel or thread. Mentioning it in a public channel it isn't in adds it, like inviting a teammate.
- Messages it in a DM.
- Replies in a thread the agent has posted in.
Messages from other agents, and messages someone hides with /aside, aren't sent. Nothing is sent while the agent is paused.
{
"id": "evt_9c1e…",
"type": "message.created",
"created_at": "2026-10-18T21:04:11.000Z",
"workspace": { "slug": "acme", "name": "Acme" },
"agent": { "id": "…", "name": "Scout" },
"conversation": { "type": "channel", "id": "…", "name": "#launch" },
"message": {
"id": "…",
"text": "@Scout can you summarize the feedback from this week?",
"thread_id": null,
"author": { "id": "…", "name": "Dana Kim" },
"mentioned": true,
"direct": false,
"url": "https://coline.app/acme/channels/launch"
},
"reply": {
"url": "https://coline.app/api/v1/agent-api/conversations/channel/…/messages",
"thread_id": "…"
}
}To answer in the right place, POST to reply.url with reply.thread_id. In a channel that starts a thread under the person's message; in a DM it's null, so the reply goes in the conversation.
Send test event delivers a ping with workspace and agent.
Verify deliveries
Deliveries are signed with Standard Webhooks. Each request has webhook-id, webhook-timestamp and webhook-signature headers. The signature is v1, followed by the base64 HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{body}, keyed with the base64 part of your whsec_ secret. Any Standard Webhooks library verifies it:
import { Webhook } from "standardwebhooks";
const event = new Webhook(process.env.COLINE_SIGNING_SECRET!).verify(rawBody, headers);Reject old timestamps, and use webhook-id to ignore a repeat. Answer 2xx quickly and do the work afterwards. Coline retries other answers with backoff for about a day, keeping the same webhook-id. 410 and 413 aren't retried.
Agent API
https://coline.app/api/v1/agent-apiSend the agent token as a bearer token. The agent sees only conversations it's in, and everything it posts appears under its own name.
curl https://coline.app/api/v1/agent-api/me \
-H "Authorization: Bearer col_agent_..."| Method | Path | Does |
|---|---|---|
GET | /me | The agent and its workspace |
GET | /conversations | Channels and DMs the agent is in |
GET | /conversations/{type}/{id}/messages | Recent messages. type is channel or dm. Query: thread_id for one thread, limit (1 to 100, default 30), before for older messages |
POST | /conversations/{type}/{id}/messages | Post {"text": "…", "thread_id": "…"} as the agent. thread_id is optional |
Responses use the REST API's { "data": … } and { "error": { "code", "message" } } shapes.
curl https://coline.app/api/v1/agent-api/conversations/channel/CHANNEL_ID/messages \
-H "Authorization: Bearer col_agent_..." \
-H "Content-Type: application/json" \
-d '{ "text": "Here is the summary…", "thread_id": "MESSAGE_ID" }'A message the agent posts in a DM notifies the people in it.
Limits and errors
The Agent API allows 240 reads and 60 posts per agent per minute.
| Code | Meaning |
|---|---|
INVALID_TOKEN | The token is unknown, was replaced, or the agent was removed |
AGENT_PAUSED | Someone paused the agent in Coline |
NOT_IN_CONVERSATION | The agent isn't in that conversation; someone has to add it or message it first |
RATE_LIMIT_EXCEEDED | Too many requests; wait a minute |
VALIDATION_ERROR | The path, query or body is invalid |