Connect a chat app or tool
POST
type and values follow GET /api/catalog: e.g. { "kind": "tool", "type": "github", "name": "GitHub", "values": { "token": "github_pat_…" } }. A tool whose catalog entry has connect.checks is checked with the tool first: the connection comes back with account (who the key belongs to). A key the tool refuses is never saved: 400 { error, reason: "credential" | "permission" }, the error saying what to fix. When the tool couldn't be reached, reason is "unreachable"; send the same request with skipCheck: true to save it anyway. Where the catalog entry says registersWebhook, Roster registers its own webhook at the tool; webhookProblem says so if it couldn't.
sessioncookie
better-auth.session_token<token>Set by POST /api/auth/sign-in/email.
ws*stringThe workspace id (from GET /api/me).
application/json- body
kind*stringValue in
"chat""tool"type*stringLength
1 <= lengthname*stringLength
1 <= length <= 80values?Default
{}skipCheck?booleanThe connection.
application/jsoncurl -X POST 'https://app.useroster.work/api/workspaces/string/connections' \ -H 'Content-Type: application/json' \ -d '{ "kind": "chat", "type": "string", "name": "string"}'Example Response
{ "id": "8d1e5b2c-0f3a-4e7b-9c6d-1a2b3c4d5e6f", "kind": "tool", "type": "github", "name": "GitHub", "settings": {}, "secretsSet": [ "token" ], "status": "connected", "statusDetail": null, "account": "acme-studio", "checkedAt": "2026-11-03T09:00:00.000Z", "createdAt": "2026-11-03T09:00:00.000Z"}