DocsConcepts
Keys and scopes
A key says which account an agent acts for. Give each bot or job a key of its own, limited to what it needs.
Send the key as a bearer token on every call that reads or changes the business's data:
Authorization: Bearer conecto_sk_...X-Api-Key: conecto_sk_... works too, for tools that put a key in a header of their own, like Power Platform connectors. Over MCP, set the same Authorization header when you add the server.
A key starts with conecto_sk_. It is shown once, when it is made. Conecto keeps only its SHA-256 hash and its last four characters.
The routes that describe Conecto answer without a key: the index, the lists of areas and tools, SKILL.md, the OpenAPI files, and an MCP server's initialize and tools/list.
POST /v1/keys makes a key for another bot or job, from a key that works. The new key is never wider than the key that makes it.
curl
curl -X POST https://api.conecto.chat/v1/keys \
-H "Authorization: Bearer $CONECTO_KEY" \
-H "Content-Type: application/json" \
-d '{
"bot_name": "Support bot",
"areas": ["helpdesk"],
"drafts_only": true,
"expires_at": "2027-01-31T18:00:00Z",
"networks": ["203.0.113.0/24"],
"team": "Support",
"accountable": "Lena Brandt"
}'Python
import os
import requests
reply = requests.post(
"https://api.conecto.chat/v1/keys",
headers={"Authorization": f"Bearer {os.environ['CONECTO_KEY']}"},
json={
"bot_name": "Support bot",
"areas": ["helpdesk"],
"drafts_only": True,
"expires_at": "2027-01-31T18:00:00Z",
"networks": ["203.0.113.0/24"],
"team": "Support",
"accountable": "Lena Brandt",
},
)
print(reply.status_code, reply.json())JavaScript
const reply = await fetch("https://api.conecto.chat/v1/keys", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CONECTO_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
bot_name: "Support bot",
areas: ["helpdesk"],
drafts_only: true,
expires_at: "2027-01-31T18:00:00Z",
networks: ["203.0.113.0/24"],
team: "Support",
accountable: "Lena Brandt",
}),
});
console.log(reply.status, await reply.json());{
"key_id": 4128,
"key": "conecto_sk_9d2e7b4a1c6f3e8b5a0d7c2f9e4b1a6d",
"key_note": "Shown once.",
"daily_budget_usd": "$20.00",
"scope": {
"areas": ["helpdesk"],
"tools": null,
"deny_tools": null,
"read_only": false,
"drafts_only": true,
"expires_at": "2027-01-31T18:00:00+00:00",
"networks": ["203.0.113.0/24"],
"team": "Support",
"accountable": "Lena Brandt"
}
}| Field | Type | What it is |
|---|---|---|
bot_name Required |
string | The bot's name, as the call log shows it. 1 to 80 characters. |
runtime |
string | What the agent runs in, like n8n or Claude Code. It shows beside the key. |
daily_ |
number | Its daily budget. On an account with an owner email, at most this key's. |
areas |
array of strings | The areas it works in. |
tools |
array of strings | The only tools it may run. |
deny_tools |
array of strings | Tools it may not run. |
read_only |
boolean | It only reads. |
drafts_only |
boolean | Every change it makes waits for a person. |
expires_in_days |
integer | It stops working after this many days. |
expires_at |
string (date-time) | It stops working at this time, as ISO 8601 with its offset. |
networks |
array of strings | The addresses or ranges it may be used from. |
team |
string | Its team. Only a key of the company-wide team with no limits names another team, and a new name makes it. |
accountable |
string | The person who answers for the key. |
- A key makes keys only within its own scope and team. A request for more answers
scope_too_wide. - Keys made from a key form a line, and the whole line shares the daily budget of its first key. Limits explains the budgets.
- On an account with an owner email, a new key's daily budget is at most that of the key making it.
- Only a key of the company-wide team with no areas, tool list or read-only limit names another team. A new team name makes the team.
- An account has at most 25 keys that work. More answers
limit_reached.
A key limited to areas, to a list of tools or to reading is a scoped key. It stays inside what it was given:
- Of the account tools, it keeps
account_balance,account_get_call,account_list_callsandaccount_dashboard_link, since the others reach every area. Its maker can name others intools. GET /v1/callsshows it its own calls only.- Changing the limits or auto-reload answers
key_scope.
networks keeps any key to some addresses or ranges, like 203.0.113.0/24, up to 20 of them. A call from anywhere else answers network_not_allowed. An end date, expires_in_days or expires_at, at most 366 days ahead, ends a key on its own, and a call after that answers key_expired.
drafts_only makes every change the key asks for wait for a person, while its reads go through. Approvals has the details.
GET /v1/keys lists the keys that work, with each one's scope and the last time it was used. current: true marks the key making the call.
DELETE /v1/keys/{key_id} revokes a key. A key revokes itself and the keys made from it, and the first key of a line revokes any key of its line. Any other key answers not_yours. The owner revokes any key on the account page. A revoked key stops working on every server within 30 seconds.
A connector that a person signs in to runs on a key of its own, named like "Ben, through Claude". It acts as that person, within their teams and role, and removing them from the account revokes it at once. Accounts and people has more.
Updated . Every route, field and number here is read from the API's own code.