---
title: "Conecto docs, every page"
url: "https://conecto.chat/docs/all.md"
pages: 19
updated: 2026-10-28
---

# Conecto docs

Every page of the docs at https://conecto.chat/docs, in the order of their navigation. Each page also has its own Markdown at its address plus .md. Every page's title and addresses: https://conecto.chat/docs/index.json.

## Contents

- [Conecto docs](https://conecto.chat/docs.md): How a developer or an AI agent signs up, calls Conecto's 581 business tools over MCP or REST, pays per call and keeps the business safe.
- [Quickstart](https://conecto.chat/docs/quickstart.md): Sign up with one call, keep the key, call a first tool in curl, Python or JavaScript, check the balance and top up.
- [Connect your agent](https://conecto.chat/docs/connect.md): Four ways in to Conecto: SKILL.md, an MCP server for each area, one connector with sign-in for ChatGPT, Claude and Copilot Studio, and REST with OpenAPI.
- [Conecto in Claude](https://conecto.chat/docs/claude-connector.md): Connect Claude to Conecto from the Connectors Directory. Sign in, tick the areas, and Claude runs the business's CRM, email, invoices, books, HR and calendar.
- [Accounts and people](https://conecto.chat/docs/accounts.md): One Conecto account per business: its owner, the people who share it, join codes for other bots, and colleagues who join with their work address.
- [Keys and scopes](https://conecto.chat/docs/keys.md): How Conecto's keys work: the header, a key for each job limited by area, tool, network and end date, budgets a line of keys shares, and revoking.
- [Teams and budgets](https://conecto.chat/docs/teams.md): Teams group a business's keys by department, location or project, keep them to the team's areas, count their spend against a budget and pause at once.
- [Calling tools](https://conecto.chat/docs/calling-tools.md): How a tool call works: the request, the reply envelope, what it costs, safe retries with an Idempotency-Key, background calls and refusals.
- [Approvals](https://conecto.chat/docs/approvals.md): Approval rules hold risky tool calls until a person approves them, and notify_request_approval asks a person before an agent acts.
- [Events and webhooks](https://conecto.chat/docs/events.md): What happens in a business reaches its agent as events. Poll account_events, or send events to Slack, Teams, Telegram or a signed webhook.
- [Money](https://conecto.chat/docs/money.md): How an agent pays on Conecto: one prepaid balance in US dollars, a price for each call, free reads and downloads, top-ups, auto-reload and refunds.
- [Limits](https://conecto.chat/docs/limits.md): The daily budget of each key, the account's monthly ceiling, team budgets, the usage limits every account shares and how to ask for more.
- [The business's own systems](https://conecto.chat/docs/your-systems.md): Work in the company's own HubSpot, Salesforce, Microsoft 365, Google Workspace, Entra ID or Okta, or any REST API, each kept to its allowed calls.
- [Data and security](https://conecto.chat/docs/data-and-security.md): Where each Conecto area keeps and sends its data, how keys and secrets are stored, what the call log and audit log hold, retention and data requests.
- [REST API](https://conecto.chat/docs/api.md): Every route of Conecto's REST API: signing up, the balance, top-ups, auto-reload, limits, keys, calls and tool calls, with fields, statuses and examples.
- [Errors](https://conecto.chat/docs/errors.md): Every error code Conecto's API and tools answer, grouped by HTTP status, with what each means and what to do next. A refused call costs nothing.
- [Event kinds](https://conecto.chat/docs/event-kinds.md): Every event Conecto records for an account, by area, with what it means and the fields its data carries, read from the code that sends it.
- [Tools](https://conecto.chat/docs/tools.md): Where to find each of Conecto's 581 tools: the 52 areas by what a business does with them, each with its tools, prices and MCP server.
- [Files for AI agents](https://conecto.chat/docs/for-agents.md): Every file an AI agent reads to learn and use Conecto: SKILL.md, the facts about Conecto, the tool catalog, OpenAPI, MCP servers and these docs in Markdown.

---

Source: https://conecto.chat/docs

# Conecto docs

Conecto gives an AI agent the tools a business runs on, from a CRM and an inbox to invoices and a phone line. These pages cover what an agent and its developer need to use them.

## Start with one line

Give this line to your agent. It reads the file, signs itself up with one call and keeps its key.

Give this to your agent:

```text
Set up Conecto from https://conecto.chat/SKILL.md
```

The other pages explain what happens behind that line, for the developer who builds the agent and for the agent itself.

## Three ways in

| Way in | Address | Who uses it |
| --- | --- | --- |
| SKILL.md | `https://conecto.chat/SKILL.md` | An agent that reads a file and follows it. It signs up and works from there. |
| MCP servers | `https://api.conecto.chat/mcp/<area>` | Agents and apps that speak MCP. Each of the 52 areas has its own server. |
| REST API | `https://api.conecto.chat/v1` | Your own code, a custom GPT or Copilot Studio, with OpenAPI files to import. |

[Connect your agent](https://conecto.chat/docs/connect.md) shows each one. The [setup pages](https://conecto.chat/agents.md) give the steps for Claude, ChatGPT, Cursor and other agents.

## How it works

- **One call signs up.** `POST /v1/signup` makes the account and its first key, with $1 of free credit. See the [quickstart](https://conecto.chat/docs/quickstart.md).
- **Each tool is one call.** A call runs one of 581 tools across 52 areas, and every reply has the same envelope. See [Calling tools](https://conecto.chat/docs/calling-tools.md).
- **One balance pays.** Each call is paid from a prepaid balance in US dollars, and a call that fails costs nothing. See [Money](https://conecto.chat/docs/money.md).
- **Limits and approvals guard the business.** Budgets cap what each key spends, and approval rules make risky calls wait for a person. See [Limits](https://conecto.chat/docs/limits.md) and [Approvals](https://conecto.chat/docs/approvals.md).

## What is where

| Section | What it covers |
| --- | --- |
| [Get started](https://conecto.chat/docs/quickstart.md) | Signing up, the first call and the ways to connect an agent. |
| [Concepts](https://conecto.chat/docs/accounts.md) | Accounts and people, keys, teams, calling tools, approvals, events, money, limits, the business's own systems, data and security. |
| [Reference](https://conecto.chat/docs/api.md) | Every REST route, every error code, every event and the directory of tools. |
| [For agents](https://conecto.chat/docs/for-agents.md) | The files an agent reads: SKILL.md, the OpenAPI files, the tool catalog and these pages in Markdown. |

## Numbers to know

| What | Amount |
| --- | --- |
| Free credit at signup | $1 |
| A change to a record, like saving a contact | $0.01 |
| Reads free each month, for the whole account | 1,000,000 |
| The smallest top-up | $5, plus a 7% + $0.35 fee |
| The first top-up | Doubled, up to $20 extra |
| The daily budget of a new key | $20 |
| The monthly ceiling of a new account | $100 |
| A call that fails | $0.00 |

## For agents reading this

Every page here has a Markdown twin at its address plus `.md`, like https://conecto.chat/docs/quickstart.md. https://conecto.chat/docs/all.md holds every page in one file, and https://conecto.chat/docs/index.json lists them with their addresses. [For agents](https://conecto.chat/docs/for-agents.md) names every other file an agent can read.

---

Source: https://conecto.chat/docs/quickstart

# Quickstart

One call signs an agent up, and the next one does real work. This page shows both, then the balance and a top-up, in curl, Python and JavaScript.

> **Note:** An agent that reads SKILL.md does all of this on its own. Give it the line `Set up Conecto from https://conecto.chat/SKILL.md` and it signs up, keeps its key and starts working.

## Sign up

`POST https://api.conecto.chat/v1/signup` makes the account and its first key. Send your agent's name as `bot_name` and `accept_terms: true`. That accepts the [terms](https://conecto.chat/terms) for the business you act for, so read them first at https://conecto.chat/terms.md. `business_name` and `owner_email` are optional. The request needs no key.

curl:

```bash
curl -X POST https://api.conecto.chat/v1/signup \
  -H "Content-Type: application/json" \
  -d '{
    "bot_name": "Pip",
    "accept_terms": true,
    "business_name": "Halverson Cycle & Repair",
    "owner_email": "dana@halversoncycle.example"
  }'
```

Python:

```python
import requests

reply = requests.post(
    "https://api.conecto.chat/v1/signup",
    json={
        "bot_name": "Pip",
        "accept_terms": True,
        "business_name": "Halverson Cycle & Repair",
        "owner_email": "dana@halversoncycle.example",
    },
)
print(reply.status_code, reply.json())
```

JavaScript:

```javascript
const reply = await fetch("https://api.conecto.chat/v1/signup", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    bot_name: "Pip",
    accept_terms: true,
    business_name: "Halverson Cycle & Repair",
    owner_email: "dana@halversoncycle.example",
  }),
});
console.log(reply.status, await reply.json());
```

The reply, with status `201`:

```json
{
  "account_id": 4127,
  "business_name": "Halverson Cycle & Repair",
  "key": "conecto_sk_4f9b2c7e1a8d3f6b0e5c9a2d7f1b4e8c",
  "key_note": "Shown once. Send it as \"Authorization: Bearer <key>\" on every call.",
  "balance_usd": "$1.00",
  "free_credit_usd": "$1.00",
  "free_credit_note": null,
  "daily_budget_usd": "$20.00",
  "monthly_ceiling_usd": "$100.00",
  "owner_note": "dana@halversoncycle.example is the owner now, with nothing to confirm: they sign in at conecto.chat/account/login with that address. Only the owner raises limits, and the account's warnings and approval requests go to them.",
  "terms": {
    "version": "2026-10-27",
    "url": "https://conecto.chat/terms",
    "privacy": "https://conecto.chat/privacy",
    "accepted_for": "Halverson Cycle & Repair"
  },
  "next": {
    "tools": "GET /v1/tools",
    "run": "POST /v1/tools/<name> with the arguments as a JSON object",
    "mcp": "Connect https://api.conecto.chat/mcp/<area> with the same Authorization header",
    "top_up": "POST /v1/topups {\"amount_usd\": 20}: your first top-up is doubled, up to $20 extra"
  }
}
```

The address in `owner_email` is the owner at once, with nothing to confirm. `owner_note` says what that means: only the owner raises limits, and the account's warnings and approval requests go to them. [Accounts and people](https://conecto.chat/docs/accounts.md#the-owner) covers an account with no owner yet.

The free credit is $1, for one new account per network a day. A second signup from the same network that day still gets a key, and `free_credit_note` says why it got no credit.

## Keep the key

The key starts with `conecto_sk_` and the reply shows it once. Conecto keeps only a hash of it. Store it where your agent keeps secrets, like an environment variable, and send it on every call:

Header:

```text
Authorization: Bearer conecto_sk_...
```

A key spends the balance, so keep it out of prompts, logs and shared code. A lost key is gone for good: make another with `POST /v1/keys` from a key that works, or ask the owner to make one. [Keys and scopes](https://conecto.chat/docs/keys.md) has the rest.

The samples below read the key from an environment variable:

Terminal:

```bash
export CONECTO_KEY="conecto_sk_..."
```

## Call a tool

Every tool is one call: `POST https://api.conecto.chat/v1/tools/<name>` with the tool's arguments as a JSON object. This one saves a contact in the CRM, for $0.01. It is the tool's documented call, made for Hansen & Voss, a restaurant-equipment wholesaler in Hamburg, so its balance differs from a new account's.

curl:

```bash
curl -X POST https://api.conecto.chat/v1/tools/crm_save_contact \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jana@weber-kuechenplanung.example",
    "name": "Jana Weber",
    "title": "Kitchen planner",
    "company": "Weber Küchenplanung",
    "phone": "+49 40 66969 120",
    "location": "Hamburg",
    "lifecycle_stage": "lead",
    "tags": ["trade", "test-kitchen-visit"]
  }'
```

Python:

```python
import os
import requests

reply = requests.post(
    "https://api.conecto.chat/v1/tools/crm_save_contact",
    headers={"Authorization": f"Bearer {os.environ['CONECTO_KEY']}"},
    json={
        "email": "jana@weber-kuechenplanung.example",
        "name": "Jana Weber",
        "title": "Kitchen planner",
        "company": "Weber Küchenplanung",
        "phone": "+49 40 66969 120",
        "location": "Hamburg",
        "lifecycle_stage": "lead",
        "tags": ["trade", "test-kitchen-visit"],
    },
)
print(reply.status_code, reply.json())
```

JavaScript:

```javascript
const reply = await fetch("https://api.conecto.chat/v1/tools/crm_save_contact", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CONECTO_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    email: "jana@weber-kuechenplanung.example",
    name: "Jana Weber",
    title: "Kitchen planner",
    company: "Weber Küchenplanung",
    phone: "+49 40 66969 120",
    location: "Hamburg",
    lifecycle_stage: "lead",
    tags: ["trade", "test-kitchen-visit"],
  }),
});
console.log(reply.status, await reply.json());
```

The reply:

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "tool": "crm_save_contact",
  "status": "succeeded",
  "replayed": false,
  "cost_usd": "$0.01",
  "balance_usd": "$19.75",
  "result": {
    "contact": {
      "id": 4107,
      "email": "jana@weber-kuechenplanung.example",
      "name": "Jana Weber",
      "title": "Kitchen planner",
      "company": "Weber Küchenplanung",
      "company_id": 4105,
      "phone": "+49 40 66969 120",
      "location": "Hamburg",
      "lifecycle_stage": "lead",
      "outreach_status": null,
      "notes": "",
      "tags": ["test-kitchen-visit", "trade"],
      "custom_fields": {},
      "archived": false,
      "updated_at": "2026-10-14T08:00:00+00:00"
    },
    "created": true
  }
}
```

`cost_usd` is what the call cost and `balance_usd` what is left. `result` is the tool's own answer, and each tool's page in the [tools directory](https://conecto.chat/tools.md) shows it. A call that fails costs nothing. [Calling tools](https://conecto.chat/docs/calling-tools.md) explains every field, retries and calls that run in the background.

## Check the balance

`GET /v1/balance` shows the balance, the key's daily budget, the account's monthly ceiling and where the month's free reads and downloads stand. The `account_balance` tool answers the same.

curl:

```bash
curl https://api.conecto.chat/v1/balance \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Python:

```python
import os
import requests

reply = requests.get(
    "https://api.conecto.chat/v1/balance",
    headers={"Authorization": f"Bearer {os.environ['CONECTO_KEY']}"},
)
print(reply.status_code, reply.json())
```

JavaScript:

```javascript
const reply = await fetch("https://api.conecto.chat/v1/balance", {
  headers: {
    Authorization: `Bearer ${process.env.CONECTO_KEY}`,
  },
});
console.log(reply.status, await reply.json());
```

```json
{
  "balance_usd": "$1.00",
  "reserved_usd": "$0.00",
  "daily_budget_usd": "$20.00",
  "monthly_ceiling_usd": "$100.00",
  "auto_reload": {
    "status": "off",
    "amount_usd": "$0.00"
  },
  "free_this_month": {
    "reads": {
      "free": 1000000,
      "used": 0,
      "bought": 0,
      "price_after": "$0.50 per 10,000 reads"
    },
    "downloads": {
      "free": "5 GB",
      "used": "0 bytes",
      "bought": "0 bytes",
      "free_bytes": 5368709120,
      "used_bytes": 0,
      "bought_bytes": 0,
      "price_after": "$0.30 per GB"
    },
    "resets_at": "2026-11-01T00:00:00+00:00"
  }
}
```

## Top up

Free credit works inside the business. Email, phone calls and documents sent to people outside it need one real top-up first. `POST /v1/topups` with an amount answers with a Stripe checkout link: open it, or hand it to the owner. A top-up is $5 to $5,000 in whole cents, with a 7% + $0.35 fee, and the first one is doubled, up to $20 extra.

curl:

```bash
curl -X POST https://api.conecto.chat/v1/topups \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount_usd": 20, "po_number": "4500012345"}'
```

Python:

```python
import os
import requests

reply = requests.post(
    "https://api.conecto.chat/v1/topups",
    headers={"Authorization": f"Bearer {os.environ['CONECTO_KEY']}"},
    json={
        "amount_usd": 20,
        "po_number": "4500012345",
    },
)
print(reply.status_code, reply.json())
```

JavaScript:

```javascript
const reply = await fetch("https://api.conecto.chat/v1/topups", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CONECTO_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    amount_usd: 20,
    po_number: "4500012345",
  }),
});
console.log(reply.status, await reply.json());
```

```json
{
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_a1B2c3D4e5F6g7H8",
  "amount_usd": "$20.00",
  "fee_usd": "$1.75",
  "total_usd": "$21.75",
  "first_topup_bonus_usd": "$20.00",
  "credited_usd": "$40.00",
  "how": "Open the link, or hand it to your owner. Credit lands within seconds of payment.",
  "po_number": "4500012345"
}
```

The credit lands within seconds of the payment. [Money](https://conecto.chat/docs/money.md) covers auto-reload, refunds and receipts for a company.

## Connect over MCP

An MCP client connects one server for every area the key may use, `https://api.conecto.chat/v1/mcp`, with the same `Authorization` header. This adds Conecto to Claude Code:

Terminal:

```bash
claude mcp add --transport http --scope user conecto https://api.conecto.chat/v1/mcp \
  --header "Authorization: Bearer $CONECTO_KEY"
```

[Connect your agent](https://conecto.chat/docs/connect.md) shows the other ways in, and the [setup pages](https://conecto.chat/agents.md) give the steps for each agent.

## Next

- [Calling tools](https://conecto.chat/docs/calling-tools.md): the reply envelope, safe retries and background calls.
- [Keys and scopes](https://conecto.chat/docs/keys.md): a key for each job, limited to what it needs.
- [Approvals](https://conecto.chat/docs/approvals.md): calls that wait for a person.
- [The tools directory](https://conecto.chat/tools.md): every tool with its inputs, its price and a real reply.

---

Source: https://conecto.chat/docs/connect

# Connect your agent

Every way in reaches the same tools, the same account and the same balance. Use the one your agent supports, or several at once.

## SKILL.md

https://conecto.chat/SKILL.md is the file an agent keeps. It says how to sign up, call tools, pay and keep the business safe, then lists every area with its prices and tools. An agent that reads it signs itself up with one call.

Give this to your agent:

```text
Set up Conecto from https://conecto.chat/SKILL.md
```

Agents that look for skills on their own find it at https://conecto.chat/.well-known/agent-skills/index.json. [For agents](https://conecto.chat/docs/for-agents.md) lists its sections and its digest. A Conecto partner's link adds `?ref=<code>` to the address, and the file then puts their code in its signup example.

## MCP servers

One MCP server holds every area a key may use, `https://api.conecto.chat/v1/mcp`, over Streamable HTTP. Calling a tool needs the key in the `Authorization` header. An agent adds it once, right after signing up, with the key typed in that one command:

Terminal:

```bash
claude mcp add --transport http --scope user conecto https://api.conecto.chat/v1/mcp \
  --header "Authorization: Bearer $CONECTO_KEY"
```

Each area also has a server of its own at `https://api.conecto.chat/mcp/<area>`, for an agent that wants only some areas. Listing its tools needs no key, and it carries the account tools too, like `account_balance`.

A key limited to some areas or tools sees only those in `tools/list`. [Calling tools](https://conecto.chat/docs/calling-tools.md#over-mcp) shows a call and its reply over MCP.

## The connector with sign-in

Assistants that people use, like ChatGPT, Claude and Grok, and agents built in Copilot Studio, sign in with OAuth at one address for every area, `https://api.conecto.chat/v1/mcp`. Add it as a custom connector (in Copilot Studio, a Model Context Protocol tool), sign in to Conecto, tick the areas the app may use and allow it.

- The owner signs in with the session they have on conecto.chat. Anyone else on the account signs in with a link emailed to them, or through the company's single sign-on.
- They pick the account and tick the areas. The business's areas are ticked already, and Select all ticks every one. The connection then runs on a key of its own, limited to those areas, so it shows with the account's other keys and is revoked like them.
- Tools that move money, like topping up, stay out of the connector whatever is ticked.
- A token works only on the connector's address. An access token lasts 1 hour, and a refresh token 30 days.
- Someone on the account besides the owner connects as themselves. The key is theirs, named like "Ben, through Claude", and works within their teams and role. Removing them from the account ends it at once.
- The owner can list the apps people may connect. An app that signs people in from anywhere else is refused.

The sign-in follows OAuth 2.1 with PKCE, dynamic client registration and resource indicators, and refresh tokens change with each use. The connector's metadata is at `https://api.conecto.chat/.well-known/oauth-protected-resource/v1/mcp`, and [For agents](https://conecto.chat/docs/for-agents.md#oauth) shows it.

## REST and OpenAPI

Any code that speaks HTTPS calls `POST https://api.conecto.chat/v1/tools/<name>`. These OpenAPI files describe it:

| File | Address | For |
| --- | --- | --- |
| Every route and tool | `https://api.conecto.chat/v1/openapi.json` | OpenAPI 3.1, for your own code and API clients. |
| One area | `https://api.conecto.chat/v1/openapi/<area>.json` | OpenAPI 3.0, with descriptions short enough for a custom GPT's Actions to import. OpenAI retires custom GPTs on December 11, 2026, so in ChatGPT use the connector. |
| One area, OpenAPI 2.0 | `https://api.conecto.chat/v1/openapi/<area>.swagger.json` | Power Automate, Logic Apps and Copilot Studio. The key goes in the `X-Api-Key` header. |

An area's file also carries the account tools. In the file for a custom GPT, a tool that only reads is marked so ChatGPT can offer to always allow it. [The REST API](https://conecto.chat/docs/api.md) has every route.

## Setup pages for each agent

Each page gives the steps from that agent's own docs, with the addresses to paste.

- [Claude](https://conecto.chat/agents/claude.md): Custom connector.
- [ChatGPT](https://conecto.chat/agents/chatgpt.md): Custom MCP server.
- [Grok](https://conecto.chat/agents/grok.md): Custom connector.
- [Claude Code](https://conecto.chat/agents/claude-code.md): SKILL.md and a setup line.
- [Cursor](https://conecto.chat/agents/cursor.md): mcp.json.
- [Codex](https://conecto.chat/agents/codex.md): SKILL.md and a setup line.
- [Gemini CLI](https://conecto.chat/agents/gemini-cli.md): settings.json.
- [OpenClaw](https://conecto.chat/agents/openclaw.md): SKILL.md and a setup line.
- [Hermes Agent](https://conecto.chat/agents/hermes-agent.md): SKILL.md and a setup line.

## Every area's addresses

Add the areas the business uses. Each link opens the area's tools.



Assistants that sign in use one connector for every area: `https://api.conecto.chat/v1/mcp`. Agents with a key use each area's MCP server.

| Area | MCP server |
| --- | --- |
| [CRM](https://conecto.chat/tools/crm.md) | `https://api.conecto.chat/mcp/crm` |
| [Prospects](https://conecto.chat/tools/prospects.md) | `https://api.conecto.chat/mcp/prospects` |
| [Outreach](https://conecto.chat/tools/outreach.md) | `https://api.conecto.chat/mcp/outreach` |
| [Email](https://conecto.chat/tools/email.md) | `https://api.conecto.chat/mcp/email` |
| [Website chat](https://conecto.chat/tools/chat.md) | `https://api.conecto.chat/mcp/chat` |
| [Phone](https://conecto.chat/tools/phone.md) | `https://api.conecto.chat/mcp/phone` |
| [Calendar](https://conecto.chat/tools/calendar.md) | `https://api.conecto.chat/mcp/calendar` |
| [Help desk](https://conecto.chat/tools/helpdesk.md) | `https://api.conecto.chat/mcp/helpdesk` |
| [Help center](https://conecto.chat/tools/helpcenter.md) | `https://api.conecto.chat/mcp/helpcenter` |
| [Forms](https://conecto.chat/tools/forms.md) | `https://api.conecto.chat/mcp/forms` |
| [Company & email lookups](https://conecto.chat/tools/lookups.md) | `https://api.conecto.chat/mcp/lookups` |
| [Newsletters](https://conecto.chat/tools/newsletters.md) | `https://api.conecto.chat/mcp/newsletters` |
| [Social](https://conecto.chat/tools/social.md) | `https://api.conecto.chat/mcp/social` |
| [Websites](https://conecto.chat/tools/websites.md) | `https://api.conecto.chat/mcp/websites` |
| [Website analytics](https://conecto.chat/tools/analytics.md) | `https://api.conecto.chat/mcp/analytics` |
| [AI visibility](https://conecto.chat/tools/visibility.md) | `https://api.conecto.chat/mcp/visibility` |
| [Links & QR codes](https://conecto.chat/tools/links.md) | `https://api.conecto.chat/mcp/links` |
| [Invoices](https://conecto.chat/tools/invoices.md) | `https://api.conecto.chat/mcp/invoices` |
| [Bookkeeping](https://conecto.chat/tools/books.md) | `https://api.conecto.chat/mcp/books` |
| [Purchasing](https://conecto.chat/tools/purchasing.md) | `https://api.conecto.chat/mcp/purchasing` |
| [Inventory](https://conecto.chat/tools/inventory.md) | `https://api.conecto.chat/mcp/inventory` |
| [Company data](https://conecto.chat/tools/companies.md) | `https://api.conecto.chat/mcp/companies` |
| [Valuation](https://conecto.chat/tools/valuation.md) | `https://api.conecto.chat/mcp/valuation` |
| [Longlists](https://conecto.chat/tools/longlists.md) | `https://api.conecto.chat/mcp/longlists` |
| [Market data](https://conecto.chat/tools/markets.md) | `https://api.conecto.chat/mcp/markets` |
| [Mergers & acquisitions](https://conecto.chat/tools/mergers.md) | `https://api.conecto.chat/mcp/mergers` |
| [HR](https://conecto.chat/tools/hr.md) | `https://api.conecto.chat/mcp/hr` |
| [Hiring](https://conecto.chat/tools/hiring.md) | `https://api.conecto.chat/mcp/hiring` |
| [Whistleblowing](https://conecto.chat/tools/whistleblowing.md) | `https://api.conecto.chat/mcp/whistleblowing` |
| [Directory](https://conecto.chat/tools/directory.md) | `https://api.conecto.chat/mcp/directory` |
| [Microsoft 365](https://conecto.chat/tools/microsoft365.md) | `https://api.conecto.chat/mcp/microsoft365` |
| [Google Workspace](https://conecto.chat/tools/googleworkspace.md) | `https://api.conecto.chat/mcp/googleworkspace` |
| [HubSpot](https://conecto.chat/tools/hubspot.md) | `https://api.conecto.chat/mcp/hubspot` |
| [Salesforce](https://conecto.chat/tools/salesforce.md) | `https://api.conecto.chat/mcp/salesforce` |
| [Connections](https://conecto.chat/tools/connect.md) | `https://api.conecto.chat/mcp/connect` |
| [Import](https://conecto.chat/tools/imports.md) | `https://api.conecto.chat/mcp/imports` |
| [Projects](https://conecto.chat/tools/projects.md) | `https://api.conecto.chat/mcp/projects` |
| [E-signature](https://conecto.chat/tools/esign.md) | `https://api.conecto.chat/mcp/esign` |
| [Documents](https://conecto.chat/tools/documents.md) | `https://api.conecto.chat/mcp/documents` |
| [Files](https://conecto.chat/tools/files.md) | `https://api.conecto.chat/mcp/files` |
| [Tables](https://conecto.chat/tools/tables.md) | `https://api.conecto.chat/mcp/tables` |
| [Views](https://conecto.chat/tools/views.md) | `https://api.conecto.chat/mcp/views` |
| [Notifications](https://conecto.chat/tools/notify.md) | `https://api.conecto.chat/mcp/notify` |
| [Schedules](https://conecto.chat/tools/schedules.md) | `https://api.conecto.chat/mcp/schedules` |
| [Uptime](https://conecto.chat/tools/uptime.md) | `https://api.conecto.chat/mcp/uptime` |
| [Vault](https://conecto.chat/tools/vault.md) | `https://api.conecto.chat/mcp/vault` |
| [Code](https://conecto.chat/tools/code.md) | `https://api.conecto.chat/mcp/code` |
| [Account](https://conecto.chat/tools/account.md) | `https://api.conecto.chat/mcp/account` |
| [Account admin](https://conecto.chat/tools/admin.md) | `https://api.conecto.chat/mcp/admin` |
| [Web](https://conecto.chat/tools/web.md) | `https://api.conecto.chat/mcp/web` |
| [Speech](https://conecto.chat/tools/speech.md) | `https://api.conecto.chat/mcp/speech` |
| [Images](https://conecto.chat/tools/images.md) | `https://api.conecto.chat/mcp/images` |

---

Source: https://conecto.chat/docs/claude-connector

# Conecto in Claude

Claude reaches Conecto through one connector with sign-in. Claude asks before each change, and every call is paid from the business's Conecto balance at the tool's price.

## Connect Claude

1. In Claude, open Customize, then Connectors, and add Conecto. On Team and Enterprise plans, an Owner adds it for the organization first.
2. Sign in to Conecto. The sign-in page emails a link to the account's owner, or to anyone the owner added. A new business creates its account at [conecto.chat/account/signup](https://conecto.chat/account/signup) first, and it starts with $1.00 of free credit.
3. Pick the account, tick the areas Claude may use, and allow it.

Claude Code adds the same connector from a terminal, then signs in from `/mcp`:

Terminal:

```bash
claude mcp add --transport http conecto https://api.conecto.chat/v1/mcp/claude
```

The connector's address is `https://api.conecto.chat/v1/mcp/claude`, and its sign-in metadata is at `https://api.conecto.chat/.well-known/oauth-protected-resource/v1/mcp/claude`.

## What Claude can use

Claude sees the tools of the areas ticked at sign-in, with the account's own tools: the balance, the call log, search, approval rules and requests about a person's data.

| Area | What it holds |
| --- | --- |
| CRM | Contacts, companies, deals, notes and tasks |
| Email | Inboxes on the business's own subdomain |
| Calendar | Booking pages, meeting types and bookings |
| Invoices | Quotes, invoices, credit notes and reminders |
| Books | Accounts, entries, bank statements, reports and VAT returns |
| E-signature | Documents sent for signing, and templates |
| Help desk | Tickets from email and chat, with canned replies |
| Help center | Articles, collections and the help center's design |
| Forms | Forms, their responses and summaries |
| Files | The file store, with search, text and OCR |
| Documents | PDFs, Word templates and PowerPoint decks |
| Projects | Projects, boards and tasks |
| Tables | Tables of rows, with queries and summaries |
| Inventory | Items, stock at each location, and stocktakes |
| Analytics | Website visits, goals, funnels and heatmaps, counted without cookies |
| Websites | Websites Conecto hosts, with their pages and posts |
| Dashboards | Saved dashboards and one-time pages of results |
| Imports | Contacts and companies from a CSV file |
| Purchasing | Suppliers, purchase orders and bills, with the payments recorded against them |
| HR | People, time off requests, documents, training, checklists and policies |
| Admin | Who can open the account, join codes and the business's domains |
| Website chat | The chat on the business's website, which Claude answers, with each reply marked to visitors as an AI agent's |
| Valuation | DCF, LBO, WACC, multiples and forecasts from figures the business gives |
| Whistleblowing | The reporting channel's case numbers and deadlines, never what a report says |
| Images | Images in the file store, resized and converted |
| Schedules | Calls of this connector's tools that run later, once or on a timetable |

## What stays with the main connector

This connector carries the tools that Anthropic's Connectors Directory accepts. The rest of Conecto stays with the [main connector](https://conecto.chat/docs/connect.md#connectors) and [SKILL.md](https://conecto.chat/docs/connect.md#skill-md):

- the phone line and speech, which talk with an AI voice
- the lead finder and outreach
- hiring, and approving or adjusting a person's time off
- refunds of top-ups, and bank transfer files for payments
- newsletters, uptime checks, short links and notifications to outside channels
- connections to other systems, like HubSpot, Salesforce, and Google and Microsoft administration, and files fetched from a web address
- market data, company registers, the mergers database, and live interest and exchange rates

A booking made here never sets up a call before the meeting. A time off request made here waits for a person to decide it, and a schedule made here runs only this connector's tools.

## Changes ask first

Every tool that changes something is marked as one that changes data, so Claude asks before each such call. Tools that only read run without asking. The owner can also hold chosen tools for a person's approval, as [Approvals](https://conecto.chat/docs/approvals.md) describes.

## What it costs

- Each tool shows its price, and each call is paid from the business's prepaid balance. A call that fails costs nothing.
- Reading the business's own data is free up to 1,000,000 reads a month.
- Only a person adds money, on the [account page](https://conecto.chat/account), from $5.00 plus a 7% + $0.35 fee.
- The connection runs on a key of its own, with a daily budget of $20.00 until the owner changes it. The account has a monthly ceiling of $100.00.

[Money](https://conecto.chat/docs/money.md) has the rest.

## What Conecto receives

Conecto receives the tool calls Claude makes, with their arguments, and answers each one. The conversation itself stays with Claude. Conecto keeps a call's input and output for 30 days and the rest of its record for 13 months, as the [privacy notice](https://conecto.chat/privacy.md) explains.

A token works at this connector's address only. An access token lasts 1 hour, and a refresh token 30 days.

## Troubleshooting

- **The sign-in link never arrives.** It goes to the email the account knows for you. Check the spam folder, or ask the owner to add you on the account page.
- **A call answers with an error.** The reply says what happened and how to fix it. `402` means the balance needs a top-up, `429` means a limit was reached, and `approval_required` means a person was asked to approve. [Errors](https://conecto.chat/docs/errors.md) lists every code.
- **An area is missing.** Claude sees the areas ticked at sign-in. To change them, remove Conecto in Claude's Connectors, add it again, and tick the areas.
- **To end the connection,** remove Conecto in Claude's Connectors, or revoke its key on the account page.
- **For help,** write to hello@conecto.chat. For privacy questions, write to legal@conecto.chat.

---

Source: https://conecto.chat/docs/accounts

# Accounts and people

An account belongs to one business. A bot can make it with one call, and the people who run the business join it as owners, admins, members or auditors.

## The account

`POST /v1/signup` makes an account with its first key and its balance. The bot that signs up accepts the terms for the business it acts for, and the account keeps the version it accepted. Everything an agent does happens in that account: its records, its call log, its balance and its keys.

The people who run the business open the account page at https://conecto.chat/account. They sign in with a link emailed to them, which works once, within 30 minutes. The page shows the balance, the calls the bots made, the people, the keys and the rentals.

## The owner

The owner is the person the account answers to. Only the owner raises a spending limit, and the account's warnings and approval requests go to them.

- **Named at signup.** `owner_email` makes that address the owner at once. They have nothing to confirm.
- **Named later.** `account_set_owner_email` emails the person a link to confirm. Nothing changes until they open it.
- **No owner yet.** The bot raises its own limits, and a call that needs a person's approval answers `no_approver`.

`account_owner_link` makes a one-time link that signs the owner in with no password. Its `page` opens it where they are needed, like `people` for a role only the owner gives, or `limits`. A bot hands that link to the owner when something is theirs to do.

A second owner, like a business partner, gets everything the owner gets. Only the owner adds one.

## People on the account

| Role | What they do |
| --- | --- |
| Owner | Everything, including raising limits and adding a second owner. |
| Admin | Keys, rentals and the call log. |
| Billing | Credit, auto-reload and budgets. |
| Auditor | Reads everything and changes nothing. |
| Member | Works in their own teams and connections. |

A bot adds a member or an auditor with `admin_save_person`: their email, their teams or areas, and for an outsider the last day of their access, like a bookkeeper until the year-end. They are told by email. Making someone an admin, a billing person or an owner is the owner's, on the account page. An account holds up to 100 people besides the owner.

`admin_remove_person` takes a person's access away at once, with their own assistants.

## Their own assistants

Anyone on the account can connect their own ChatGPT, Claude or Grok, or a Copilot Studio agent, through a [connector](https://conecto.chat/docs/connect.md#connectors). It acts as that person, within their teams and role, so an auditor's assistant only reads. The call log names them, like "Ben, through Claude", and each call is charged to the person's team that holds the tool's area. The owner can list which apps people may connect.

## Other bots on the same account

A second bot joins the account with a join code. `admin_make_join_code` makes one for a team and its areas, and the code can keep the bot to reading or to drafts. It is shown once, works once, and lasts 7 days unless it is set to any number from 1 to 30.

The other bot signs up with the code in place of the usual fields:

POST /v1/signup:

```json
{"bot_name": "Accounting bot", "join": "conecto_join_..."}
```

Its key works for the code's team, within its areas. The reply has `joined: true` and the key's `scope`, and brings no free credit. The account's balance pays for both bots.

## Colleagues who join by work address

Once the company proves its email domain, colleagues can join on their own.

1. `admin_save_domain` adds the domain, like `hansenvoss.example`, and answers with a TXT record that starts `conecto-verification=`.
2. Once the record is in the domain's DNS, the same tool with `verify: true` proves it.
3. `joining` says what happens next. `request` lets people ask to join, and an owner, an admin or the bot approves each one. `open` lets them join at once as members. `off` stops both. Only the owner turns on `open`.

When someone asks, the bot gets the event `account.join_requested`, and `admin_decide_join_request` lets them in or declines them. People who join come in as members, in the domain's team and areas, and can connect their own assistant. A public email provider, like gmail.com, is refused, since anyone can have an address there. An account holds up to 10 domains, and a person who was declined can ask again after 30 days.

## Who runs the admin tools

The admin area, at `https://api.conecto.chat/mcp/admin`, does what the account page does: people and their teams, join codes for other bots, the company's email domains and requests to join, and bridges. It takes a key of the company-wide team with no areas, tool list or read-only limit, or the assistant of the owner or an admin. On an account with no owner email, any key runs it. What stays the owner's answers `owner_required`, and `account_owner_link` makes them a link to the page for it.

When a bot starts working for a business, `admin_overview` reads the account in one call: the balance, the month's spending, the teams, the people, the systems connected and what the owner said about the business.

## Company sign-in

The owner can connect the company's own identity provider over OpenID Connect, like Okta, Microsoft Entra ID or Google Workspace, at no charge. People on the company's proved domains then sign in through it. With single sign-on required, members on those domains must use it, and the owner keeps the emailed link as a way back in.

---

Source: https://conecto.chat/docs/keys

# 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.

## Sending the key

Send the key as a bearer token on every call that reads or changes the business's data:

Header:

```text
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.

> **Warning:** A key spends the balance. Keep it out of prompts, logs and code you share, and revoke it as soon as it leaks.

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`.

## Making a key

`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:

```bash
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:

```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:

```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());
```

```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"
  }
}
```

### Every field

| 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_budget_usd` | 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. |

### The rules

- 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](https://conecto.chat/docs/limits.md#daily-budget) 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`.

## Scoped keys

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_calls` and `account_dashboard_link`, since the others reach every area. Its maker can name others in `tools`.
- `GET /v1/calls` shows 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](https://conecto.chat/docs/approvals.md#holds-with-no-rule) has the details.

## Listing and revoking

`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.

## Keys for people's assistants

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](https://conecto.chat/docs/accounts.md#assistants) has more.

---

Source: https://conecto.chat/docs/teams

# Teams and budgets

A team is a department, a location or a project. Its keys work in its areas and spend against its budget. Most small businesses need no teams at all.

## The company-wide team

Every account has one team called Company. It holds every key no other team holds, the account's first key among them, and it works in every area. A small business can leave everything there, with no budgets, rules or drafts-only setting, until the owner asks for them.

## Making a team

`account_save_team` makes or changes a team, for $0.001. A key joins a team when it is made, with `team` in `POST /v1/keys`, and it never works outside the team's areas.

| Field | What it does |
| --- | --- |
| `name` | The team's name, like Support, Finance or the Hamburg shop. |
| `new_name` | Renames the team. Its keys, its spend and its budget stay with it. |
| `areas` | The areas its keys may work in. The account tools always work. |
| `read_only` | Its keys only read. |
| `drafts_only` | Every change its keys ask for waits for a person. |
| `monthly_budget_usd` | Its budget for each period. Left empty, the spend is counted with no cap. |
| `budget_period` | `month`, `quarter` or `year`, or `project` for one total that ends on `budget_ends_on`. |
| `budget` | `hard` refuses the call that would pass the budget. `soft` only warns. |
| `alert_percent` | The share of the budget at which the alert goes out. |
| `erp_code` | The team's code in the business's ERP. |
| `mailboxes` | The Microsoft 365 or Google mailboxes its keys may act as. |
| `sees_sensitive` | `false` hides suppliers' bank details and HR notes and contracts from its keys. Only the owner turns it on. |

`account_list_teams` lists the teams with their areas, budgets, the spend of each budget's current period, ERP codes, keys and people.

## Budgets

A team's budget counts what its keys spend. The most a call can cost is held when it starts and settled when it ends, so a burst of calls stays inside a hard budget. Past a hard budget, a call answers `team_budget_reached` with status 429 and costs nothing. A soft budget only warns.

Periods follow the account's calendar: its time zone, UTC until the owner picks another on the account page, and the month its fiscal year starts, January until set. Quarters and years count from that month. A project budget never starts again, and once its end date has passed, a hard one refuses every call until the date moves.

When the spend reaches `alert_percent` of the budget, the bot gets the event `account.budget_alert`, and the owner, the team's managers and the account's billing people get an email, once a period.

Bots make teams, narrow them and pause them. On an account with an owner email, the owner does the rest on the account page: widening a team, letting it write, ending drafts only, softening, raising or removing its budget, changing its period and letting a project run longer. The owner can also raise a budget for a while, and the raise ends on its own.

## Pausing

`account_pause_team` stops every key of a team at once, for free. Their calls answer `team_paused` until the owner starts the team again. It is the quick stop for a bot that misbehaves or a team that spends too fast. The owner can also pause the whole account, and every call then answers `account_paused`.

## Charges for what a team owns

Some charges come with no key behind them: a form's responses, a number's calls, an inbox's tickets. Each lands on the team that owns the thing it came through, and a customer's charge never stops on a team budget. `account_assign_team` gives a form, a meeting type, a job, an inbox, a phone number, a newsletter, the website chat, a rental, a pipeline, a table or a website to a team. Something a bot makes belongs to the bot's team from the start.

## People in teams

A person can be in several teams, and a manager of some of them. Their own assistant works for the first of their teams that allows each tool, and each call is charged to that team. Someone in no team works for the company-wide team. A team's managers approve the calls of a drafts-only team, and a team named in an approval rule approves through its managers, or through all its people when the rule says so.

An account has up to 100 teams.

---

Source: https://conecto.chat/docs/calling-tools

# Calling tools

Every tool is one call over REST or MCP. Every reply comes in the same envelope, with what the call cost and what is left.

## Finding a tool

- Each tool's page in the [tools directory](https://conecto.chat/tools.md) shows its inputs, an example call, a real reply and its errors. Read it before calling a tool for the first time. Its Markdown is at the page's address plus `.md`.
- `GET https://api.conecto.chat/v1/tools` lists every tool, and `?area=crm` one area. `GET https://api.conecto.chat/v1/tools/<name>` gives one tool's input schema. Neither needs a key.
- Over MCP, `tools/list` on an area's server lists its tools with their input schemas and prices.

## Over REST

`POST https://api.conecto.chat/v1/tools/<name>` with the arguments as a JSON object, and the key in the `Authorization` header. The examples on this page are the tools' documented calls, made for the docs' two example businesses: Halverson Cycle & Repair, a bike shop in Portland, and Hansen & Voss, a restaurant-equipment wholesaler in Hamburg.

curl:

```bash
curl -X POST https://api.conecto.chat/v1/tools/crm_save_contact \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jana@weber-kuechenplanung.example",
    "name": "Jana Weber",
    "title": "Kitchen planner",
    "company": "Weber Küchenplanung",
    "phone": "+49 40 66969 120",
    "location": "Hamburg",
    "lifecycle_stage": "lead",
    "tags": ["trade", "test-kitchen-visit"]
  }'
```

Python:

```python
import os
import requests

reply = requests.post(
    "https://api.conecto.chat/v1/tools/crm_save_contact",
    headers={"Authorization": f"Bearer {os.environ['CONECTO_KEY']}"},
    json={
        "email": "jana@weber-kuechenplanung.example",
        "name": "Jana Weber",
        "title": "Kitchen planner",
        "company": "Weber Küchenplanung",
        "phone": "+49 40 66969 120",
        "location": "Hamburg",
        "lifecycle_stage": "lead",
        "tags": ["trade", "test-kitchen-visit"],
    },
)
print(reply.status_code, reply.json())
```

JavaScript:

```javascript
const reply = await fetch("https://api.conecto.chat/v1/tools/crm_save_contact", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CONECTO_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    email: "jana@weber-kuechenplanung.example",
    name: "Jana Weber",
    title: "Kitchen planner",
    company: "Weber Küchenplanung",
    phone: "+49 40 66969 120",
    location: "Hamburg",
    lifecycle_stage: "lead",
    tags: ["trade", "test-kitchen-visit"],
  }),
});
console.log(reply.status, await reply.json());
```

## The reply

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "tool": "crm_save_contact",
  "status": "succeeded",
  "replayed": false,
  "cost_usd": "$0.01",
  "balance_usd": "$19.75",
  "result": {
    "contact": {
      "id": 4107,
      "email": "jana@weber-kuechenplanung.example",
      "name": "Jana Weber",
      "title": "Kitchen planner",
      "company": "Weber Küchenplanung",
      "company_id": 4105,
      "phone": "+49 40 66969 120",
      "location": "Hamburg",
      "lifecycle_stage": "lead",
      "outreach_status": null,
      "notes": "",
      "tags": ["test-kitchen-visit", "trade"],
      "custom_fields": {},
      "archived": false,
      "updated_at": "2026-10-14T08:00:00+00:00"
    },
    "created": true
  }
}
```

| Field | What it is |
| --- | --- |
| `call_id` | The call's id, for `GET /v1/calls/{call_id}` and the call log. |
| `tool` | The tool that ran. |
| `status` | `succeeded`. A background call says `running` first. |
| `replayed` | `true` when the reply repeats an earlier call with the same `Idempotency-Key`. A replay costs nothing. |
| `cost_usd` | What this call cost. |
| `balance_usd` | What the account can spend after it. |
| `result` | The tool's own answer. Each tool's page shows it. |
| `bought` | Only on a read that bought the month's next block of reads: what it bought and what that cost. |

Amounts are strings in US dollars with as many decimals as they need, at least two, like `"$0.01"` or `"$0.0005"`.

## Over MCP

Connect `https://api.conecto.chat/mcp/<area>` with the key in the `Authorization` header, then call `tools/call`. The idempotency key goes in `_meta.idempotencyKey`, and an approval in `_meta.approvalId`.

tools/call, the request:

```json
{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "crm_save_contact",
    "arguments": {
      "email": "jana@weber-kuechenplanung.example",
      "name": "Jana Weber",
      "title": "Kitchen planner",
      "company": "Weber Küchenplanung",
      "phone": "+49 40 66969 120",
      "location": "Hamburg",
      "lifecycle_stage": "lead",
      "tags": ["trade", "test-kitchen-visit"]
    },
    "_meta": {
      "idempotencyKey": "save-jana-weber"
    }
  }
}
```

tools/call, the reply:

```json
{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\n \"call_id\": \"5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93\",\n \"tool\": \"crm_save_contact\",\n \"status\": \"succeeded\",\n \"replayed\": false,\n \"cost_usd\": \"$0.01\",\n \"balance_usd\": \"$19.75\",\n \"result\": {\n  \"contact\": {\n   \"id\": 4107,\n   \"email\": \"jana@weber-kuechenplanung.example\",\n   \"name\": \"Jana Weber\",\n   \"title\": \"Kitchen planner\",\n   \"company\": \"Weber Küchenplanung\",\n   \"company_id\": 4105,\n   \"phone\": \"+49 40 66969 120\",\n   \"location\": \"Hamburg\",\n   \"lifecycle_stage\": \"lead\",\n   \"outreach_status\": null,\n   \"notes\": \"\",\n   \"tags\": [\n    \"test-kitchen-visit\",\n    \"trade\"\n   ],\n   \"custom_fields\": {},\n   \"archived\": false,\n   \"updated_at\": \"2026-10-14T08:00:00+00:00\"\n  },\n  \"created\": true\n }\n}"
      }
    ],
    "structuredContent": {
      "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
      "tool": "crm_save_contact",
      "status": "succeeded",
      "replayed": false,
      "cost_usd": "$0.01",
      "balance_usd": "$19.75",
      "result": {
        "contact": {
          "id": 4107,
          "email": "jana@weber-kuechenplanung.example",
          "name": "Jana Weber",
          "title": "Kitchen planner",
          "company": "Weber Küchenplanung",
          "company_id": 4105,
          "phone": "+49 40 66969 120",
          "location": "Hamburg",
          "lifecycle_stage": "lead",
          "outreach_status": null,
          "notes": "",
          "tags": ["test-kitchen-visit", "trade"],
          "custom_fields": {},
          "archived": false,
          "updated_at": "2026-10-14T08:00:00+00:00"
        },
        "created": true
      }
    },
    "isError": false
  }
}
```

The reply's `structuredContent` holds the same envelope as REST, and `content` holds it as text. A refusal comes back with `isError: true` and the refusal as its text. Without a key, `tools/call` answers with a short text that says how to sign up. A batch of up to 50 messages counts each message toward the rate limits. [JSON-RPC errors](https://conecto.chat/docs/calling-tools.md#rpc-errors) lists what the server itself answers.

## What a call costs

Before a call runs, the most it can cost is held against the balance, the key's daily budget, its team's budget and the account's monthly ceiling. When it ends, the account pays what it really cost and the rest of the hold comes back. A call that fails costs nothing, and its whole hold comes back.

| Model | Tools | How it is charged | For example |
| --- | --- | --- | --- |
| Free | 313 | Costs nothing. A read counts toward the month's free reads. | [`crm_search`](https://conecto.chat/tools/crm/crm_search.md): free up to the month's 1,000,000 reads |
| Per call | 219 | One price for each call that succeeds. | [`crm_save_contact`](https://conecto.chat/tools/crm/crm_save_contact.md): $0.01 |
| Per item | 40 | A price for each thing the call handles, like each record saved or each page read. The most it can cost is held first. | [`crm_save_contacts`](https://conecto.chat/tools/crm/crm_save_contacts.md): $0.01 per record saved |
| Metered | 8 | What the work cost, known once it is done, up to a stated most. AI work is charged at the model's cost plus 40% unless the tool says otherwise. | [`email_send`](https://conecto.chat/tools/email/email_send.md): $0.001 per recipient, plus $0.001 per started MB of attachments for each recipient ($0.001 to one person without attachments), up to $0.52 |
| Quoted | 1 | The price in a quote the tool gives first, up to a stated most. | [`phone_rent_number`](https://conecto.chat/tools/phone/phone_rent_number.md): quoted, up to $25.00 |

Reads are free up to 1,000,000 a month for the whole account. Past that, the read that needs more buys the next 10,000 reads for $0.50 before it runs, and its reply says so in `bought`. [Money](https://conecto.chat/docs/money.md#free-reads) has the details.

## Retrying safely

Send an `Idempotency-Key` header, any string up to 120 characters, to retry without paying twice. A longer one is kept as its SHA-256. Each idempotency key belongs to the API key that sent it.

- The same idempotency key with the same tool and arguments, after a success, answers with the first result, `replayed: true` and a cost of $0.00.
- After a failure, it runs the call again.
- While the first call still runs, it answers `in_progress` with status 409.
- With another tool or other arguments, it answers `idempotency_key_reused` with status 409. Use a new idempotency key for a new request.

A tool that returns a secret runs again on a retry, since the call log never keeps the secret.

## Background calls

A few tools take a while, like transcribing audio or importing a CRM. They answer `202` at once:

curl:

```bash
curl -X POST https://api.conecto.chat/v1/tools/speech_transcribe \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file_id": "7c9e1b3d-5f7a-4c9e-8b1d-3f5a7c9e1b4d",
    "speakers": true,
    "language": "de"
  }'
```

Python:

```python
import os
import requests

reply = requests.post(
    "https://api.conecto.chat/v1/tools/speech_transcribe",
    headers={"Authorization": f"Bearer {os.environ['CONECTO_KEY']}"},
    json={
        "file_id": "7c9e1b3d-5f7a-4c9e-8b1d-3f5a7c9e1b4d",
        "speakers": True,
        "language": "de",
    },
)
print(reply.status_code, reply.json())
```

JavaScript:

```javascript
const reply = await fetch("https://api.conecto.chat/v1/tools/speech_transcribe", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CONECTO_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    file_id: "7c9e1b3d-5f7a-4c9e-8b1d-3f5a7c9e1b4d",
    speakers: true,
    language: "de",
  }),
});
console.log(reply.status, await reply.json());
```

```json
{
  "call_id": "9b7e3c51-2f4a-4d8e-a0c6-71e5d2b8f4a3",
  "tool": "speech_transcribe",
  "status": "running",
  "reserved_usd": "$0.60",
  "poll": "GET /v1/calls/9b7e3c51-2f4a-4d8e-a0c6-71e5d2b8f4a3 (or the account_get_call tool) until status is succeeded or failed. You are charged only when it succeeds."
}
```

Poll `GET /v1/calls/{call_id}`, or call `account_get_call`, until `status` is `succeeded` or `failed`. The hold stays until then, and the call is charged only when it succeeds. These tools run in the background: `account_export_all`, `files_ocr`, `import_from_hubspot`, `import_from_pipedrive`, `import_from_zendesk`, `speech_transcribe` and `visibility_check`.

## When a call is refused

A refused call answers with a status of 400 or more and costs nothing. Its `error` is a code, its `message` says what to do in words written for an agent, and `details`, when there is something to add, holds what is needed to fix it.

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "status": "failed",
  "error": "insufficient_balance",
  "message": "This call costs up to $0.10 and the balance is $0.04. Top up to continue; nothing was charged.",
  "cost_usd": "$0.00",
  "details": {
    "price_usd": "$0.10",
    "balance_usd": "$0.04",
    "top_up": "POST /v1/topups {\"amount_usd\": 20} returns a Stripe checkout link; pay it once and turn on auto-reload so the balance never runs dry.",
    "minimum_usd": 5,
    "fee": "7% + $0.35 per top-up, Stripe's fees passed on",
    "first_topup_offer": "Your first top-up is doubled, up to $20 extra."
  }
}
```

- `402` means top up. The details say how.
- `429` means a limit was reached: a budget, the monthly ceiling or the rate. [Limits](https://conecto.chat/docs/limits.md) says which is which.
- `409` with `approval_required` means a person must approve this exact call first. [Approvals](https://conecto.chat/docs/approvals.md) shows the next step.

[Errors](https://conecto.chat/docs/errors.md) lists every code with its fix, and each tool's page lists the codes that tool can give.

## Limits on a request

- A body is at most 16 MB. A bigger one answers `too_large`. Send big files with `files_upload_link`.
- Text with the NUL character (U+0000) is refused with `invalid_input`.
- Arguments that fail the tool's input schema answer `invalid_input`, and `details.input_schema` holds the schema.
- A tool's secret arguments, like a password, are kept encrypted while the call runs and stored as `[redacted]` after it.

## JSON-RPC errors

An MCP server answers these JSON-RPC errors itself, before any tool runs.

| Code | When |
| --- | --- |
| -32601 | Method not found: ... |
| -32600 | Invalid JSON-RPC request. |
| -32602 | Unknown tool ... in this connector. Call tools/list. |
| -32002 | Too many requests. The message names the limit. |
| -32600 | The request is over 16 MB. Send big files with files_upload_link. |
| -32700 | Parse error: the body is not JSON. |

---

Source: https://conecto.chat/docs/approvals

# Approvals

Some calls should wait for a person, like a big refund or a change to the company's HubSpot. An approval rule holds them, and the agent goes on once someone says yes.

## How a held call goes

1. The agent calls a tool that a rule holds. The call answers `approval_required` with status 409 and costs nothing.
2. The request goes to the approver as a one-time page, by email or through a saved channel like Slack.
3. The approver picks Approve or Decline on that page, with a comment if they like.
4. The agent gets the event `notify.answered` with the answer. `notify_get_approval` shows it too.
5. On Approve, the agent calls the tool again with the same arguments and the approval. That one call runs.

The held call's reply, 409:

```json
{
  "error": "approval_required",
  "approval_id": "3e9a6f12-5c7b-4d81-9f0e-2a6b8c4d1e57",
  "approver": "dana@halversoncycle.example",
  "message": "A person must approve this first: the request went to dana@halversoncycle.example. When notify.answered arrives (or notify_get_approval says Approve), call again with the same arguments and the approval (header X-Conecto-Approval, or _meta.approvalId over MCP). Nothing was charged.",
  "cost_usd": "$0.00"
}
```

The approval goes in the `X-Conecto-Approval` header over REST, or in `_meta.approvalId` over MCP. It fits the exact call it was made for: the same tool with the same arguments. Calling again with the same arguments while the request waits reuses that request, so the approver gets one.

## Approval rules

`account_add_approval_rule` makes a tool wait for a person, for $0.001.

| Field | What it does |
| --- | --- |
| `tool` | The tool to hold. |
| `argument` and `over` | Hold only the calls whose argument is over a number, like `invoices_create_credit_note` when `amount` is over 500. |
| `argument` and `values` | Hold only the calls whose argument is one of some values, like `connect_call` when `method` is POST, PUT, PATCH or DELETE. |
| `approver_email` | A person who approves. |
| `approver_channel` | A saved notify channel that gets the request. |
| `approver_team` and `approvers` | A team that approves, through its `managers` or `everyone` in it. |
| `two_people_over` | Calls whose argument is over this need two different people. |

With no `argument`, every call of the tool waits. `account_list_approval_rules` lists the rules. Bots add rules and tighten them. On an account with an owner email, removing a rule is the owner's, on the account page.

## Who approves

- The person a call is for never approves it: the person an assistant acts as, or the person a bot answers to, its key's `accountable`. In a one-person business, with nobody else on the account, the owner approves their own.
- Calls over `two_people_over` need two different people to approve. One Decline declines it.
- Someone away passes their approvals to their delegate.
- When too few people are left, the owner steps in, then the admins and the billing people. With nobody at all, the call answers `no_approver`.
- Each approver gets a link of their own, so the page knows who answered. A channel's link is shared, so a call with a known requester goes to people by email.

## Holds with no rule

Three holds need no rule:

- A supplier's new or changed bank details, in `purchasing_save_supplier`, always wait for someone else.
- Paying a person's expense claims back to an IBAN never paid before, in `books_repay_claims`, waits the same way.
- Every change from a key or a team set to drafts only waits for its team's managers, or the owner. Reads go through.

## Holds made when a system is connected

On an account with an owner email, connecting some of the company's systems makes rules of its own, with the owner as the approver, unless the tool has a rule already. The request shows what the call would change.

| Connecting with | Waits for the owner | Which calls |
| --- | --- | --- |
| `connect_add` | `connect_set_rules` | Every call |
| `connect_add` | `connect_call` | When `method` is `POST`, `PUT`, `PATCH` or `DELETE` |
| `google_connect` | `google_calendar_cancel` | Every call |
| `google_connect` | `google_drive_upload` | When `if_exists` is `REPLACE` |
| `hubspot_connect` | `hubspot_update` | Every call |
| `m365_connect` | `m365_calendar_cancel` | Every call |
| `m365_connect` | `m365_files_upload` | When `if_exists` is `REPLACE` |
| `salesforce_connect` | `salesforce_update` | Every call |
| `directory_connect` | `directory_suspend_user` | Every call |

[Your own systems](https://conecto.chat/docs/your-systems.md) covers each connection.

## Asking a person yourself

`notify_request_approval` asks a person before the agent acts, with no rule needed: approve or decline, or one of up to 5 options, with an optional comment. It goes through a saved channel or by email as a one-time page, and costs $0.01 a request, $0.02 more by email, up to $0.03. The answer is free.

notify_request_approval, the arguments:

```json
{
  "question": "Refund order 1042 in full ($849)?",
  "details": "The buyer says the Tabor arrived with a bent derailleur hanger and sent two photos.",
  "email": "dana@halversoncycle.example",
  "reference": "order-1042"
}
```

- The first answer reaches the agent as the event `notify.answered`, with the option picked and the comment.
- A request lapses after `expires_in_hours`: 72 hours unless set, 720 at most.
- Anyone holding the link can answer, so send it to the person who decides and nobody else.
- Email follows the account's rules: on free credit, it reaches only the owner.

---

Source: https://conecto.chat/docs/events

# Events and webhooks

When someone outside the agent acts, like booking a meeting or signing a document, Conecto records an event. The agent reads it, or a channel gets it as it happens.

## What an event is

An area records an event when something happens that the agent should hear about: a candidate applies, a customer books, a form comes in, a document is signed, an email arrives, the balance runs low. Each event is kept 30 days, and events and their deliveries are free. [Event kinds](https://conecto.chat/docs/event-kinds.md) lists every kind with the fields its data carries.

| Field | What it is |
| --- | --- |
| `event_id` | A number that grows with each event. Poll with `after` set to the last one you saw. |
| `kind` | What happened, like `calendar.booking_created`. |
| `title` | One line about it. |
| `text` | More words, when there are some. |
| `data` | The facts as JSON. Each kind's fields are on [Event kinds](https://conecto.chat/docs/event-kinds.md). |
| `link` | A page about it, when there is one. |
| `occurred_at` | When it happened. |

## Reading events

`account_events` returns what happened, oldest first. Pass `after` with the last `event_id` you saw, and `kinds` to narrow it, like `calendar.*`. A read is free up to the month's 1,000,000 free reads.

account_events, the arguments:

```json
{
  "after": 1520,
  "kinds": ["calendar.*", "forms.*", "esign.*"]
}
```

account_events, the result:

```json
{
  "events": [
    {
      "event_id": 4101,
      "kind": "calendar.booking_created",
      "title": "Rachel Kim booked Bike fitting",
      "text": "Saturday, October 24, 2026 at 11:30 (America/Los Angeles)",
      "data": {
        "reference": "CUT49YHZ85",
        "meeting_type": "bike-fitting",
        "start": "2026-10-24T11:30:00-07:00",
        "end": "2026-10-24T19:15:00+00:00",
        "name": "Rachel Kim",
        "email": "rachel.kim@example.com",
        "phone": null,
        "source": "bot",
        "reason": null
      },
      "link": null,
      "occurred_at": "2026-10-14T08:00:00+00:00"
    }
  ],
  "next_after": 4101,
  "note": null
}
```

`next_after` is the `event_id` to pass the next time. A channel that gets events as they happen saves the polling.

## Sending events to a channel

A channel is a place the business gets messages: Slack, Microsoft Teams, Discord, Google Chat, a Telegram chat, ntfy, Pushover, or a webhook of its own.

1. `notify_add_channel` saves a channel by name, for $0.001. It sends a test message first, and saves nothing when the test fails to arrive. Its tokens are stored encrypted and never shown back.
2. `notify_subscribe` sends chosen events to it, for $0.001: one kind, every event of an area like `hiring.*`, the events bots send like `custom.*`, or `*` for all of them, up to 30 names. It replaces the channel's list.
3. `notify_unsubscribe` stops them. The channel stays for `notify_send`.

notify_subscribe, the arguments:

```json
{
  "channel": "hiring",
  "events": ["hiring.application_received", "hiring.test_completed"]
}
```

A chat app gets the event's title, its text and its link. A webhook gets the whole event as signed JSON.

Deliveries go out within about a minute. Some kinds go out at once, like a chat message and the answer to an approval, and [Event kinds](https://conecto.chat/docs/event-kinds.md) marks them. A delivery that fails is tried again after 5 minutes and after 30 more, 3 tries in all. A channel gets at most 30 messages a minute, and the rest wait a minute. An account keeps up to 50 channels.

## Webhooks

A webhook channel posts each event to the business's own address, which is how Zapier, Make, n8n or the business's own systems connect. `notify_add_channel` with `kind: "webhook"` and a public https `url` answers with a `webhook_secret`, shown once.

The body of a delivery:

```json
{
  "id": "evt_4101",
  "event": "calendar.booking_created",
  "title": "Rachel Kim booked Bike fitting",
  "text": "Saturday, October 24, 2026 at 11:30 (America/Los Angeles)",
  "data": {
    "reference": "CUT49YHZ85",
    "meeting_type": "bike-fitting",
    "start": "2026-10-24T11:30:00-07:00",
    "end": "2026-10-24T19:15:00+00:00",
    "name": "Rachel Kim",
    "email": "rachel.kim@example.com",
    "phone": null,
    "source": "bot",
    "reason": null
  },
  "link": null,
  "account": "Halverson Cycle & Repair",
  "occurred_at": "2026-10-14T08:00:00+00:00"
}
```

| Header | What it holds |
| --- | --- |
| `Content-Type` | `application/json`. |
| `X-Conecto-Signature` | `sha256=` and the HMAC-SHA256 of the raw body, keyed with the channel's `webhook_secret`, as hex. |
| `X-Conecto-Event` | The event's kind, like `calendar.booking_created`. |
| `X-Conecto-Delivery` | `evt_` and the event's `event_id`. A retry sends the same value. |
| `User-Agent` | `Conecto-Notify/1.0`. |

### Checking the signature

Compute the HMAC-SHA256 of the raw body with the `webhook_secret`, as hex, and compare it with the header in constant time. A retry sends the same `X-Conecto-Delivery`, so drop one you have seen.

Python:

```python
import hashlib
import hmac


def is_from_conecto(body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)
```

JavaScript:

```javascript
import { createHmac, timingSafeEqual } from "node:crypto";

export function isFromConecto(body, header, secret) {
  const expected = "sha256=" + createHmac("sha256", secret).update(body).digest("hex");
  return expected.length === header.length && timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}
```

A message that `notify_send` posts to a webhook is signed the same way. Its body holds `title`, `message`, `link`, `urgent`, `account` and `sent_at`, with no `X-Conecto-Event` header.

## Custom events

A bot names its own events with `account_emit_event`: `custom.` and a name, like `custom.order_shipped`, with a title and up to 10 KB of data. They go to every channel subscribed to them and to `account_events`, where another team's bot can pick them up. Each costs $0.005 per channel it goes to, and `sent_by` is added with the bot's name and team.

---

Source: https://conecto.chat/docs/money

# Money

An account has one prepaid balance in US dollars. Each call is paid from it at the tool's own price, and a call that fails costs nothing.

## The balance

`GET /v1/balance`, or the `account_balance` tool, shows the balance with the key's daily budget, the account's monthly ceiling, auto-reload and the month's free reads and downloads. Checking it never counts as a read.

| Field | What it is |
| --- | --- |
| `balance_usd` | What the account can spend now: its credit, less what running calls hold, plus the reload amount while auto-reload is on. |
| `reserved_usd` | What running calls hold until they settle. |
| `daily_budget_usd` | This key's daily budget. |
| `monthly_ceiling_usd` | The account's monthly ceiling. |
| `auto_reload` | Whether auto-reload is on, and its amount. |
| `free_this_month` | The month's free reads and downloads: what is used, what was bought and when they start again. |

When the balance is empty, the reply also says how to top up, the smallest top-up, the fee and the first top-up's offer.

Every amount is a string in US dollars with as many decimals as it needs, at least two. Prices go down to a millionth of a dollar, like `$0.0005` for some calls.

## Prices

Each tool has its own price, and its page in the [tools directory](https://conecto.chat/tools.md) shows it. A tool is priced in one of five ways:

| Model | Tools | How it is charged | For example |
| --- | --- | --- | --- |
| Free | 313 | Costs nothing. A read counts toward the month's free reads. | [`crm_search`](https://conecto.chat/tools/crm/crm_search.md): free up to the month's 1,000,000 reads |
| Per call | 219 | One price for each call that succeeds. | [`crm_save_contact`](https://conecto.chat/tools/crm/crm_save_contact.md): $0.01 |
| Per item | 40 | A price for each thing the call handles, like each record saved or each page read. The most it can cost is held first. | [`crm_save_contacts`](https://conecto.chat/tools/crm/crm_save_contacts.md): $0.01 per record saved |
| Metered | 8 | What the work cost, known once it is done, up to a stated most. AI work is charged at the model's cost plus 40% unless the tool says otherwise. | [`email_send`](https://conecto.chat/tools/email/email_send.md): $0.001 per recipient, plus $0.001 per started MB of attachments for each recipient ($0.001 to one person without attachments), up to $0.52 |
| Quoted | 1 | The price in a quote the tool gives first, up to a stated most. | [`phone_rent_number`](https://conecto.chat/tools/phone/phone_rent_number.md): quoted, up to $25.00 |

A change to a record, like saving a contact, costs $0.01. Monthly rentals, like an inbox at $1.00 a month, renew from the balance, and [Rentals](https://conecto.chat/docs/money.md#rentals) has the rules.

## Free each month

Every account gets these each calendar month, in UTC:

- **1,000,000 reads.** A read is a call to a free tool that only reads, over REST, MCP or a schedule. Past that, the read that needs more buys 10,000 more for $0.50 before it runs, and its reply says so in `bought`.
- **5 GB of downloads** through the account's download links. Past that, the download that needs more buys 1 GB for $0.30. The first 5 downloads of each copy of the account's own data are free.

A block bought this way shows in the call log as a call of its own, and it lasts until the month ends. When the balance or a budget is short for the next block, the read is refused like a paid call and stays uncounted. These never count, since they show where the account stands, help fix it or answer a person's data request: `account_balance`, `account_find_person`, `account_get_call`, `account_get_limits`, `account_list_calls` and `account_owner_link`.

`free_this_month` in the balance shows where the month stands, and its `resets_at` says when it starts again.

## Top-ups

`POST /v1/topups` with `amount_usd` answers with a Stripe checkout link to pay once. Open it, or hand it to the owner. The credit lands within seconds of the payment.

- A top-up is $5 to $5,000, in whole cents.
- The fee is 7% + $0.35 a top-up: Stripe's fees, passed on.
- The account's first top-up is doubled, up to $20 extra.
- Stripe takes the payment as the merchant of record and sends the receipt and the invoice.

curl:

```bash
curl -X POST https://api.conecto.chat/v1/topups \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount_usd": 20, "po_number": "4500012345"}'
```

Python:

```python
import os
import requests

reply = requests.post(
    "https://api.conecto.chat/v1/topups",
    headers={"Authorization": f"Bearer {os.environ['CONECTO_KEY']}"},
    json={
        "amount_usd": 20,
        "po_number": "4500012345",
    },
)
print(reply.status_code, reply.json())
```

JavaScript:

```javascript
const reply = await fetch("https://api.conecto.chat/v1/topups", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CONECTO_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    amount_usd: 20,
    po_number: "4500012345",
  }),
});
console.log(reply.status, await reply.json());
```

```json
{
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_a1B2c3D4e5F6g7H8",
  "amount_usd": "$20.00",
  "fee_usd": "$1.75",
  "total_usd": "$21.75",
  "first_topup_bonus_usd": "$20.00",
  "credited_usd": "$40.00",
  "how": "Open the link, or hand it to your owner. Credit lands within seconds of payment.",
  "po_number": "4500012345"
}
```

`GET /v1/topups` lists the credit added, newest first: top-ups, bonuses, auto-reloads and free credit, up to the last 100.

### Buying for a company

Add `po_number` with a purchase order number, and it is printed on the receipt and the invoice. At checkout, enter the company's name, and "I'm providing a tax ID" appears for its VAT ID.

## Auto-reload

`POST /v1/auto-reload` with `amount_usd` turns on auto-reload with one Stripe checkout. After that, once the prepaid credit is used, calls can run up to the reload amount past zero. Stripe charges the saved card each time that usage reaches the amount, plus the 7% + $0.35 fee, and the paid invoice refills the balance.

- `GET /v1/auto-reload` shows its status: `off`, `pending` until the first payment, `active`, or `failed` when a card payment failed.
- `POST` again while it is on changes the amount.
- `DELETE /v1/auto-reload` turns it off, and a last invoice bills the usage left.
- A scoped key turns it neither on nor off, and answers `key_scope`.

The reload amount keeps the bounds of a top-up: $5 to $5,000.

## Refunds

`account_refund_topup` refunds a top-up paid in the last 24 hours, while none of it is used. Its credit and the first top-up's bonus leave the balance, the card gets the credit's share back with its tax, and the service fee is kept. The owner can refund on the account page too. In `GET /v1/topups`, `refundable_until` says how long each top-up stays refundable. An auto-reload pays for calls already made, so only a top-up is refunded.

## Free credit

A new account gets $1 of free credit, for one new account per network a day. Free credit pays for work inside the business. Email, calls and documents sent to people outside it need one real top-up, or auto-reload, first. Until then they answer `payment_required_for_outbound`.

AI visibility and the phone (calls, their minutes and a phone number's rent) run only on credit bought with a top-up. Free credit, from signup, a beta invitation or a first top-up's bonus, goes to every other tool, which spends it first. When the credit bought is too little for one of these calls, it answers `purchased_credit_required`. `account_balance` shows both parts: `bought_credit_usd` and `free_and_bonus_credit_usd`.

## Rentals

Some things are rented by the month: inboxes, phone numbers, extra storage, uptime monitors, schedules, analytics sites, websites, the people kept in HR and a public help center. The call that rents one pays the first month. After that it renews from the balance on the same day each month. When the balance is short, the rental gets 7 days' grace, tried again each day, and is then released.

## When the balance runs low

With auto-reload off, the bot gets the event `account.balance_low` when the balance falls to a fifth of what the last top-up left, and `account.balance_empty` when it runs out. The owner gets an email each time, once per top-up. Paid tools then answer `insufficient_balance` with status 402 until someone adds credit. A caller to the business's phone line can still leave a message, for free, and it arrives as `phone.message_left`.

---

Source: https://conecto.chat/docs/limits

# Limits

Three kinds of limit keep an agent in check. Spending limits cap what keys spend, usage limits cap how much an account does, and rate limits cap how fast.

## Spending limits

| Limit | Unless changed | Starts again | When it is reached |
| --- | --- | --- | --- |
| A key's daily budget | $20 | At midnight UTC | `daily_budget_reached`, status 429 |
| A team's budget | No budget | With its period | `team_budget_reached`, status 429 |
| The account's monthly ceiling | $100 | On the 1st, UTC | `monthly_ceiling_reached`, status 429 |
| The balance | $1 at signup | When someone adds credit | `insufficient_balance`, status 402 |

Before a call runs, the most it can cost is held against each of them, and the unused part comes back when it ends. A refused call costs nothing. [Teams and budgets](https://conecto.chat/docs/teams.md#budgets) covers team budgets.

### The daily budget

Each key has a daily budget, $20 unless set. Keys made from a key form a line, and the whole line shares the daily budget of its first key, so making more keys adds no room. A connector a person signs in to through an emailed link or single sign-on gets a daily budget of its own.

### Changing them

`GET /v1/limits` shows the calling key's daily budget and the account's monthly ceiling. `PATCH /v1/limits` lowers either one, at any time.

curl:

```bash
curl -X PATCH https://api.conecto.chat/v1/limits \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"daily_budget_usd": 10}'
```

Python:

```python
import os
import requests

reply = requests.patch(
    "https://api.conecto.chat/v1/limits",
    headers={"Authorization": f"Bearer {os.environ['CONECTO_KEY']}"},
    json={
        "daily_budget_usd": 10,
    },
)
print(reply.status_code, reply.json())
```

JavaScript:

```javascript
const reply = await fetch("https://api.conecto.chat/v1/limits", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.CONECTO_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    daily_budget_usd: 10,
  }),
});
console.log(reply.status, await reply.json());
```

- On an account with an owner email, raising a limit is the owner's. The call answers `owner_required`, and the owner raises it on the account page.
- On an account with no owner email, the bot raises its own.
- A scoped key changes neither, and answers `key_scope`.
- A limit goes up to $1000000.00.

## Usage limits

Every account has the same usage limits, and no plan raises them.

| Limit | Name | Standard | Where it applies |
| --- | --- | --- | --- |
| Actions a minute for the whole business | `calls_per_minute` | 1,200 actions a minute | Everything your AI apps do through Conecto. |
| Actions a minute for each AI app | `key_calls_per_minute` | 600 actions a minute | Everything one AI app does through Conecto. |
| Downloads of one file from one network an hour | `downloads_per_hour` | 30 downloads an hour | Download links. |
| New email addresses a day | `new_email_recipients_per_day` | 20 new addresses a day | Emails to addresses the business never wrote with before. |
| Quotes and invoices emailed a day | `documents_emailed_per_day` | 200 documents a day | Sending quotes and invoices, and their reminders. |
| Purchase orders emailed a day | `orders_emailed_per_day` | 200 orders a day | Sending purchase orders. |
| Phone numbers rented at once | `phone_numbers` | 5 numbers | Renting phone numbers. |
| Meeting confirmation calls a day | `confirmation_calls_per_day` | 50 calls a day | The calls that confirm booked meetings. |
| Connected outside systems | `connections` | 50 connections | Connecting outside systems. |
| Blocks of 10 GB file storage rented at once | `storage_blocks` | 20 blocks | Renting more file storage. |
| Prospects found a month | `prospects_per_month` | 1,000 prospects a month | Prospect searches. |
| Mailboxes connected for outreach | `outreach_mailboxes` | 10 mailboxes | Connecting the business's own mailboxes for outreach campaigns. |

`account_get_limits` lists each one with its standard and current value, the most that can be asked for, and the business's requests with their answers.

### Asking for more

When the business truly needs more, `account_request_limit` asks Conecto, with the limit, the number it needs and why, in 40 to 2,000 characters. A person at Conecto reviews it and approves, maybe with less, or declines. The answer reaches the bot as the event `account.limit_request_answered` and the owner by email. When anyone but the owner asks, the owner hears at once and can withdraw the request on the account page. People ask on the account page too, under Billing.

- Only an account that has topped up asks.
- One request per limit waits at a time, and an account asks at most 5 times in 30 days.
- After a decline, the same limit can be asked for again after 14 days.
- The number is above the account's limit and at most 100 times the standard one.
- The owner, an admin or a key of the company-wide team with no areas, tool list or read-only limit asks.

## Rate limits

Each key makes at most 600 calls a minute, and the whole account 1,200. Past either, a call answers `rate_limited` with status 429: wait a few seconds and call again. Each message of an MCP batch counts as a call. Both are usage limits, so a business that needs more asks for them the same way.

A network signs up at most 20 accounts an hour, and free credit goes to one new account per network a day.

## 402 and 429

- `402` means the balance is short. Top up, and the refusal's `details` hold the amount and the first top-up's offer.
- `429` means a limit was reached. The `error` names which one, and the `message` says when it starts again or who raises it.

---

Source: https://conecto.chat/docs/your-systems

# The business's own systems

A business that already runs HubSpot, Salesforce, Microsoft 365 or Google Workspace keeps them. The agent works in them through Conecto, and their records stay where they are.

## Systems with tools of their own

Four systems have tools of their own. Each connects through the company's own app or account, so the company decides what the agent may reach. Conecto keeps the encrypted credential and the call log, and copies nothing else.

| System | Connect with | What the agent does there |
| --- | --- | --- |
| [HubSpot](https://conecto.chat/tools/hubspot.md) | `hubspot_connect`, with a private app's token | Finds, reads and changes contacts, companies, deals and tickets, and adds notes. |
| [Salesforce](https://conecto.chat/tools/salesforce.md) | `salesforce_connect`, with a connected app and a run-as user | Queries, reads and changes records of any object the run-as user may touch. |
| [Microsoft 365](https://conecto.chat/tools/microsoft365.md) | `m365_connect`, with an app registered in Entra ID | Outlook mail, calendars and OneDrive files, as the mailboxes the company names. |
| [Google Workspace](https://conecto.chat/tools/googleworkspace.md) | `google_connect`, with a service account | Gmail, Google Calendar and Drive, as the mailboxes the company names. |

Each credential is checked before anything is kept. Working in these systems in place of Conecto's own CRM or inbox keeps one source of truth, so the agent leaves their records where they are.

On an account with an owner email, the riskier changes there wait for the owner by default: changing a HubSpot or Salesforce record, canceling an event, replacing a file. [Approvals](https://conecto.chat/docs/approvals.md#connecting) lists each one.

## The company directory

`directory_connect` connects the company's Microsoft Entra ID or Okta. The agent then opens accounts for people who join, keeps titles and departments in step with HR, and suspends people who leave. A suspension waits for the owner's approval by default. [Directory](https://conecto.chat/tools/directory.md) has its tools.

## Any other system

Any system with a REST API, like an ERP or an old help desk, connects with `connect_add`: its https address, its credential and the calls the agent may make.

connect_add, the arguments:

```json
{
  "name": "zendesk",
  "base_url": "https://hansenvoss.zendesk.com/api/v2",
  "auth": "bearer",
  "secret": "zd-example-token",
  "allow": ["GET /tickets*", "PUT /tickets/*"],
  "description": "The old help desk, until the move is done"
}
```

- **Allowed calls.** Each is a method and a path pattern, like `GET /tickets*`, where `*` matches anything. A call outside the list is refused. Up to 50 of them.
- **Credentials.** `bearer`, a `header` of your choice, `basic` or `none`. The credential is kept encrypted and never shown again.
- **Calls.** `connect_call` sends one request inside the allowed calls and answers with the status, the content type and the body, up to 1 MB. `connect_preview` shows exactly what it would send, with the credential hidden.
- **Writes wait.** On an account with an owner email, `POST`, `PUT`, `PATCH` and `DELETE` calls, and changes to the allowed calls, wait for the owner's approval by default.
- **Price.** The first 10,000 calls a month are free. After that a call costs $0.0003 for each started 10 seconds the system takes to answer, up to $0.0012. Adding a connection is free, and listing them counts as one of the month's free reads.

## Systems behind the firewall

A system inside the company's network goes through a bridge: a small program the company runs inside its own network. The bridge connects out to Conecto, collects the calls meant for its systems, checks each one against its own allowed calls and makes it with credentials only it holds. Nothing connects in.

1. `admin_make_bridge` makes a bridge. Its token comes back once, with the program and the steps for IT.
2. `connect_add` with `bridge` and `system` connects a system the bridge serves.
3. `connect_call` on that connection answers `202` at once, and `account_get_call` has the answer once the bridge sends it, usually within seconds. Past the month's free calls, a call through a bridge costs $0.0003, since Conecto waits on nothing.

A bridge that collects no call within 60 seconds fails it with `bridge_offline`, and one that answers no call within 2 minutes of collecting it fails it with `bridge_timeout`. Both cost nothing. An account has up to 10 bridges.

## Moving records in

Records from a tool the business used before move into Conecto with [Imports](https://conecto.chat/tools/imports.md): contacts and companies from a CSV, a whole HubSpot or Pipedrive CRM with its deals, notes and tasks, and Zendesk tickets with their replies. Running an import again updates what changed and adds no duplicates.

---

Source: https://conecto.chat/docs/data-and-security

# Data and security

The business controls its data, and Conecto processes it for the business. This page says where each area's data goes, how keys and secrets are kept and what the logs hold.

## Where the data goes

### Every area

Every area keeps its records in the database and runs on Conecto's servers.

| Place | Where | What it holds |
| --- | --- | --- |
| Amazon Web Services (Amazon RDS for PostgreSQL) | Frankfurt, Germany (eu-central-1) | Every record of the account |
| Google Cloud (Cloud Run) | Belgium (europe-west1) | Every call while it runs. Nothing is kept there |
| Hetzner Online (Conecto's own mail server, CitrusMail) | Helsinki, Finland | The emails Conecto sends for the account: sign-in links, the owner's notices, and invoices, bookings, forms and signing requests sent in the business's name |

### What some areas add

These areas also send data to the places named here.

| Area | Also sends data to |
| --- | --- |
| [Email](https://conecto.chat/tools/email.md) | Amazon Web Services (Amazon SES and S3) |
| [Help desk](https://conecto.chat/tools/helpdesk.md) | Amazon Web Services (Amazon SES and S3) |
| [Newsletters](https://conecto.chat/tools/newsletters.md) | Amazon Web Services (Amazon SES and S3) |
| [Notifications](https://conecto.chat/tools/notify.md) | The places the business sends notifications (Slack, Teams, Discord, Telegram, Pushover, a webhook) and Amazon Web Services (Amazon SES and S3) |
| [Files](https://conecto.chat/tools/files.md) | Google Cloud (Cloud Storage) |
| [Documents](https://conecto.chat/tools/documents.md) | Google Cloud (Cloud Storage) and Google Cloud (Conecto's PDF service) |
| [E-signature](https://conecto.chat/tools/esign.md) | Google Cloud (Cloud Storage), Google Cloud (Conecto's PDF service) and Amazon Web Services (Amazon SES and S3) |
| [Invoices](https://conecto.chat/tools/invoices.md) | Google Cloud (Cloud Storage), Google Cloud (Conecto's PDF service), Amazon Web Services (Amazon SES and S3), European Commission (VIES) and the business's own Stripe account |
| [Bookkeeping](https://conecto.chat/tools/books.md) | Google Cloud (Cloud Storage) |
| [Purchasing](https://conecto.chat/tools/purchasing.md) | Google Cloud (Cloud Storage), Google Cloud (Conecto's PDF service) and Amazon Web Services (Amazon SES and S3) |
| [Import](https://conecto.chat/tools/imports.md) | Google Cloud (Cloud Storage) |
| [Images](https://conecto.chat/tools/images.md) | Google Cloud (Cloud Storage) |
| [Phone](https://conecto.chat/tools/phone.md) | Twilio and ElevenLabs |
| [Speech](https://conecto.chat/tools/speech.md) | ElevenLabs and Google Cloud (Cloud Storage) |
| [Code](https://conecto.chat/tools/code.md) | Hetzner Online (Conecto's code sandbox) |
| [Social](https://conecto.chat/tools/social.md) | Hetzner Online (Conecto's Postiz) and the social networks the business connects |
| [Web](https://conecto.chat/tools/web.md) | Hetzner Online (Conecto's search service, reached through Cloudflare), which asks DuckDuckGo, Google or Bing |
| [Company & email lookups](https://conecto.chat/tools/lookups.md) | Hetzner Online (Conecto's mailbox checker) |
| [Prospects](https://conecto.chat/tools/prospects.md) | Hetzner Online (Conecto's lead research server), OpenRouter, with the AI models it routes to, Hetzner Online (Conecto's search service, reached through Cloudflare), which asks DuckDuckGo, Google or Bing and Hetzner Online (Conecto's mailbox checker) |
| [Outreach](https://conecto.chat/tools/outreach.md) | The business's own mailboxes it connects for outreach (Gmail, Outlook or any other) |
| [AI visibility](https://conecto.chat/tools/visibility.md) | OpenRouter and the AI assistants asked (OpenAI, Anthropic, Google, Perplexity and others) |
| [Calendar](https://conecto.chat/tools/calendar.md) | The business's own Google or Microsoft calendar, when connected, Amazon Web Services (Amazon SES and S3) and Twilio |
| [Website chat](https://conecto.chat/tools/chat.md) | The business's own AI provider, when it answers chats with its own key |
| [Forms](https://conecto.chat/tools/forms.md) | Cloudflare (Turnstile) and Amazon Web Services (Amazon SES and S3) |
| [Hiring](https://conecto.chat/tools/hiring.md) | Google Cloud (Cloud Storage), Amazon Web Services (Amazon SES and S3) and Cloudflare (Turnstile) |
| [HR](https://conecto.chat/tools/hr.md) | Google Cloud (Cloud Storage) and Amazon Web Services (Amazon SES and S3) |
| [Whistleblowing](https://conecto.chat/tools/whistleblowing.md) | Amazon Web Services (Amazon SES and S3) |
| [Account](https://conecto.chat/tools/account.md) | Stripe, Google Cloud (Cloud Storage) and Amazon Web Services (Amazon SES and S3) |
| [Account admin](https://conecto.chat/tools/admin.md) | Amazon Web Services (Amazon SES and S3) |
| [Help center](https://conecto.chat/tools/helpcenter.md) | Google Cloud (Cloud Storage) |
| [Websites](https://conecto.chat/tools/websites.md) | Google Cloud (Cloud Storage) |
| [Valuation](https://conecto.chat/tools/valuation.md) | The Bundesbank, the ECB and the US Treasury and Hetzner Online (Conecto's analysis service) |
| [Company data](https://conecto.chat/tools/companies.md) | The public registers and statistics asked: GLEIF, the SEC, filings.xbrl.org, the French, Norwegian and Finnish company registers, Companies House and Eurostat, Hetzner Online (Conecto's analysis service) and Google Cloud (Cloud Storage) |
| [Longlists](https://conecto.chat/tools/longlists.md) | The public registers and statistics asked: GLEIF, the SEC, filings.xbrl.org, the French, Norwegian and Finnish company registers, Companies House and Eurostat and Hetzner Online (Conecto's analysis service) |
| [Uptime](https://conecto.chat/tools/uptime.md) | Amazon Web Services (Amazon SES and S3) and the places the business sends notifications (Slack, Teams, Discord, Telegram, Pushover, a webhook) |
| [Directory](https://conecto.chat/tools/directory.md) | The business's own Microsoft Entra ID or Okta |
| [Connections](https://conecto.chat/tools/connect.md) | The business's own systems it connects |
| [Microsoft 365](https://conecto.chat/tools/microsoft365.md) | The business's own Microsoft 365 |
| [Google Workspace](https://conecto.chat/tools/googleworkspace.md) | The business's own Google Workspace |
| [HubSpot](https://conecto.chat/tools/hubspot.md) | The business's own HubSpot |
| [Salesforce](https://conecto.chat/tools/salesforce.md) | The business's own Salesforce org |
| [Market data](https://conecto.chat/tools/markets.md) | The statistics offices asked: Eurostat, the US Census Bureau, the US Bureau of Labor Statistics and HMRC |
| [Mergers & acquisitions](https://conecto.chat/tools/mergers.md) | The public registers and statistics asked: GLEIF, the SEC, filings.xbrl.org, the French, Norwegian and Finnish company registers, Companies House and Eurostat |

### The other places

| Place | Where | What it holds |
| --- | --- | --- |
| Amazon Web Services (Amazon SES and S3) | Ireland (eu-west-1) | Emails sent and received. Received originals are kept 30 days |
| The places the business sends notifications (Slack, Teams, Discord, Telegram, Pushover, a webhook) | Where each runs | The notification text |
| Google Cloud (Cloud Storage) | Belgium (europe-west1) | Stored files, PDFs and exports |
| Google Cloud (Conecto's PDF service) | Belgium (europe-west1) | Documents while they are made into PDFs. Nothing is kept |
| European Commission (VIES) | European Union | Customers' VAT IDs, to check them |
| The business's own Stripe account | Where Stripe runs | Its customers' payments |
| Twilio | United States (US1) | Phone numbers, calls and their audio while a call runs |
| ElevenLabs | United States | Audio to transcribe and text to read aloud |
| Hetzner Online (Conecto's code sandbox) | Nuremberg, Germany | The code and its input while it runs. Nothing is kept |
| Hetzner Online (Conecto's Postiz) | Nuremberg, Germany | Posts and connected social accounts |
| The social networks the business connects | Where each network runs | The posts sent to them |
| Hetzner Online (Conecto's search service, reached through Cloudflare), which asks DuckDuckGo, Google or Bing | Helsinki, Finland. The search engines it asks are in the United States | Search queries |
| Hetzner Online (Conecto's mailbox checker) | Helsinki, Finland | The email address being checked |
| Hetzner Online (Conecto's lead research server) | Nuremberg, Germany | A prospect search's brief and the public business pages it reads while it runs |
| OpenRouter, with the AI models it routes to | United States | The brief and public business pages, to judge which businesses and people fit it |
| The business's own mailboxes it connects for outreach (Gmail, Outlook or any other) | Where each provider runs | The campaign emails sent from them and the replies read there. Conecto keeps the encrypted password, the emails it sent and the replies to them |
| OpenRouter | United States | The questions sent on to the AI assistants |
| The AI assistants asked (OpenAI, Anthropic, Google, Perplexity and others) | United States | The questions asked about the business, never its records |
| The business's own Google or Microsoft calendar, when connected | Where that provider runs | Meetings |
| The business's own AI provider, when it answers chats with its own key | Where that provider runs | The conversation and the knowledge chosen for it |
| Cloudflare (Turnstile) | Global network | A check that a person, not a bot, sends a form |
| Stripe | Ireland and the United States | Payments for credit and the payer's details |
| The Bundesbank, the ECB and the US Treasury | Germany and the United States | Which maturities are asked for, nothing of the business's |
| Hetzner Online (Conecto's analysis service) | Helsinki, Finland | The figures to forecast, the annual reports to read and a longlist's business model to rank by, while they are worked on. Nothing a business sends is kept |
| The public registers and statistics asked: GLEIF, the SEC, filings.xbrl.org, the French, Norwegian and Finnish company registers, Companies House and Eurostat | Germany, the EU, Norway, Finland, the UK and the United States | The company names and numbers looked up, never the business's records |
| The business's own Microsoft Entra ID or Okta | Where that directory runs | Its people and groups. Conecto keeps only the connection's secret, encrypted |
| The business's own systems it connects | Where each runs | The requests the agent sends and their answers. Conecto keeps the encrypted credential and the call log |
| The business's own Microsoft 365 | Where its tenant runs | The mail, events and files the agent reads or writes. Conecto keeps the encrypted secret and the call log, and copies nothing else |
| The business's own Google Workspace | Where its domain's data is kept | The mail, events and files the agent reads or writes. Conecto keeps the encrypted key and the call log, and copies nothing else |
| The business's own HubSpot | Where its HubSpot account keeps data | The records the agent reads or writes. Conecto keeps the encrypted token and the call log, and copies nothing else |
| The business's own Salesforce org | Where its org runs | The records the agent reads or writes. Conecto keeps the encrypted secret and the call log, and copies nothing else |
| The statistics offices asked: Eurostat, the US Census Bureau, the US Bureau of Labor Statistics and HMRC | Luxembourg, the United States and the United Kingdom | The industry and product codes asked, never the business's records |


`account_data_locations` gives the agent the same list, area by area, for the business's own records of processing.

## Keys and secrets

- A key is stored as its SHA-256 hash, with its last four characters to tell keys apart. The key itself is shown once, when it is made.
- A key can be kept to some areas, some tools, reading, some networks and an end date. [Keys and scopes](https://conecto.chat/docs/keys.md) has the fields.
- A tool's secret arguments, like a password or a token, are encrypted while the call waits or runs, and kept as `[redacted]` once it ends. The call log and the API show `[redacted]` in their place.
- A tool's secret answer reaches the bot, and the call log keeps `[redacted]` in its place.
- The credentials of connected systems and notify channels are stored encrypted and never shown back.
- The [Vault](https://conecto.chat/tools/vault.md) keeps the business's own secrets encrypted. A read of one is counted and stays out of the call log.

## The call log

Every call is logged with the key that made it, its status, what it cost and what it was given and answered. `GET /v1/calls`, the `account_list_calls` tool and the Activity page of the account show it. A scoped key sees its own calls only. A call's input and output are cleared 30 days after it was made, and the rest of its record is deleted after 13 months. When the business erases a person, the calls that name them lose their contents at once.

`account_audit_log` lists the account's admin and security actions, like keys made and revoked, newest first, with a check that none was changed or removed.

## Approvals and limits

Approval rules make risky calls wait for a person, like a refund over an amount or a change in the company's HubSpot, and the request shows what the call would change. Each key spends within its daily budget, the account within its monthly ceiling, and a team within its budget. [Approvals](https://conecto.chat/docs/approvals.md) and [Limits](https://conecto.chat/docs/limits.md) explain both.

## How long things are kept

- Events are kept 30 days.
- The originals of received emails are kept 30 days.
- An account with no activity for two years is deleted, with warnings to the owner 60 and 14 days before. Activity is a key making a call, or a payment. An account that holds credit, or rents something, stays.
- An account that issued invoices or keeps books stays, dormant, until its newest invoice, book entry, bill or bank line is 10 years old, counted from the end of its year. With the warnings, the owner gets every invoice as PDFs and the books, to keep.

## Requests from people about their data

The business answers people who ask to see their data, take it with them or have it erased, and Conecto's tools do the work. Confirming that the person asking is the person named is the business's job.

- `account_find_person` finds every record about one person, by email or phone number.
- `account_export_person` puts their records and files in one ZIP with a download link to give them.
- `account_erase_person` erases them across every area and says what it kept and why, like invoices the law keeps.
- `account_export_all` exports everything the account holds as ZIP files: every record as JSON Lines, and the stored files.

## Rules that protect people outside the business

- On free credit, the agent contacts nobody outside the business. Email, phone numbers, documents sent outside and newsletters need one real top-up first.
- Email to addresses the business never wrote with before is capped at 20 a day. Replies have no cap.
- A Conecto inbox never writes first to an address found with prospect search or Conecto's lookups, or checked with them, and answers `found_by_lookup` with status 422. Once that person writes to the business, the inbox answers them like anyone else.
- Newsletters go out through the business's own email service, to people who confirmed. An invitation says how the people asked to hear from the business.
- The only phone calls going out are calls that confirm meetings booked in advance.
- A phone line's greeting tells callers they reached an automated line, and a greeting without that is refused.
- An email an agent writes to someone ends with a line saying the business's AI assistant wrote it. A reply a person at the business writes through the agent carries no such line.

### The cold-email check

Before an email goes to someone who never wrote to the business, Perplexity's decision model reads it through OpenRouter and judges whether it is cold outreach: a sales pitch, prospecting, link building, a partnership ask or a request for a meeting, sent to people with no tie to the business. Newsletter issues and invitations go through the same check. The model reads the subject and the words, with the number of recipients and never their addresses.

- A cold email stays unsent and answers `cold_email` with status 422. Nothing is charged.
- When the check is down, nothing goes out and the call answers `check_unavailable` with status 503. Call again in a minute. A newsletter issue stays scheduled and goes once it passes.
- Replies, email to people who wrote first, and email to the owner and the account's people skip the check.

### When email pauses

The account's email pauses at once, until Conecto reviews it, when:

- The cold-email check refuses 3 within 7 days. Emails, newsletter issues and invitations all count.
- Over the last 30 days, with at least 50 sent, more than 2% bounced or more than 0.1% complained. Newsletters through the business's own email service count on their own: the hard bounces the service reports, and every reader who presses "I never signed up for this" on the unsubscribe page.

While it is paused, every email answers `sending_paused` with status 403. Newsletter issues already scheduled wait, and sending a new one answers `sending_unavailable`.

## Terms and privacy

The bot that signs up accepts the [terms](https://conecto.chat/terms) for the business, with their data processing terms, and the account keeps the version, 2026-10-27. The [privacy notice](https://conecto.chat/privacy) says how Conecto handles personal data.

---

Source: https://conecto.chat/docs/api

# REST API

The REST API signs an agent up, runs every tool and looks after the account. This page lists every route with what it takes, what it answers and an example.

## Basics

- **Base address.** `https://api.conecto.chat`. Every route below starts there.
- **Keys.** Send the key as `Authorization: Bearer <key>`. `X-Api-Key: <key>` works too. The routes for discovery need no key. [Keys and scopes](https://conecto.chat/docs/keys.md)
- **Bodies.** JSON, with `Content-Type: application/json`, up to 16 MB.
- **Amounts.** Strings in US dollars with as many decimals as they need, at least two, like `"$0.01"`. Amounts you send, like `amount_usd`, are numbers.
- **Times.** ISO 8601 in UTC, like `2026-10-14T08:00:00+00:00`.
- **Refusals.** A status of 400 or more, with `error` and `message`, and nothing charged. [Errors](https://conecto.chat/docs/errors.md)
- **OpenAPI.** https://api.conecto.chat/v1/openapi.json describes every route here and every tool.

The balance and the call log also have tools, `account_balance`, `account_list_calls` and `account_get_call`, so an agent on MCP reaches them too.

## Sign up and get a key

`POST https://api.conecto.chat/v1/signup`

Makes the account, its first key and $1 of free credit. With `join`, it makes a key on the company's account instead, for the team and areas the code names. That reply has `joined` and `scope`, and no free credit, ceiling, terms or `owner_note`.

It needs no key.

### Body

| Field | Type | What it is |
| --- | --- | --- |
| `bot_name` (required) | string | The bot's name, as the call log shows it. 1 to 80 characters. |
| `accept_terms` (required) | boolean | Must be true. It accepts the terms, with their data processing terms, for the business you act for. |
| `business_name` | string | The business the account is for. Without it the account is called after the bot. |
| `owner_email` | string (email) | The owner's address. It makes them the owner at once, with nothing to confirm. |
| `country` | string | The business's country as two letters, like US or DE. |
| `runtime` | string | What the agent runs in, like n8n or Claude Code. It shows beside the key. |
| `website` | string | The business's website. |
| `referral` | string | A Conecto partner's code, if a partner sent you. It only counts at signup. |
| `join` | string | A join code the company gave you, in place of signing up alone. |
| `accountable` | string | The person who answers for the key. |

### Reply 201

The key (shown once) and the balance.

| Field | Type | What it is |
| --- | --- | --- |
| `account_id` | integer | The account's number. |
| `business_name` | string | The business the account is for. |
| `key` | string | The key. It is shown once. |
| `key_note` | string | How to send the key. |
| `balance_usd` | string | What the account can spend now: its credit, less what running calls hold, plus the reload amount while auto-reload is on. |
| `free_credit_usd` | string | The free credit this signup got. |
| `free_credit_note` | string or null | Why this signup got no free credit, when it got none. |
| `daily_budget_usd` | string | This key's daily budget. |
| `monthly_ceiling_usd` | string | The account's monthly ceiling. |
| `owner_note` | string | What the owner email means: whether anyone has something to confirm, and who raises limits. |
| `terms` | object | The terms accepted: their version, their addresses and the business they were accepted for. |
| `next` | object | The next calls to make, in words. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 400 | [`invalid_input`](https://conecto.chat/docs/errors.md#invalid_input) | The arguments do not fit the tool: a field is missing, has the wrong type or is out of range, or a value is not one the tool takes. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl -X POST https://api.conecto.chat/v1/signup \
  -H "Content-Type: application/json" \
  -d '{
    "bot_name": "Pip",
    "accept_terms": true,
    "business_name": "Halverson Cycle & Repair",
    "owner_email": "dana@halversoncycle.example"
  }'
```

Reply 201:

```json
{
  "account_id": 4127,
  "business_name": "Halverson Cycle & Repair",
  "key": "conecto_sk_4f9b2c7e1a8d3f6b0e5c9a2d7f1b4e8c",
  "key_note": "Shown once. Send it as \"Authorization: Bearer <key>\" on every call.",
  "balance_usd": "$1.00",
  "free_credit_usd": "$1.00",
  "free_credit_note": null,
  "daily_budget_usd": "$20.00",
  "monthly_ceiling_usd": "$100.00",
  "owner_note": "dana@halversoncycle.example is the owner now, with nothing to confirm: they sign in at conecto.chat/account/login with that address. Only the owner raises limits, and the account's warnings and approval requests go to them.",
  "terms": {
    "version": "2026-10-27",
    "url": "https://conecto.chat/terms",
    "privacy": "https://conecto.chat/privacy",
    "accepted_for": "Halverson Cycle & Repair"
  },
  "next": {
    "tools": "GET /v1/tools",
    "run": "POST /v1/tools/<name> with the arguments as a JSON object",
    "mcp": "Connect https://api.conecto.chat/mcp/<area> with the same Authorization header",
    "top_up": "POST /v1/topups {\"amount_usd\": 20}: your first top-up is doubled, up to $20 extra"
  }
}
```

## Check the balance

`GET https://api.conecto.chat/v1/balance`

The balance, this key's daily budget, the account's monthly ceiling, auto-reload and the month's free reads and downloads. With an empty balance it also says how to top up.

Send the key as `Authorization: Bearer <key>`.

### Reply 200

The balance and limits.

| Field | Type | What it is |
| --- | --- | --- |
| `balance_usd` | string | What the account can spend now: its credit, less what running calls hold, plus the reload amount while auto-reload is on. |
| `reserved_usd` | string | What running calls hold until they settle. |
| `daily_budget_usd` | string | This key's daily budget. |
| `monthly_ceiling_usd` | string | The account's monthly ceiling. |
| `auto_reload` | object | Whether auto-reload is on, and its amount. |
| `auto_reload.status` | string | `off`, `pending` (waiting for the first payment), `active` or `failed` (a card payment failed). |
| `auto_reload.amount_usd` | string | The reload amount. |
| `free_this_month` | object | The month's free reads and downloads: what is used, what was bought and when they start again. |
| `top_up` | string | Only when the balance is empty: how to top up. |
| `minimum_usd` | integer | Only when the balance is empty: the smallest top-up. |
| `fee` | string | Only when the balance is empty: the fee on a top-up. |
| `first_topup_offer` | string or null | Only when the balance is empty: the first top-up's bonus. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl https://api.conecto.chat/v1/balance \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Reply 200:

```json
{
  "balance_usd": "$1.00",
  "reserved_usd": "$0.00",
  "daily_budget_usd": "$20.00",
  "monthly_ceiling_usd": "$100.00",
  "auto_reload": {
    "status": "off",
    "amount_usd": "$0.00"
  },
  "free_this_month": {
    "reads": {
      "free": 1000000,
      "used": 0,
      "bought": 0,
      "price_after": "$0.50 per 10,000 reads"
    },
    "downloads": {
      "free": "5 GB",
      "used": "0 bytes",
      "bought": "0 bytes",
      "free_bytes": 5368709120,
      "used_bytes": 0,
      "bought_bytes": 0,
      "price_after": "$0.30 per GB"
    },
    "resets_at": "2026-11-01T00:00:00+00:00"
  }
}
```

## List the credit added

`GET https://api.conecto.chat/v1/topups`

The newest 100 entries of credit added: top-ups, first top-up bonuses, auto-reloads and free credit. A top-up says until when the `account_refund_topup` tool can refund it.

Send the key as `Authorization: Bearer <key>`.

### Reply 200

The credit added.

| Field | Type | What it is |
| --- | --- | --- |
| `credits` | array of objects | The credit added, newest first: top-ups, first top-up bonuses, auto-reloads and free credit. |
| `credits[].id` | integer | The entry's number. `account_refund_topup` takes a top-up's number as `topup_id`. |
| `credits[].kind` | string | What added it: `topup`, `bonus`, `auto_reload` or `free_credit`. |
| `credits[].amount_usd` | string | The credit added. |
| `credits[].at` | string | When it was added. |
| `credits[].note` | string or null | Its note, like the purchase order number of a top-up. |
| `credits[].refundable_until` | string or null | Until when a top-up can be refunded. null once the window has closed or part of it was used. |
| `refunds` | string | How a top-up is refunded. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl https://api.conecto.chat/v1/topups \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Reply 200:

```json
{
  "credits": [
    {
      "id": 813,
      "kind": "bonus",
      "amount_usd": "$20.00",
      "at": "2026-10-14T09:12:00+00:00",
      "note": "First top-up doubled"
    },
    {
      "id": 812,
      "kind": "topup",
      "amount_usd": "$20.00",
      "at": "2026-10-14T09:12:00+00:00",
      "note": "Top-up, PO 4500012345",
      "refundable_until": "2026-10-15T09:12:00+00:00"
    },
    {
      "id": 790,
      "kind": "free_credit",
      "amount_usd": "$1.00",
      "at": "2026-10-14T08:00:00+00:00",
      "note": "Free signup credit"
    }
  ],
  "refunds": "An unused top-up can be refunded within 24 hours with the account_refund_topup tool; the fee is kept."
}
```

## Top up the balance

`POST https://api.conecto.chat/v1/topups`

A Stripe checkout link to pay once for credit, from $5 to $5,000 in whole cents. `po_number` prints a purchase order number on the receipt and the invoice.

Send the key as `Authorization: Bearer <key>`.

### Body

| Field | Type | What it is |
| --- | --- | --- |
| `amount_usd` (required) | number | The credit to buy, in US dollars, in whole cents. |
| `po_number` | string | A purchase order number. It is printed on the receipt and the invoice. |

### Reply 201

A Stripe checkout link to pay once.

| Field | Type | What it is |
| --- | --- | --- |
| `checkout_url` | string | Stripe's checkout page. Open it, or hand it to the owner, and pay once. |
| `amount_usd` | string | The credit bought, before the fee. |
| `fee_usd` | string | The service fee on this top-up. |
| `total_usd` | string | What the card pays. |
| `first_topup_bonus_usd` | string | The bonus credit this top-up brings, when it is the account's first. |
| `credited_usd` | string | The credit the balance gets once it is paid. |
| `po_number` | string | The purchase order number, when one was given. |
| `how` | string | What happens next, in words. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 400 | [`invalid_input`](https://conecto.chat/docs/errors.md#invalid_input) | The arguments do not fit the tool: a field is missing, has the wrong type or is out of range, or a value is not one the tool takes. |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl -X POST https://api.conecto.chat/v1/topups \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount_usd": 20, "po_number": "4500012345"}'
```

Reply 201:

```json
{
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_a1B2c3D4e5F6g7H8",
  "amount_usd": "$20.00",
  "fee_usd": "$1.75",
  "total_usd": "$21.75",
  "first_topup_bonus_usd": "$20.00",
  "credited_usd": "$40.00",
  "how": "Open the link, or hand it to your owner. Credit lands within seconds of payment.",
  "po_number": "4500012345"
}
```

## Check auto-reload

`GET https://api.conecto.chat/v1/auto-reload`

Whether auto-reload is on, and its amount.

Send the key as `Authorization: Bearer <key>`.

### Reply 200

Whether auto-reload is on, and its amount.

| Field | Type | What it is |
| --- | --- | --- |
| `status` | string | `off`, `pending` (waiting for the first payment), `active` or `failed` (a card payment failed). |
| `amount_usd` | string | The reload amount. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl https://api.conecto.chat/v1/auto-reload \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Reply 200:

```json
{
  "status": "off",
  "amount_usd": "$20.00"
}
```

## Turn auto-reload on, or change its amount

`POST https://api.conecto.chat/v1/auto-reload`

When auto-reload is off, it answers 201 with a Stripe checkout link to pay once. After that the card is charged each time the bots use the amount, plus the top-up fee. When it is on, it changes the amount and answers 200. A scoped key answers `key_scope`.

Send the key as `Authorization: Bearer <key>`.

### Body

| Field | Type | What it is |
| --- | --- | --- |
| `amount_usd` | number | The reload amount in US dollars, in whole cents. Left out, it keeps the amount set before. |

### Reply 200

It was on: the new amount.

| Field | Type | What it is |
| --- | --- | --- |
| `status` | string | `pending` until the first payment, or `active` when it was on already. |
| `amount_usd` | string | The reload amount. |

### Reply 201

Pay once through the link to turn it on.

| Field | Type | What it is |
| --- | --- | --- |
| `status` | string | `pending` until the first payment, or `active` when it was on already. |
| `checkout_url` | string | Stripe's checkout page. Open it, or hand it to the owner, and pay once. |
| `amount_usd` | string | The reload amount. |
| `how` | string | What happens next, in words. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 400 | [`invalid_input`](https://conecto.chat/docs/errors.md#invalid_input) | The arguments do not fit the tool: a field is missing, has the wrong type or is out of range, or a value is not one the tool takes. |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`key_scope`](https://conecto.chat/docs/errors.md#key_scope) | The key's scope doesn't cover this: another area, a tool it isn't given or is denied, a change by a read-only key, or a setting only a key without limits changes. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |
| 503 | [`unavailable`](https://conecto.chat/docs/errors.md#unavailable) | The tool, or a service it needs, is not available right now (or not switched on yet). Nothing was charged. |

### Example

Request:

```bash
curl -X POST https://api.conecto.chat/v1/auto-reload \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount_usd": 20}'
```

Reply 201:

```json
{
  "status": "pending",
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_b2C3d4E5f6G7h8I9",
  "amount_usd": "$20.00",
  "how": "Pay once through the link; after that the card is charged automatically each time your bots use the reload amount, plus the 7% + $0.35 fee each time."
}
```

## Turn auto-reload off

`DELETE https://api.conecto.chat/v1/auto-reload`

Turns auto-reload off, and a last invoice bills the usage left. A scoped key answers `key_scope`.

Send the key as `Authorization: Bearer <key>`.

### Reply 200

Off.

| Field | Type | What it is |
| --- | --- | --- |
| `status` | string | `off`. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`key_scope`](https://conecto.chat/docs/errors.md#key_scope) | The key's scope doesn't cover this: another area, a tool it isn't given or is denied, a change by a read-only key, or a setting only a key without limits changes. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl -X DELETE https://api.conecto.chat/v1/auto-reload \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Reply 200:

```json
{
  "status": "off"
}
```

## Check the limits

`GET https://api.conecto.chat/v1/limits`

This key's daily budget and the account's monthly ceiling.

Send the key as `Authorization: Bearer <key>`.

### Reply 200

This key's daily budget and the account's monthly ceiling.

| Field | Type | What it is |
| --- | --- | --- |
| `daily_budget_usd` | string | This key's daily budget. |
| `monthly_ceiling_usd` | string | The account's monthly ceiling. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl https://api.conecto.chat/v1/limits \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Reply 200:

```json
{
  "daily_budget_usd": "$20.00",
  "monthly_ceiling_usd": "$100.00"
}
```

## Lower the limits

`PATCH https://api.conecto.chat/v1/limits`

Lowers this key's daily budget or the account's monthly ceiling, at any time. On an account with an owner email, raising either is the owner's and answers `owner_required`. A scoped key answers `key_scope`.

Send the key as `Authorization: Bearer <key>`.

### Body

| Field | Type | What it is |
| --- | --- | --- |
| `daily_budget_usd` | number | Its daily budget. On an account with an owner email, at most this key's. |
| `monthly_ceiling_usd` | number | The account's monthly ceiling. |

### Reply 200

The limits now.

| Field | Type | What it is |
| --- | --- | --- |
| `daily_budget_usd` | string | This key's daily budget. |
| `monthly_ceiling_usd` | string | The account's monthly ceiling. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 400 | [`invalid_input`](https://conecto.chat/docs/errors.md#invalid_input) | The arguments do not fit the tool: a field is missing, has the wrong type or is out of range, or a value is not one the tool takes. |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`key_scope`](https://conecto.chat/docs/errors.md#key_scope) | The key's scope doesn't cover this: another area, a tool it isn't given or is denied, a change by a read-only key, or a setting only a key without limits changes. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 403 | [`owner_required`](https://conecto.chat/docs/errors.md#owner_required) | Only the owner may raise a spending limit or give a new key more daily budget than the key making it. The account page's own tools, and asking Conecto for a higher limit, take the owner, an admin or a key of the company-wide team without limits. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl -X PATCH https://api.conecto.chat/v1/limits \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"daily_budget_usd": 10}'
```

Reply 200:

```json
{
  "daily_budget_usd": "$10.00",
  "monthly_ceiling_usd": "$100.00"
}
```

## List the keys

`GET https://api.conecto.chat/v1/keys`

The account's keys that work, with their scopes. `current` marks the key making the call.

Send the key as `Authorization: Bearer <key>`.

### Reply 200

The keys that work.

| Field | Type | What it is |
| --- | --- | --- |
| `keys` | array of objects | The account's keys that work. |
| `keys[].key_id` | integer | The key's number. `DELETE /v1/keys/{key_id}` revokes it. |
| `keys[].bot_name` | string | The name it was made with. |
| `keys[].runtime` | string | What it runs in, when it said. |
| `keys[].last4` | string | The key's last four characters. |
| `keys[].daily_budget_usd` | string | Its daily budget. |
| `keys[].current` | boolean | true for the key making this call. |
| `keys[].scope` | object | What the key may do: its areas, tools, tools it may not run, reading only, drafts only, end date, networks, team and the person who answers for it. null means no limit. |
| `keys[].scope.areas` | array or null | The areas it works in. |
| `keys[].scope.tools` | array or null | The only tools it may run. |
| `keys[].scope.deny_tools` | array or null | Tools it may not run. |
| `keys[].scope.read_only` | boolean | It only reads. |
| `keys[].scope.drafts_only` | boolean | Every change it makes waits for a person. |
| `keys[].scope.expires_at` | string or null | It stops working at this time, as ISO 8601 with its offset. |
| `keys[].scope.networks` | array or null | The addresses or ranges it may be used from. |
| `keys[].scope.team` | string or null | Its team. |
| `keys[].scope.accountable` | string or null | The person who answers for the key. |
| `keys[].last_used_at` | string or null | When it last made a call. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl https://api.conecto.chat/v1/keys \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Reply 200:

```json
{
  "keys": [
    {
      "key_id": 4127,
      "bot_name": "Pip",
      "runtime": "n8n",
      "last4": "4e8c",
      "daily_budget_usd": "$20.00",
      "current": true,
      "scope": {
        "areas": null,
        "tools": null,
        "deny_tools": null,
        "read_only": false,
        "drafts_only": false,
        "expires_at": null,
        "networks": null,
        "team": "Company",
        "accountable": null
      },
      "last_used_at": "2026-10-14T09:30:00+00:00"
    }
  ]
}
```

## Make a key

`POST https://api.conecto.chat/v1/keys`

A key for another bot or job, within this key's scope and team. It shares the daily budget of its line's first key. An account has at most 25 keys that work.

Send the key as `Authorization: Bearer <key>`.

### Body

| 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_budget_usd` | 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. |

### Reply 201

The new key (shown once) and its scope.

| Field | Type | What it is |
| --- | --- | --- |
| `key_id` | integer | The new key's number. |
| `key` | string | The key. It is shown once. |
| `key_note` | string | How to send the key. |
| `daily_budget_usd` | string | This key's daily budget. |
| `scope` | object | What the key may do: its areas, tools, tools it may not run, reading only, drafts only, end date, networks, team and the person who answers for it. null means no limit. A person's own assistant shows the person and their teams. |
| `scope.areas` | array or null | The areas it works in. |
| `scope.tools` | array or null | The only tools it may run. |
| `scope.deny_tools` | array or null | Tools it may not run. |
| `scope.read_only` | boolean | It only reads. |
| `scope.drafts_only` | boolean | Every change it makes waits for a person. |
| `scope.expires_at` | string or null | It stops working at this time, as ISO 8601 with its offset. |
| `scope.networks` | array or null | The addresses or ranges it may be used from. |
| `scope.team` | string or null | Its team. |
| `scope.accountable` | string or null | The person who answers for the key. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 400 | [`invalid_input`](https://conecto.chat/docs/errors.md#invalid_input) | The arguments do not fit the tool: a field is missing, has the wrong type or is out of range, or a value is not one the tool takes. |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 403 | [`owner_required`](https://conecto.chat/docs/errors.md#owner_required) | Only the owner may raise a spending limit or give a new key more daily budget than the key making it. The account page's own tools, and asking Conecto for a higher limit, take the owner, an admin or a key of the company-wide team without limits. |
| 403 | [`scope_too_wide`](https://conecto.chat/docs/errors.md#scope_too_wide) | A new key can't be wider than the key making it: more areas or tools, other networks, or a later expiry. |
| 409 | [`limit_reached`](https://conecto.chat/docs/errors.md#limit_reached) | The business has as many of these as it may: keys, tables, schedules, pages, channels and the like. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
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"
  }'
```

Reply 201:

```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"
  }
}
```

## Revoke a key

`DELETE https://api.conecto.chat/v1/keys/{key_id}`

A key revokes itself and the keys made from it, and the first key of a line revokes any key of its line.

Send the key as `Authorization: Bearer <key>`.

### Parameters

| Parameter | In | Type | What it is |
| --- | --- | --- | --- |
| `key_id` | path | integer | The new key's number. |

### Reply 200

Revoked.

| Field | Type | What it is |
| --- | --- | --- |
| `revoked` | integer | The number of the key revoked. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 403 | [`not_yours`](https://conecto.chat/docs/errors.md#not_yours) | A key revokes itself and the keys made from it. The first key of a line revokes any key of its line. |
| 404 | [`not_found`](https://conecto.chat/docs/errors.md#not_found) | The thing named does not exist for this business: a record, a file, a call, a key or a page. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl -X DELETE https://api.conecto.chat/v1/keys/4128 \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Reply 200:

```json
{
  "revoked": 4128
}
```

## List recent calls

`GET https://api.conecto.chat/v1/calls`

The account's calls, newest first. A scoped key sees its own calls only.

Send the key as `Authorization: Bearer <key>`.

### Parameters

| Parameter | In | Type | What it is |
| --- | --- | --- | --- |
| `limit` | query | integer | How many calls to list, newest first. |
| `status` | query | string | Only the calls in this state. |

### Reply 200

The calls.

| Field | Type | What it is |
| --- | --- | --- |
| `calls` | array of objects | The calls, newest first. |
| `calls[].call_id` | string | The call's id. |
| `calls[].tool` | string | The tool called. |
| `calls[].area` | string | The tool's area. |
| `calls[].status` | string | Where the call is: `reserved` (waiting to run), `running`, `succeeded` or `failed`. |
| `calls[].cost_usd` | string | What the call cost. A call that fails costs $0.00. |
| `calls[].error` | string or null | The error code of a call that failed. |
| `calls[].message` | string or null | What went wrong, in words. |
| `calls[].latency_ms` | integer or null | How long the tool took, in milliseconds. |
| `calls[].at` | string | When the call was made. |
| `calls[].bot` | string or null | The name of the key that made it. |
| `calls[].person` | string or null | Whose agent it was: the person the key belongs to, by name or email. null for a bot's own key. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl https://api.conecto.chat/v1/calls?limit=20&status=succeeded \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Reply 200:

```json
{
  "calls": [
    {
      "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
      "tool": "crm_save_contact",
      "area": "crm",
      "status": "succeeded",
      "cost_usd": "$0.01",
      "error": null,
      "message": null,
      "latency_ms": 84,
      "at": "2026-10-14T08:00:00+00:00",
      "bot": "Pip",
      "person": null
    }
  ]
}
```

## Get a call (poll background calls)

`GET https://api.conecto.chat/v1/calls/{call_id}`

One call with its status and cost, what it was given and what it answered. Poll it for a call that runs in the background.

Send the key as `Authorization: Bearer <key>`.

### Parameters

| Parameter | In | Type | What it is |
| --- | --- | --- | --- |
| `call_id` | path | string | The call's id. |

### Reply 200

The call, its status and cost, with what it was given and what it answered.

| Field | Type | What it is |
| --- | --- | --- |
| `call_id` | string | The call's id. |
| `tool` | string | The tool called. |
| `area` | string | The tool's area. |
| `status` | string | Where the call is: `reserved` (waiting to run), `running`, `succeeded` or `failed`. |
| `cost_usd` | string | What the call cost. A call that fails costs $0.00. |
| `error` | string or null | The error code of a call that failed. |
| `message` | string or null | What went wrong, in words. |
| `latency_ms` | integer or null | How long the tool took, in milliseconds. |
| `at` | string | When the call was made. |
| `bot` | string or null | The name of the key that made it. |
| `person` | string or null | Whose agent it was: the person the key belongs to, by name or email. null for a bot's own key. |
| `input` | object or null | The arguments it was given. A secret argument shows as [redacted]. |
| `output` | object or null | What it answered. |

### Errors

A refusal costs nothing and its `message` says what to do. Each code links to its fix.

| Status | Code | What it means |
| --- | --- | --- |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 404 | [`not_found`](https://conecto.chat/docs/errors.md#not_found) | The thing named does not exist for this business: a record, a file, a call, a key or a page. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |

### Example

Request:

```bash
curl https://api.conecto.chat/v1/calls/5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93 \
  -H "Authorization: Bearer $CONECTO_KEY"
```

Reply 200:

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "tool": "crm_save_contact",
  "area": "crm",
  "status": "succeeded",
  "cost_usd": "$0.01",
  "error": null,
  "message": null,
  "latency_ms": 84,
  "at": "2026-10-14T08:00:00+00:00",
  "bot": "Pip",
  "person": null,
  "input": {
    "email": "jana@weber-kuechenplanung.example",
    "name": "Jana Weber",
    "title": "Kitchen planner",
    "company": "Weber Küchenplanung",
    "phone": "+49 40 66969 120",
    "location": "Hamburg",
    "lifecycle_stage": "lead",
    "tags": ["trade", "test-kitchen-visit"]
  },
  "output": {
    "contact": {
      "id": 4107,
      "email": "jana@weber-kuechenplanung.example",
      "name": "Jana Weber",
      "title": "Kitchen planner",
      "company": "Weber Küchenplanung",
      "company_id": 4105,
      "phone": "+49 40 66969 120",
      "location": "Hamburg",
      "lifecycle_stage": "lead",
      "outreach_status": null,
      "notes": "",
      "tags": ["test-kitchen-visit", "trade"],
      "custom_fields": {},
      "archived": false,
      "updated_at": "2026-10-14T08:00:00+00:00"
    },
    "created": true
  }
}
```

## Call a tool

`POST https://api.conecto.chat/v1/tools/{name}`

Runs one of the 581 tools. The body is the tool's arguments as a JSON object, and each tool's page in the [tools directory](https://conecto.chat/tools.md) lists them. Send the key as `Authorization: Bearer <key>`.

### Headers

| Header | What it is |
| --- | --- |
| `Authorization` (required) | `Bearer` and the key. `X-Api-Key` with the key works too. |
| `Content-Type` | `application/json`. |
| `Idempotency-Key` | Any string up to 120 characters. The same key never charges twice. A longer one is kept as its SHA-256. |
| `X-Conecto-Approval` | The `approval_id` of a call a person approved. It lets that one call run. |

### Reply 200

The envelope every tool answers in. The tool's own answer is in `result`.

| Field | Type | What it is |
| --- | --- | --- |
| `call_id` | string | The call's id. |
| `tool` | string | The tool called. |
| `status` | string | `succeeded`. A call that runs in the background answers `running` first, with status 202. |
| `replayed` | boolean | true when the reply repeats an earlier call with the same Idempotency-Key. A replay costs nothing. |
| `cost_usd` | string | What the call cost. A call that fails costs $0.00. |
| `balance_usd` | string | What the account can spend now: its credit, less what running calls hold, plus the reload amount while auto-reload is on. |
| `result` | object | What the tool answered. Each tool's page shows its result. |
| `bought` | object | Only on a read that bought the month's next block of reads: what it bought and what that cost, as a call of its own. |

### Reply 202

A tool that runs in the background answers `202` at once with `status: "running"`. Poll [`GET /v1/calls/{call_id}`](https://conecto.chat/docs/api.md#get-v1-calls-call-id) or the `account_get_call` tool until `status` is `succeeded` or `failed`. The call is charged only when it succeeds.

### Refusals

A refusal answers with a status of 400 or more, and `cost_usd` is `$0.00`. These codes come from the API before or around the tool's own work. Each tool's page lists the codes the tool itself can give.

| Field | Type | What it is |
| --- | --- | --- |
| `error` | string | The error code of a call that failed. |
| `message` | string | What went wrong, in words. |
| `cost_usd` | string | What the call cost. A call that fails costs $0.00. |
| `details` | object | What is needed to fix it, when there is something to add. |

| Status | Code | What it means |
| --- | --- | --- |
| 400 | [`invalid_input`](https://conecto.chat/docs/errors.md#invalid_input) | The arguments do not fit the tool: a field is missing, has the wrong type or is out of range, or a value is not one the tool takes. |
| 401 | [`key_expired`](https://conecto.chat/docs/errors.md#key_expired) | The key has expired. |
| 401 | [`unauthorized`](https://conecto.chat/docs/errors.md#unauthorized) | The call has no key, or the key is wrong or revoked. |
| 402 | [`insufficient_balance`](https://conecto.chat/docs/errors.md#insufficient_balance) | The balance cannot cover the most this call can cost, or the next reads or downloads once the month's free ones are used (a download link answers it to whoever opens it). |
| 402 | [`purchased_credit_required`](https://conecto.chat/docs/errors.md#purchased_credit_required) | AI visibility and the phone (calls, minutes and a number's rent) run only on credit bought with a top-up, never on free, beta or bonus credit, and the credit bought left cannot cover the most this call can cost. |
| 403 | [`account_paused`](https://conecto.chat/docs/errors.md#account_paused) | The owner paused every bot of the account. |
| 403 | [`key_scope`](https://conecto.chat/docs/errors.md#key_scope) | The key's scope doesn't cover this: another area, a tool it isn't given or is denied, a change by a read-only key, or a setting only a key without limits changes. |
| 403 | [`network_not_allowed`](https://conecto.chat/docs/errors.md#network_not_allowed) | The key may only be used from the networks it was given. |
| 403 | [`no_approver`](https://conecto.chat/docs/errors.md#no_approver) | Nobody but the person asking can approve this call, and nobody approves their own. |
| 403 | [`other_team`](https://conecto.chat/docs/errors.md#other_team) | The record belongs to another team. Every team reads it. Its own team changes it. |
| 403 | [`team_paused`](https://conecto.chat/docs/errors.md#team_paused) | The key's team is paused, so its keys can't run tools. |
| 404 | [`not_found`](https://conecto.chat/docs/errors.md#not_found) | The thing named does not exist for this business: a record, a file, a call, a key or a page. |
| 404 | [`unknown_tool`](https://conecto.chat/docs/errors.md#unknown_tool) | No tool has that name, or a background call's tool is gone. |
| 409 | [`approval_required`](https://conecto.chat/docs/errors.md#approval_required) | A person must approve this exact call first: an approval rule holds the tool, the key or its team is set to drafts only, or it gives a supplier new bank details. The request went to the approvers, each on a link of their own, and two people approve when the amount is over the rule's second line. Nothing was charged. |
| 409 | [`idempotency_key_reused`](https://conecto.chat/docs/errors.md#idempotency_key_reused) | The Idempotency-Key was used before for a different tool or different arguments. |
| 409 | [`in_progress`](https://conecto.chat/docs/errors.md#in_progress) | The same work is running right now: a call with this Idempotency-Key, an import, the reading of a scan, or an export of the account. |
| 413 | [`too_large`](https://conecto.chat/docs/errors.md#too_large) | The file, page or upload is over its size limit. |
| 429 | [`daily_budget_reached`](https://conecto.chat/docs/errors.md#daily_budget_reached) | The key reached its daily budget. Keys made from one key share that key's budget. |
| 429 | [`monthly_ceiling_reached`](https://conecto.chat/docs/errors.md#monthly_ceiling_reached) | The business reached its monthly spending ceiling. |
| 429 | [`rate_limited`](https://conecto.chat/docs/errors.md#rate_limited) | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. |
| 429 | [`team_budget_reached`](https://conecto.chat/docs/errors.md#team_budget_reached) | The key's team spent its budget for this period, and the budget is hard. |
| 500 | [`internal_error`](https://conecto.chat/docs/errors.md#internal_error) | Something failed on Conecto's side. Nothing was charged. |
| 500 | [`secret_unreadable`](https://conecto.chat/docs/errors.md#secret_unreadable) | A background call's secret arguments could not be read back. Nothing was charged. |
| 503 | [`unavailable`](https://conecto.chat/docs/errors.md#unavailable) | The tool, or a service it needs, is not available right now (or not switched on yet). Nothing was charged. |

### Example

Request:

```bash
curl -X POST https://api.conecto.chat/v1/tools/crm_save_contact \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jana@weber-kuechenplanung.example",
    "name": "Jana Weber",
    "title": "Kitchen planner",
    "company": "Weber Küchenplanung",
    "phone": "+49 40 66969 120",
    "location": "Hamburg",
    "lifecycle_stage": "lead",
    "tags": ["trade", "test-kitchen-visit"]
  }'
```

Reply 200:

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "tool": "crm_save_contact",
  "status": "succeeded",
  "replayed": false,
  "cost_usd": "$0.01",
  "balance_usd": "$19.75",
  "result": {
    "contact": {
      "id": 4107,
      "email": "jana@weber-kuechenplanung.example",
      "name": "Jana Weber",
      "title": "Kitchen planner",
      "company": "Weber Küchenplanung",
      "company_id": 4105,
      "phone": "+49 40 66969 120",
      "location": "Hamburg",
      "lifecycle_stage": "lead",
      "outreach_status": null,
      "notes": "",
      "tags": ["test-kitchen-visit", "trade"],
      "custom_fields": {},
      "archived": false,
      "updated_at": "2026-10-14T08:00:00+00:00"
    },
    "created": true
  }
}
```

Reply 202:

```json
{
  "call_id": "9b7e3c51-2f4a-4d8e-a0c6-71e5d2b8f4a3",
  "tool": "speech_transcribe",
  "status": "running",
  "reserved_usd": "$0.60",
  "poll": "GET /v1/calls/9b7e3c51-2f4a-4d8e-a0c6-71e5d2b8f4a3 (or the account_get_call tool) until status is succeeded or failed. You are charged only when it succeeds."
}
```

Reply 409:

```json
{
  "error": "approval_required",
  "approval_id": "3e9a6f12-5c7b-4d81-9f0e-2a6b8c4d1e57",
  "approver": "dana@halversoncycle.example",
  "message": "A person must approve this first: the request went to dana@halversoncycle.example. When notify.answered arrives (or notify_get_approval says Approve), call again with the same arguments and the approval (header X-Conecto-Approval, or _meta.approvalId over MCP). Nothing was charged.",
  "cost_usd": "$0.00"
}
```

## Routes for discovery

These answer without a key. An agent reads them to find out what Conecto has before it signs up.

### The index

`GET https://api.conecto.chat/v1`

What Conecto is, how to sign up, the prices in a few words and every area's MCP address.

Reply 200:

```json
{
  "name": "Conecto",
  "what": "The business backend for AI agents: CRM, email, phone, help desk, documents and more, paid per call.",
  "signup": {
    "method": "POST",
    "url": "https://api.conecto.chat/v1/signup",
    "body": {
      "bot_name": "string",
      "accept_terms": true,
      "business_name": "optional",
      "owner_email": "optional",
      "country": "optional, two letters",
      "runtime": "optional",
      "referral": "optional, a Conecto partner's code; only at signup"
    },
    "free_credit_usd": "$1.00"
  },
  "pricing": {
    "failed_calls": "never charged",
    "reads": "free up to 1,000,000 a month",
    "top_up_minimum_usd": "$5.00",
    "top_up_fee": "7% + $0.35",
    "first_top_up": "doubled, up to $20 extra",
    "catalog": "https://api.conecto.chat/v1/tools"
  },
  "areas": "https://api.conecto.chat/v1/areas",
  "mcp": {
    "analytics": "https://api.conecto.chat/mcp/analytics",
    "code": "https://api.conecto.chat/mcp/code",
    "crm": "https://api.conecto.chat/mcp/crm",
    "calendar": "https://api.conecto.chat/mcp/calendar",
    "chat": "https://api.conecto.chat/mcp/chat",
    "account": "https://api.conecto.chat/mcp/account",
    "admin": "https://api.conecto.chat/mcp/admin",
    "email": "https://api.conecto.chat/mcp/email",
    "helpdesk": "https://api.conecto.chat/mcp/helpdesk",
    "documents": "https://api.conecto.chat/mcp/documents",
    "esign": "https://api.conecto.chat/mcp/esign",
    "hiring": "https://api.conecto.chat/mcp/hiring",
    "outreach": "https://api.conecto.chat/mcp/outreach",
    "prospects": "https://api.conecto.chat/mcp/prospects",
    "lookups": "https://api.conecto.chat/mcp/lookups",
    "companies": "https://api.conecto.chat/mcp/companies",
    "longlists": "https://api.conecto.chat/mcp/longlists",
    "mergers": "https://api.conecto.chat/mcp/mergers",
    "valuation": "https://api.conecto.chat/mcp/valuation",
    "newsletters": "https://api.conecto.chat/mcp/newsletters",
    "notify": "https://api.conecto.chat/mcp/notify",
    "projects": "https://api.conecto.chat/mcp/projects",
    "schedules": "https://api.conecto.chat/mcp/schedules",
    "speech": "https://api.conecto.chat/mcp/speech",
    "uptime": "https://api.conecto.chat/mcp/uptime",
    "vault": "https://api.conecto.chat/mcp/vault",
    "web": "https://api.conecto.chat/mcp/web",
    "tables": "https://api.conecto.chat/mcp/tables",
    "links": "https://api.conecto.chat/mcp/links",
    "images": "https://api.conecto.chat/mcp/images",
    "files": "https://api.conecto.chat/mcp/files",
    "forms": "https://api.conecto.chat/mcp/forms",
    "helpcenter": "https://api.conecto.chat/mcp/helpcenter",
    "imports": "https://api.conecto.chat/mcp/imports",
    "invoices": "https://api.conecto.chat/mcp/invoices",
    "books": "https://api.conecto.chat/mcp/books",
    "inventory": "https://api.conecto.chat/mcp/inventory",
    "whistleblowing": "https://api.conecto.chat/mcp/whistleblowing",
    "connect": "https://api.conecto.chat/mcp/connect",
    "microsoft365": "https://api.conecto.chat/mcp/microsoft365",
    "googleworkspace": "https://api.conecto.chat/mcp/googleworkspace",
    "hubspot": "https://api.conecto.chat/mcp/hubspot",
    "salesforce": "https://api.conecto.chat/mcp/salesforce",
    "directory": "https://api.conecto.chat/mcp/directory",
    "hr": "https://api.conecto.chat/mcp/hr",
    "social": "https://api.conecto.chat/mcp/social",
    "purchasing": "https://api.conecto.chat/mcp/purchasing",
    "phone": "https://api.conecto.chat/mcp/phone",
    "websites": "https://api.conecto.chat/mcp/websites",
    "views": "https://api.conecto.chat/mcp/views",
    "visibility": "https://api.conecto.chat/mcp/visibility",
    "markets": "https://api.conecto.chat/mcp/markets"
  }
}
```

Its `reads` are free up to the month's 1,000,000 reads. Past that, each 10,000 more cost $0.50, as [Money](https://conecto.chat/docs/money.md#free-reads) explains.

### The areas

`GET https://api.conecto.chat/v1/areas`

Every area with its title, its summary, how many tools it has and its MCP address. There are 52. The first two:

Reply 200:

```json
{
  "areas": [
    {
      "area": "analytics",
      "title": "Website analytics",
      "summary": "Count a website's visits with one script tag, like Plausible or Umami: visitors, pages, sources, countries, devices and custom events. No cookies, and no IP addresses kept. $3 a month per site with 100,000 events.",
      "tools": 18,
      "mcp": "https://api.conecto.chat/mcp/analytics"
    },
    {
      "area": "code",
      "title": "Code",
      "summary": "Run Python or Node.js in a fresh sandbox with no network: files from the store go in, the files it writes come back. $0.0001 per second of run time, at least $0.005 a run.",
      "tools": 1,
      "mcp": "https://api.conecto.chat/mcp/code"
    }
  ]
}
```

### The tools

`GET https://api.conecto.chat/v1/tools`

Every tool with its name, area, title, description, price and whether it only reads, deletes data or runs in the background. Add `?area=crm` for one area. The CRM has 41. The first two:

Reply 200:

```json
{
  "tools": [
    {
      "name": "crm_find_contacts",
      "area": "crm",
      "title": "Find contacts",
      "description": "Search the CRM by name, email, company or phone, or by filters on any field, tag or custom field, or by a saved segment. Returns a page of contacts (most recently seen first unless `sort` says otherwise), the total, and next_offset for the next page.",
      "price": {
        "model": "free",
        "usd": "$0.00",
        "micros": 0
      },
      "read_only": true,
      "destructive": false,
      "runs_in_background": false
    },
    {
      "name": "crm_get_contact",
      "area": "crm",
      "title": "Get a contact",
      "description": "One contact with its tags, custom fields, recent activity, open tasks and deals, by id or email, and came_from: the website visit that led to their first chat, booking, form or signup (channel, source, campaign, landing page), when the site is counted. crm_timeline has everything that happened with them.",
      "price": {
        "model": "free",
        "usd": "$0.00",
        "micros": 0
      },
      "read_only": true,
      "destructive": false,
      "runs_in_background": false
    }
  ],
  "count": 41
}
```

### One tool

`GET https://api.conecto.chat/v1/tools/{name}`

One tool in full, with its input schema and examples. The same address with POST runs it.

Reply 200:

```json
{
  "name": "crm_save_contact",
  "area": "crm",
  "title": "Save a contact",
  "description": "Create a contact, or update the one with this email if it already exists. Only the fields you send change; tags are added, custom fields merged. Without an email a new contact is always created.",
  "price": {
    "model": "per_call",
    "usd": "$0.01",
    "micros": 10000
  },
  "read_only": false,
  "destructive": false,
  "runs_in_background": false,
  "input_schema": {
    "type": "object",
    "properties": {
      "email": {
        "type": "string",
        "maxLength": 254,
        "format": "email"
      },
      "name": {
        "type": "string",
        "maxLength": 255
      },
      "title": {
        "type": "string",
        "maxLength": 255
      },
      "company": {
        "type": "string",
        "maxLength": 255,
        "description": "Company name; also links or creates the company record."
      },
      "phone": {
        "type": "string",
        "maxLength": 60
      },
      "location": {
        "type": "string",
        "maxLength": 255
      },
      "timezone": {
        "type": "string",
        "maxLength": 60
      },
      "language": {
        "type": "string",
        "maxLength": 60
      },
      "lifecycle_stage": {
        "type": "string",
        "enum": [
          "lead",
          "trial",
          "onboarding",
          "customer",
          "at_risk",
          "churned",
          "advocate"
        ]
      },
      "notes": {
        "type": "string",
        "maxLength": 20000
      },
      "custom_fields": {
        "type": "object",
        "maxProperties": 60,
        "additionalProperties": {
          "type": ["string", "number", "boolean", "null"],
          "maxLength": 1000
        },
        "description": "Custom fields as {\"key\": value}, merged into the existing ones; null clears one. Keys defined with crm_define_field are checked against their type."
      },
      "tags": {
        "type": "array",
        "maxItems": 20,
        "items": {
          "type": "string",
          "maxLength": 60,
          "minLength": 1
        },
        "description": "Tags to add, e.g. [\"vip\"]; a new tag is made on first use. crm_tag_records removes tags."
      }
    },
    "required": [],
    "additionalProperties": false
  },
  "examples": [
    {
      "email": "ana@acme.com",
      "name": "Ana Ruiz",
      "company": "Acme",
      "lifecycle_stage": "lead",
      "tags": ["webinar-2026-10"],
      "custom_fields": {
        "plan": "Pro"
      }
    }
  ]
}
```

### SKILL.md

`GET https://api.conecto.chat/v1/skill.md`

The instructions an agent keeps, as Markdown. https://conecto.chat/SKILL.md answers the same. [For agents](https://conecto.chat/docs/for-agents.md) says what it holds.

### OpenAPI

`GET https://api.conecto.chat/v1/openapi.json`

OpenAPI 3.1.0 with every REST route above and every tool, 590 paths in all. One area at a time: `/v1/openapi/<area>.json` (OpenAPI 3.0, for a custom GPT's Actions) and `/v1/openapi/<area>.swagger.json` (OpenAPI 2.0 with the key in `X-Api-Key`, for Power Automate and Copilot Studio).

### MCP servers

`POST https://api.conecto.chat/mcp/{area}`

One MCP server per area, over Streamable HTTP. It answers JSON-RPC messages as plain JSON. `initialize` and `tools/list` need no key. `tools/call` needs the key in the `Authorization` header. A batch holds up to 50 messages. [Calling tools](https://conecto.chat/docs/calling-tools.md#over-mcp) has the details.

initialize, reply:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-11-25",
    "capabilities": {
      "tools": {
        "listChanged": false
      }
    },
    "serverInfo": {
      "name": "conecto-crm",
      "version": "1.0.0",
      "title": "Conecto CRM"
    },
    "instructions": "Conecto CRM: Contacts, companies and deals in pipelines, with notes, tasks, tags, custom fields, saved segments, one search, full timelines, duplicate merging, bulk saves, reports and CSV export: the business's customer records. Every tool lists its price; reads are free up to 1,000,000 a month for the account (then $0.50 per 10,000), and a call that fails is never charged. Pay from your Conecto balance (GET https://api.conecto.chat/v1/balance)."
  }
}
```

### The connector with sign-in

`POST https://api.conecto.chat/v1/mcp`

One address for every area, for assistants that sign in with OAuth, like ChatGPT, Claude and Copilot. The person ticks the areas it may use when they sign in, and it lists those areas' tools. Without a key or a token it answers 401 and names its OAuth metadata.

Reply 401:

```json
{
  "error": "unauthorized",
  "message": "Sign in to connect: this server uses OAuth, or a Conecto key as \"Authorization: Bearer <key>\"."
}
```

The `WWW-Authenticate` header of that reply: `Bearer resource_metadata="https://api.conecto.chat/.well-known/oauth-protected-resource/v1/mcp", scope="tools"`

---

Source: https://conecto.chat/docs/errors

# Errors

A refused call costs nothing, and its reply says what went wrong in words an agent can act on. This page lists every code by its HTTP status.

## The shape of a refusal

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "status": "failed",
  "error": "insufficient_balance",
  "message": "This call costs up to $0.10 and the balance is $0.04. Top up to continue; nothing was charged.",
  "cost_usd": "$0.00",
  "details": {
    "price_usd": "$0.10",
    "balance_usd": "$0.04",
    "top_up": "POST /v1/topups {\"amount_usd\": 20} returns a Stripe checkout link; pay it once and turn on auto-reload so the balance never runs dry.",
    "minimum_usd": 5,
    "fee": "7% + $0.35 per top-up, Stripe's fees passed on",
    "first_topup_offer": "Your first top-up is doubled, up to $20 extra."
  }
}
```

- `error` is one of the codes below.
- `message` says what went wrong and what to do, written for an agent to act on.
- `cost_usd` is `$0.00`. A refused call costs nothing.
- `details`, when there is something to add, holds what is needed to fix it, like the amount to top up.
- `call_id` and `status: "failed"` come when the call itself was logged and failed. A refusal before any call, like a wrong key, has neither. An idempotency conflict names the earlier call's `call_id`.

Over MCP the same body comes back as the tool's result, with `isError: true`. A background call that fails shows its code in `error` when you poll it.

Each tool's page in the [tools directory](https://conecto.chat/tools.md) lists the codes that tool can give, with when it gives each one.

## 400 Bad request

| Code | What it means | What to do |
| --- | --- | --- |
| `already_pdf` | The file is a PDF already. | Use it as it is. |
| `columns_needed` | The statement's date and amount columns could not be found. | Name them with columns. |
| `date_format_needed` | The statement's dates are in no known format, or could be read two ways. | Pass `date_format`. |
| `greeting_needs_ai_disclosure` | The phone greeting does not tell callers they reached an automated line or an AI. | Say so in the greeting, like "This is our automated line". |
| `invalid_brief` | The `brief_token` is not a ready brief `prospects_prepare` made for this business, or it is over a day old. | Prepare it again with `prospects_prepare` and use the `brief_token` it returns. |
| `invalid_cursor` | The `next_cursor` is not one this import returned. | Pass back exactly the last `next_cursor`, or leave it out to start again. |
| `invalid_input` | The arguments do not fit the tool: a field is missing, has the wrong type or is out of range, or a value is not one the tool takes. | Fix what the message names. details.`input_schema` has the tool's full schema. |
| `invalid_statement` | The bank statement could not be read: an amount, a date or the file format. | Fix what the message names, like passing decimal: "," for comma decimals. |
| `invalid_url` | The address is not a public https:// link. | Send a public link. |
| `login_failed` | The business's own email service refused the login. | Check the SMTP login and password (often an SMTP key, not the account password) and connect it again. |
| `low_contrast` | The two colours are too close for phones to read. | Use a darker dark or a lighter light. |
| `map_place` | The company id starts with op: a business a longlist found on the map (Overture's places), which has no register record to read. | Find its register record with `companies_search` by name and country, then call again with that id. |
| `no_working_days` | The leave has no working days for the person. | Pick other dates. |
| `not_a_host` | The host named is not one of the meeting type's round-robin hosts, or the type has none. | Leave host out, or name one from the type's hosts in `calendar_list_meeting_types`. |
| `not_a_quote` | The id is an invoice, not a quote. | Use the invoice tools for it. |
| `not_an_invoice` | The id is a quote or a credit note. Payments, reminders and credit notes are for invoices. | Turn a quote into an invoice with `invoices_convert_quote`. |
| `not_audio` | The file is not audio or video. | Upload the recording first. |
| `not_image` | The file is not an image that can be read. | Upload it again as PNG or JPEG. |
| `not_pdf` | The file is not a PDF. | Make one with `documents_convert_to_pdf` first. |
| `not_schedulable` | The tool cannot run on its own: it handles secrets, schedules things itself, buys from a quote that expires, or starts a monthly rental. | Call that tool yourself when it is needed. |
| `not_supported` | The social network connects in a way the tools do not offer. | Pick another network from `social_networks`. |
| `refused` | The posting service refused the request. The message gives its reason. | Fix what the reason names, then call again. |
| `stripe_key_refused` | The Stripe key cannot do what invoice payments need. | Make a key with the permissions the message lists. |
| `timezone_required` | The first setup needs a time zone. | Pass timezone, like "Europe/Berlin". |
| `too_long` | There is too much data for one QR code. | Shorten it. |
| `too_many_pages` | The PDF has more pages than a signature request takes. | Send a shorter PDF. |
| `unbalanced` | Debits and credits of the entry differ. | Make the lines balance. |
| `unsupported_type` | The file is not a kind the tool takes. | Use a file of a kind the message lists. |
| `video_too_long` | The video is longer than the social network lets the account post. | Ask the owner for a shorter video. The message gives the limit. |

## 401 Unauthorized

| Code | What it means | What to do |
| --- | --- | --- |
| `key_expired` | The key has expired. | Make a new key (`POST /v1/keys`) with a key that may, or ask the owner. |
| `unauthorized` | The call has no key, or the key is wrong or revoked. | Send "Authorization: Bearer <key>". No key yet? Sign up with `POST /v1/signup`. |

## 402 Payment required

| Code | What it means | What to do |
| --- | --- | --- |
| `insufficient_balance` | The balance cannot cover the most this call can cost, or the next reads or downloads once the month's free ones are used (a download link answers it to whoever opens it). | Top up with `POST /v1/topups` (details has the amount and the first top-up bonus), then call again. A download link works again once the balance can pay. |
| `payment_required` | The tool needs a paid account, and the balance is still free credit. | Top up once with `POST /v1/topups` (from $5), then call again. |
| `payment_required_for_outbound` | Free credit cannot email, call or send documents to people outside the business. | Top up once with `POST /v1/topups` (from $5). After that it works. |
| `purchased_credit_required` | AI visibility and the phone (calls, minutes and a number's rent) run only on credit bought with a top-up, never on free, beta or bonus credit, and the credit bought left cannot cover the most this call can cost. | Top up with `POST /v1/topups`, then call again. `account_balance` shows how much of the balance was bought (`bought_credit_usd`) and how much is free and bonus credit, which every other tool spends first. |

## 403 Forbidden

| Code | What it means | What to do |
| --- | --- | --- |
| `account_paused` | The owner paused every bot of the account. | Ask the owner to start the account again on their account page. |
| `blocked_by_robots` | The site's robots.txt asks bots not to read the page. | Find the facts elsewhere with `web_search`. |
| `forbidden` | The secret is limited to other bots of the business. | Ask the owner, or the bot that saved it, to let this bot read it. |
| `key_scope` | The key's scope doesn't cover this: another area, a tool it isn't given or is denied, a change by a read-only key, or a setting only a key without limits changes. | Use a key that may, or ask whoever made this key for a wider one. |
| `network_not_allowed` | The key may only be used from the networks it was given. | Call from one of those networks, or use another key. |
| `no_approver` | Nobody but the person asking can approve this call, and nobody approves their own. | Ask the owner to add an approver: a team with managers, an admin, or a rule naming someone else. |
| `not_allowed` | The connected system's call is outside the calls it allows, its address is not a public https host, or the mailbox is not one the agent may act as. | Call inside its allowed calls (`connect_list` shows them), use a listed mailbox, or ask the owner to widen them. |
| `not_yours` | A key revokes itself and the keys made from it. The first key of a line revokes any key of its line. | Revoke it with the key that made it, or ask the owner (their account page revokes any key). |
| `other_team` | The record belongs to another team. Every team reads it. Its own team changes it. | Ask that team (or a key of the company-wide team) to change it, or the owner to open the area to everyone. |
| `owner_required` | Only the owner may raise a spending limit or give a new key more daily budget than the key making it. The account page's own tools, and asking Conecto for a higher limit, take the owner, an admin or a key of the company-wide team without limits. | Ask the owner. `account_owner_link` makes them a sign-in link to their account page. Lowering works at any time. |
| `scope_too_wide` | A new key can't be wider than the key making it: more areas or tools, other networks, or a later expiry. | Ask for a key within this key's scope, or make it with a key that has more. |
| `self_only` | A person's own assistant works in HR for that person only, since none of their teams works in HR. | Ask about your own record, or ask HR. |
| `sending_paused` | Email from the business is paused after bounces, complaints or emails refused as cold outreach. | Tell the owner. Conecto reviews the pause before sending resumes. |
| `sending_unavailable` | The business cannot send newsletters right now. The message says why. | Tell the owner. Nothing was charged. |
| `team_paused` | The key's team is paused, so its keys can't run tools. | Ask the owner to start the team again on their account page. |

## 404 Not found

| Code | What it means | What to do |
| --- | --- | --- |
| `link_expired` | The download link expired, or its file was deleted. | Get a fresh link with `files_get`. |
| `no_legal_notice` | The website has no legal notice that could be read: no page named Impressum, Imprint or Legal notice, and none at the usual addresses. Nothing was charged. | Give the notice's own address if you know it, or find the company with `companies_search` by name. |
| `no_numbers` | The carrier has no numbers of that kind in that country right now. Nothing was charged. | Try another type or area code. |
| `not_found` | The thing named does not exist for this business: a record, a file, a call, a key or a page. | Find it with the area's list or search tool and use the id it returns. The message names what is missing. |
| `not_set_up` | The area is not set up for the business yet: calendar, chat, careers page or the like. | Run the area's setup tool first. The message names it. |
| `unknown_tool` | No tool has that name, or a background call's tool is gone. | Use a name from `GET /v1/tools`. |

## 405 Method not allowed

| Code | What it means | What to do |
| --- | --- | --- |
| `method_not_allowed` | The address does not take that HTTP method. | Use the method the message names: tools take POST, a call's status GET, a key DELETE. |

## 409 Conflict

| Code | What it means | What to do |
| --- | --- | --- |
| `address_taken` | The booking address is another calendar's, was ever another business's, or is kept for Conecto's own pages. | Pick another address, e.g. with the town or the trade added. |
| `ai_review_off` | Applicants are not told yet that AI reviews applications. | Run `hiring_setup_careers` with `ai_review` true first. |
| `alias_taken` | The short link alias is taken. | Pick another alias, or leave it out for a random one. |
| `already_accepted` | The customer accepted the quote already. | Turn it into an invoice with `invoices_convert_quote`. |
| `already_approved` | The leave request was approved already. | To take it back, cancel it. |
| `already_attached` | The file is on the person's record already. | Nothing to do. |
| `already_cancelled` | The purchase order or leave request is cancelled already. | Make a new one. |
| `already_closed` | The purchase order is closed already. | Draft a new order. |
| `already_converted` | The quote became an invoice already. | Work with that invoice. The message gives its `invoice_id`. |
| `already_credited` | An invoice line is credited in full already. | Credit other lines, or an amount. |
| `already_declined` | The quote, or the leave request, was declined already. | Make a new quote, or ask again with `hr_request_leave`. |
| `already_done` | The task is done already. | Nothing to do. |
| `already_hired` | The applicant is in HR already. | Find their record with `hr_list_people`. |
| `already_ignored` | The bank line was ignored. | Unmatch it first. |
| `already_matched` | The bank line, or the entry, is matched already. | Unmatch it first. |
| `already_paid` | The invoice is paid in full. | Nothing is owed. Record a refund if money goes back. |
| `already_ran` | The one-off run ran already. | Set a new one with `schedules_run_later`. |
| `already_read` | The scan was read with OCR already. | Read its text free with `files_read_text`. |
| `already_received` | Everything on the purchase order is received. | Nothing is left to receive. |
| `already_reversed` | The entry is reversed already. | Book a new entry if needed. |
| `already_sent` | Another call sent this a moment ago. | Read it again. It was sent. |
| `already_started` | The person has open tasks from that checklist already. | Finish them, or list them with `hr_tasks`. |
| `already_void` | The invoice or bill is void already. | Nothing to do. |
| `ambiguous` | The name or number fits more than one thing. | Be more exact. The message says how. |
| `amount_mismatch` | The entries, invoices or bills do not add up to the bank line. | Give amounts that add up, or pick other records. |
| `application_limit` | A candidate sent as many applications as the business takes from one person in its time window (`hiring_setup_careers` `application_limit`). | The message says from which day they can apply again. The business can change or lift the limit. |
| `approval_required` | A person must approve this exact call first: an approval rule holds the tool, the key or its team is set to drafts only, or it gives a supplier new bank details. The request went to the approvers, each on a link of their own, and two people approve when the amount is over the rule's second line. Nothing was charged. | Wait for `notify.answered` (or check `notify_get_approval`), then call again with the same arguments and the approval: the X-Conecto-Approval header, or _meta.approvalId over MCP. |
| `archived` | An account, tax, supplier, item, location or leave type named is archived. | Use one that is active, or restore it first. |
| `asset_disposed` | The asset was sold or written off. | Bring it back with `books_dispose_asset` undo first. |
| `before_start` | The date is before the books start. | Use a date on or after the start date (`books_get`). |
| `bill_paid` | The bill is paid, so its due date no longer matters. | Leave the due date. |
| `bill_void` | The bill is void. | Record a new bill if needed. |
| `bot_cannot_post` | The business's own Telegram bot may not post in the chat: not an admin of the channel with the right to post, or not a member of the group who may send messages. | Ask the owner to add the bot with that right, then connect again. |
| `bridge_unavailable` | The connection goes through a bridge that was revoked, or that no longer serves the system. | The owner or an admin makes a new bridge on the account page (Settings, Bridges) and connects the system again. |
| `call_active` | A call on the number is still going on. | Release the number when the call has ended. |
| `campaign_ended` | The outreach campaign was stopped or has finished. It can't change, start or resume. | Save a new campaign with `outreach_save_campaign`. |
| `campaign_running` | The outreach campaign is sending, so it can't change. | Pause it with `outreach_pause`, change it, then resume it with `outreach_resume`. |
| `carrier_refused` | The phone carrier would not sell that number (it may have been taken). Nothing was charged. | Search again with `phone_search_numbers`. |
| `channel_disabled` | The social channel is switched off in the posting service. | Connect it again with `social_connect`. |
| `chat_taken` | The Telegram channel is connected to another Conecto account. | Its owner disconnects it there first. |
| `closed` | The signature request is closed: completed, declined, cancelled or expired. | Send a new request if needed. |
| `code_taken` | Another account in the chart has that code. | Pick another code. |
| `conflict` | What is asked clashes with what is there: a record saved at the same moment, a merged ticket, a page of another kind. | Read the record again and call again. The message says what clashed. |
| `conversation_closed` | The visitor has a newer open conversation. | Reply there. The message gives its id. |
| `conversation_open` | The visitor already has an open conversation. | Use that conversation. |
| `currency_fixed` | The currency stays: entries or orders already use it. | Keep the currency. |
| `currency_mismatch` | Two things in different currencies were matched. | Record the payment with `invoices_record_payment` or `purchasing_pay_bill` instead. |
| `duplicate` | A bill with that reference from that supplier is recorded already. | Use the bill the message names. |
| `duplicate_key` | A key value comes twice, in the rows sent or in the table, so it can't pick out one row. | Send each key once, and merge or delete the table's extra rows first. |
| `email_taken` | Another person has that work email. | Use another email, or update that person. |
| `file_kept` | A bill keeps the PDF it was recorded with: a received invoice is kept as it came. | If it is the wrong file, void the bill and record it again with the right one. |
| `from_assets` | The entry was booked by the asset register: depreciation, or an asset sold or written off. | Undo depreciation with `books_depreciate` `undo_after`, or a sale with `books_dispose_asset` undo. |
| `from_bill` | The entry was posted from a supplier bill. | Void the bill with `purchasing_void_bill` instead. |
| `from_claim` | The entry paid expense claims back, or is an expense claim already paid back, so it stays. | Record money a person returned as a negative expense with `paid_by`. |
| `from_credit` | The entry booked a prepayment or its refund. | Void the prepayment with `invoices_use_credit` or `purchasing_use_credit` (void: true) while none of it is used. |
| `from_invoice` | The entry was posted from an invoice. | Void the invoice with `invoices_void`, or record a refund. |
| `has_balance` | The account still has a balance. | Move it to another account with an entry first. |
| `has_bills` | The purchase order has bills. | Void them with `purchasing_void_bill` first. |
| `has_credit_notes` | The invoice has credit notes, so it cannot be voided. | Credit what is left of it with `invoices_create_credit_note`. |
| `has_deliveries` | The purchase order has deliveries received, so it cannot be cancelled. | Close it instead. What came in stays. |
| `has_depreciation` | The asset's depreciation is booked, so its cost, dates, method and accounts stay and it can't be deleted. | Undo its depreciation with `books_depreciate` `undo_after` and asset first. |
| `has_left` | The person left the business. | Nothing can be planned for them after their end date. |
| `has_payments` | Payments are recorded on the invoice or bill. | Record a refund (a negative payment) first. |
| `has_receipt` | The entry has a receipt already. | Attach the file to another entry, or keep it. |
| `has_role` | The account holds a role the books use. | Give the role to another account first. |
| `has_stock` | The item or location still holds stock. | Move, ship or count it to 0 first. |
| `idempotency_key_reused` | The Idempotency-Key was used before for a different tool or different arguments. | Send a new Idempotency-Key for a new call. Reuse one only to retry the exact same call. |
| `in_progress` | The same work is running right now: a call with this Idempotency-Key, an import, the reading of a scan, or an export of the account. | Wait for it (`account_get_call` shows it), then use its result. |
| `in_use` | The thing is used elsewhere and stays while it is: a file on a record, a tax on an account, a test candidates started. The PDF of a sent invoice, credit note, quote or purchase order always stays. | Take it off there first, as the message says. |
| `inactive` | The meeting type is not taking bookings. | Pick one from `calendar_list_meeting_types`. |
| `invalid_dates` | The due date or valid-until date is before the issue date, or an invoice's issue date is in the future or before the last one numbered in its series. | Change it with `invoices_update`. Without an issue date a document is dated the day it is sent. |
| `invoice_incomplete` | The invoice lacks what the law of the business's country needs on it: an address or VAT ID, the customer's VAT ID for a reverse charge, why a line has no tax. | Add what the message names with `invoices_update` or `invoices_set_profile`, then send again. Nothing was numbered or charged. |
| `is_reversal` | The entry is itself a reversal. | Book the original again instead. |
| `key_taken` | Another project has that key. | Pick another key. |
| `limit_reached` | The business has as many of these as it may: keys, tables, schedules, pages, channels and the like. | Delete or archive one you no longer use. The message gives the limit. A business that needs more asks with `account_request_limit`. |
| `link_used` | The upload link was used already. | Ask for a new one with `files_upload_link`. |
| `manager_cycle` | The manager would end up reporting to the person, directly or through others. | Pick another manager. |
| `manages_others` | The person manages others. | Give them another manager first with `hr_save_people`. |
| `more_than_balance` | The payment is more than what is owed. | Record at most the balance the message gives. |
| `more_than_invoiced` | The credit is more than what is left of the invoice, or of an invoice line, to credit. | Credit at most what the message says is left. |
| `more_than_left` | A credit (a prepayment or an overpayment) has less left than the amount, or nothing. | Use or pay back at most what is left. `invoices_list_credits` or `purchasing_list_credits` shows it. |
| `more_than_ordered` | More would arrive than was ordered. | Receive at most what is left on the line. |
| `more_than_paid` | The refund is more than was paid. | Refund at most what was paid. |
| `name_taken` | Something of that kind has that name already. | Pick another name. |
| `national_system_required` | The business is in a country whose domestic invoices must go through a national system (Italy's SdI, Poland's KSeF, Belgium's Peppol and others), which Conecto doesn't connect to yet. | Send that invoice through the national system. Invoices to customers abroad, quotes and the books still work. |
| `network_off` | The social network is not switched on for Conecto yet. | Pick one that is enabled in `social_networks`. |
| `network_refused` | The social network won't take a post from the account right now: its daily limit, or it stopped the account from posting. | Tell the owner the reason in the message and try again later. |
| `no_account` | A bill line has no expense or asset account to post to. | Give the line an account. |
| `no_books` | The business keeps no books yet. | Set them up with `books_setup`. |
| `no_channels` | The business has no connected social channel yet. | Connect one with `social_connect`. |
| `no_date` | The person has no start or end date, which the checklist counts from. | Set it with `hr_save_people` first. |
| `no_email` | There is no email address to send the document to. | Give one with to, or save it on the customer or supplier. |
| `no_iban` | A SEPA file needs an IBAN for every supplier it pays and for the bank account it pays from. | Add it with `purchasing_save_supplier` (a person approves new bank details) or `books_save_accounts`. |
| `no_items` | The document has no line items. | Add at least one before sending. |
| `no_mailbox` | No mailbox of the outreach campaign can send: none is named, or each one is disconnected, paused or over the business's limit. | Name a mailbox `outreach_mailboxes` shows as ready in `mailbox_ids`, or connect one with `outreach_connect_mailbox`. |
| `no_match` | The bank rule given does not match the bank line. | Pick the rule the line's suggestions name, or book the line to an account. |
| `no_rate` | There is no exchange rate for that currency on that day (for the books, or for an invoice's VAT in the national currency). | Pass the rate yourself (rate, or an invoice's `vat_exchange_rate`). |
| `no_role` | No account has a role the books need. | Give it to one with `books_save_accounts`. |
| `no_sending_service` | The business has not connected its own email service, which its newsletters go out through. | Connect it with `newsletters_connect_service` (its SMTP server, login and from address). |
| `no_subscribers` | Nobody has confirmed a subscription yet. | Invite people with `newsletters_invite` first. |
| `no_support_inbox` | Attachments go out from a support inbox, and the ticket has none. | Connect one with `ticket_connect_inbox`, or pass inbox. |
| `nobody_to_email` | Nobody in the outreach campaign's audience can be emailed: they have no email address, unsubscribed, bounced, said no, replied before or are in another campaign. | Choose another audience with `outreach_save_campaign`. Its reply says who was left out and why. |
| `not_a_channel` | The Telegram code was posted in a group, where any member could have posted it. | Post it in a channel, where only admins post. |
| `not_a_draft` | The document was sent, or is a credit note, so it cannot change. | Correct a sent invoice with `invoices_create_credit_note`, or void a quote and make a new one. |
| `not_accepted` | The quote is not accepted yet. | Let the customer accept it on its page, or record that they accepted. |
| `not_beside` | The tool works in the Beside widget, and this chat runs the classic widget. | Use `chat_reply` for this chat. |
| `not_bookable` | The meeting type is not taking bookings. | Pick one from `calendar_list_meeting_types`. |
| `not_cancellable` | Only a scheduled or sending newsletter issue can be cancelled. | Nothing to cancel. |
| `not_completed` | The test is not completed yet. | Wait until the applicant completes it. |
| `not_connected` | Something the tool needs is not connected yet: the business's Stripe account, a Google or Microsoft calendar, or the company's Microsoft 365 or Google Workspace. | Connect it first. The message names the tool. |
| `not_done` | The task is still open. | Nothing to reopen. |
| `not_draft` | Only a draft can change or be sent, and this is not one. | Make a new draft. |
| `not_enough_days` | The person has fewer days of that leave left than this needs. | Pass `allow_negative`: true to allow it anyway, or ask for fewer days. |
| `not_enough_stock` | A location does not hold enough of the item. | Move or receive stock first, or take less. |
| `not_matched` | The bank line is not matched. | Leave it as it is. |
| `not_movable` | The meeting is not scheduled, or it has started. | Book a new meeting instead. |
| `not_owed` | The invoice or bill isn't owed: a draft, paid or void, so it takes no expected or planned date. | Give the date to an invoice that is sent and not paid, or a bill not paid yet. |
| `not_posted` | The payment was not posted to the books. | Match the bank line another way. |
| `not_posting` | Invoices and bills do not post to the books, so their payments cannot be matched. | Turn `post_invoices` on with `books_setup`. |
| `not_published` | The website is not published. | Publish it first with `website_publish`. |
| `not_refundable` | The top-up can't be refunded: it is more than 24 hours old, part of it was used, it was refunded already, or it was an auto-reload. Nothing was refunded. | Credit doesn't expire, so it stays for later calls. |
| `not_sent` | The quote, invoice or purchase order is still a draft. | Send it first. The message names the tool. |
| `not_set_up` | The page needs something the business has not set up yet, like the website chat. | Set it up first. The message names the tool. |
| `not_started` | The outreach campaign never started, so there is nothing to pause or resume. | Start it with `outreach_start`. |
| `not_tracked` | The leave type is not tracked, so it has no balance. | Nothing to adjust. |
| `not_verified` | The email domain is not proved yet, so nobody can join with it. | Add the TXT record the domain came back with, then verify it. |
| `not_voidable` | A credit note stays once issued. | To charge the customer again, send a new invoice. |
| `not_waiting` | The prospect search is not waiting for an answer: it is running, or it ended. | Read it with `prospects_get`, and answer only while its status is `needs_input`. |
| `not_yet` | Telegram has not seen "/connect <code>" in the channel yet. | Ask the owner to post the code, then call again with code. |
| `nothing_due` | Nothing is owed on the invoice. | No reminder is needed. |
| `nothing_to_bill` | Everything on the purchase order is billed already. | Nothing to do. |
| `nothing_to_credit` | Everything on the invoice is credited already. | To charge the customer again, send a new invoice. |
| `nothing_to_do` | Nobody is waiting to sign right now. | Nothing to send. |
| `nothing_to_read` | Every page of the PDF has text of its own, so OCR has nothing to read. | Read it free with `files_read_text`. |
| `nothing_to_receive` | Nothing is left to receive on the purchase order. | Nothing to do. |
| `nothing_to_repay` | The person's open expense claims come to nothing or less. | Nothing to pay back. `books_list_claims` shows their claims. |
| `number_taken` | The number is in use already: a document number, or a phone number someone else took. | Pick the next free number, or search phone numbers again. |
| `ocr_in_progress` | Another scan of the business is being read. OCR reads one at a time. | Call again once that call is done (`account_get_call` shows it). |
| `order_cancelled` | The purchase order is cancelled. | Draft a new order. |
| `order_closed` | The purchase order is closed. | Draft a new order. |
| `other_customer` | A customer's credit goes only on that customer's invoices. | Use it on one of their invoices. |
| `other_supplier` | A credit with a supplier goes only on that supplier's bills. | Use it on one of their bills. |
| `outside_employment` | The dates fall outside the person's employment. | Pick dates while they work for the business. |
| `overlaps` | The person has leave on those days already. | Pick other dates, or cancel the other request. |
| `period_locked` | The date falls in a locked period of the books. | Use a later date, or unlock the period with `books_lock`. |
| `post_closed` | The post waiting for its owner was answered already, or its time to be answered ran out. | Read how it went with `social_post_check`, and post again if it is still wanted. |
| `price_changed` | The website's rent ended a moment ago, so publishing starts a new month. Nothing was charged. | Publish again. |
| `price_too_high` | The number costs more than bots can rent today. Nothing was charged. | Pick another number. |
| `profile_incomplete` | The business has no name or country for documents yet. | Set them with `invoices_set_profile` `legal_name` and country. |
| `quote_declined` | The customer declined the quote. | Make a new quote or invoice. |
| `quote_expired` | The number's price quote expired or belongs to another account. | Search again with `phone_search_numbers`. |
| `quote_void` | The quote is void. | Make a new quote or invoice. |
| `rate_fixed` | The tax is in use, so its rate stays. | Add a new tax for the new rate. |
| `reached_customer` | The invoice may be in the customer's hands (emailed, opened, or its PDF downloaded), so it is corrected with a document they get, not voided. | Cancel it with `invoices_create_credit_note` for all of it. |
| `rent_lapsed` | The monthly rent lapsed while it was paused. | Remove it and add it again. |
| `request_pending` | A request for a higher limit of that kind is waiting for Conecto's answer. | Wait for the `account.limit_request_answered` event, or withdraw the request on the account page to ask for another amount. |
| `reversed` | The entry is reversed, so nothing is left to match. | Match another entry. |
| `role_needed` | The account holds a role the books need. | Give that role to another account first. |
| `rule_broken` | A bank rule books to an account that was archived or is gone. | Change the rule with `books_save_bank_rule`. |
| `scope_too_wide` | The areas asked for reach past the team's: a join code or the areas people join in. | Pick areas inside the team's, or leave them out for the team's own. |
| `sku_taken` | Another item has that SKU. | Pick another SKU. |
| `slug_taken` | A meeting type or routing form on that calendar already has that address. | Pick another slug. `calendar_list_meeting_types` and `calendar_list_routing_forms` show the ones in use. |
| `stage_in_use` | Applicants are still in a stage that would go. | Move them first. |
| `start_fixed` | Entries are booked, so the books' start date stays. | Keep the start date. |
| `storage_full` | The file store has no room for the file. | Delete files with `files_delete`, or add room with `files_add_storage`. |
| `storage_in_use` | The files would no longer fit in less storage. | Delete files with `files_delete` first. |
| `time_taken` | The time is not free: taken, outside the hours, too soon or too far ahead. | Pick one of the free times `calendar_find_times` gives. |
| `type_fixed` | The account or field is in use, so its type stays. | Make a new one instead. |
| `vat_id_invalid` | VIES, the EU's VAT ID check, says the customer's VAT ID is not valid, so a reverse-charge or intra-Community invoice can't go out. | Check the number with the customer and fix customer.`tax_id` with `invoices_update`. |
| `void` | The invoice or bill is void. | Make a new one if needed. |
| `wrong_account` | Payments of that kind do not land on the bank line's account. | Map a payment method to it with `books_setup` `payment_accounts`. |
| `year_closed` | The date falls in a fiscal year closed for good with `books_close_year`. | Book it, or the correction, in the open year. |

## 410 Gone

| Code | What it means | What to do |
| --- | --- | --- |
| `gone` | The original of a received email is no longer kept (30 days) or could not be read. | Ask the sender for its files again. |
| `link_expired` | The upload link expired. | Ask for a new one with `files_upload_link`. |

## 413 Too large

| Code | What it means | What to do |
| --- | --- | --- |
| `too_large` | The file, page or upload is over its size limit. | Send a smaller file, or fewer at once. The message gives the limit. |
| `too_many_lines` | The statement has more lines than `max_lines`. | Pass the `max_lines` the message names, up to 5,000 a call. |
| `too_many_pages` | The scan has more pages to read than `max_pages`. | Pass the `max_pages` the message names. |
| `too_many_rows` | The CSV has more rows than one call imports. | Pass a higher `max_rows`, or split the file. |

## 422 Could not be done

| Code | What it means | What to do |
| --- | --- | --- |
| `cold_email` | The email looks like cold outreach, a pitch or a request to people who never wrote to the business, so it wasn't sent. The third refused within 7 days pauses the account's email. | Email only people who wrote first or asked to hear from the business. Prospecting goes from the business's own mailbox. |
| `conversion_failed` | The content or file could not be made into a PDF. | Check the HTML, Markdown or file, then try again. |
| `crashed` | Reading the file needed more memory or time than a file may use. | Split the file, or send a smaller one. |
| `credentials_refused` | The other service refused the token or login, or the account name does not exist there. | Check the credentials with the owner. The message says where to find them. |
| `deck_error` | The deck could not be made: the template isn't a PowerPoint file that opens, or a slide could not be drawn (the message names it). | Use a .pptx or .potx template, or change the slide the message names. |
| `deck_too_slow` | Making the deck took over a minute. | Send fewer slides at a time, or use a smaller template and smaller images. |
| `empty` | The page has no readable text. It may need JavaScript to show anything. | Find the facts elsewhere with `web_search`. |
| `fetch_failed` | The link could not be fetched, redirected too often, or answered with an error. | Make sure the link opens without signing in. |
| `found_by_lookup` | A Conecto inbox never writes first to an address found or checked with Conecto's lookups. | Write from the business's own mailbox (`google_mail_send` or `m365_mail_send`). Answering someone who wrote first is fine. |
| `invalid_pdf` | The PDF could not be read: damaged, or built to waste time. | Ask for another copy. |
| `login_failed` | The social network refused the login. | Check the username and app password with the owner. |
| `not_a_page` | The address is a file, not a page. | Keep it with `files_upload` and its url. |
| `ocr_failed` | OCR could not read the scan. | Try a sharper scan. |
| `pdf_locked` | The PDF is password-protected. | Ask for a copy without a password. |
| `refused` | The other service refused: a site would not show the page to a bot, the posting service reported a conflict, or the business's email service will not take mail for an address. | Read the reason in the message. Find the facts elsewhere, read the post again, or use another address. |
| `suppressed` | An address bounced, complained or unsubscribed before. | Leave those addresses out. The message lists them. |
| `template_error` | The Word template has a broken placeholder, or the data does not fit it. | Fix the place the message names. |
| `template_too_slow` | Filling the template took too long. | Simplify its loops. |
| `timeout` | Reading the PDF or scan took too long. Nothing was charged. | Read fewer pages at a time, or send a smaller file. |
| `too_many` | The ticket would hold more tags or custom fields than it may. | Remove some first. |
| `tool_error` | The tool could not do what was asked. The message says why. | Do what the message says, then call again. |
| `unmapped_columns` | No column of the CSV looks like an email, a name or a phone (for companies: a name, domain or website). | Name the columns like Email, Name, Company and send it again. |
| `unreadable` | The speech service could not read the file. | Send a common audio or video format. |
| `writing_check` | An outreach email does not pass Conecto's writing check: a dash, a stock opener or closer, a contrast or slogan, hype, too many words, links or asks, "Re:" on a first email, or a placeholder some people have no value for. | Make each fix the message names with `outreach_save_campaign`, look again with `outreach_preview`, then start it. |

## 429 Too many requests

| Code | What it means | What to do |
| --- | --- | --- |
| `daily_budget_reached` | The key reached its daily budget. Keys made from one key share that key's budget. | Wait until midnight UTC, or lower the cost of the call. Only the owner raises the budget. |
| `daily_email_limit` | The business emailed as many quotes, invoices or purchase orders in 24 hours as it may. | Send the rest tomorrow, or download the PDF and send it yourself. A business that needs more asks with `account_request_limit`. |
| `monthly_ceiling_reached` | The business reached its monthly spending ceiling. | Wait until the month turns, or ask the owner to raise the ceiling on their account page. |
| `new_recipient_limit` | The business emailed as many new addresses today as it may. | Send to these people tomorrow. Replies and people who wrote first are not limited. A business that needs more asks with `account_request_limit`. |
| `rate_limited` | Too many calls in a short time: from this key or account, or to a service the tool uses (search, social posting, a site's analytics events), or more than three exports of the account in a day. | Wait a few seconds (a minute for a service) and call again. A business that needs more calls a minute asks with `account_request_limit`. |
| `team_budget_reached` | The key's team spent its budget for this period, and the budget is hard. | Wait for the next period (counted in the account's time zone. A project budget doesn't start again), or ask the owner to raise the budget or make it soft. |
| `too_many_emails` | The document was emailed as often in 24 hours as one document may be. | Try again tomorrow. |
| `too_soon` | A reminder about it went out in the last 24 hours. | Remind again after the time the message gives. |

## 500 Server error

| Code | What it means | What to do |
| --- | --- | --- |
| `internal_error` | Something failed on Conecto's side. Nothing was charged. | Call again in a moment, with the same Idempotency-Key if you sent one. |
| `interrupted` | A call stopped before it finished (shown on the call when you poll it). Nothing was charged. | Run the call again. |
| `secret_unreadable` | A background call's secret arguments could not be read back. Nothing was charged. | Call the tool again. |

## 502 Bad gateway

| Code | What it means | What to do |
| --- | --- | --- |
| `carrier_error` | The phone carrier answered with something else than was asked. Nothing was charged. | Search again with `phone_search_numbers`. |
| `check_failed` | Asking the AI assistants failed. Nothing was charged. | Run the check again later. |
| `delivery_failed` | The notification reached no channel, or a channel's test message did not arrive. Nothing was charged. | Check the channel's webhook or token, or add the channel again. |
| `directory_rejected` | The directory refused: the credentials, or the permissions given to them, are not enough for that. | Ask the directory's admin to grant what the message names, then try again. |
| `email_failed` | The email with the document could not be sent. The document stays as it was and nothing was charged. | Try again in a moment. |
| `fetch_failed` | The link did not answer. | Check the link and try again. |
| `refund_refused` | Stripe refused the refund, for instance because the way it was paid can't be refunded. Nothing was refunded. | The payer can ask Link's support, which can refund a payment within 60 days. |
| `send_failed` | The email service did not accept the email. | Call again in a moment. The message says what was saved. |
| `service_refused` | The business's own email service turned the email down, often a from address it does not allow. | Allow the from address in the service, or connect it with one it allows. |
| `service_unreachable` | The business's own email service could not be reached, or the connection dropped. | Check the SMTP server and port (587 or 465), then try again. |
| `stripe_error` | Stripe refused or could not do what was asked (an invoice's payment page, its webhook). | Try again. The message gives Stripe's reason. |
| `vendor_rejected` | The company's Microsoft 365 or Google Workspace refused: its app lacks a permission or the admin's consent, or it said no to the request. | Ask the admin to grant what the message names, then try again. |
| `vendor_unavailable` | The other service an import reads from did not answer. Nothing was charged. | Try again in a few minutes, with the same `next_cursor` if you passed one. |

## 503 Unavailable

| Code | What it means | What to do |
| --- | --- | --- |
| `bridge_offline` | The company's bridge, the program inside its network that reaches systems behind its firewall, has not checked in for over 30 seconds. Nothing was charged. | Ask the company's IT to start the bridge, then call again. |
| `busy` | The workers that read files or run code are busy with other calls. Nothing was charged. | Try again in a minute. |
| `calendar_unavailable` | The business's connected calendar could not be checked, so nothing can be booked. | Try again in a few minutes. |
| `carrier_refused` | The phone carrier could not complete the order just now. Nothing was charged. | Search again with `phone_search_numbers` and try another number. |
| `carrier_unavailable` | The phone carrier could not be reached. | Try again in a minute. The message says what is kept. |
| `check_unavailable` | Every new email is checked for cold outreach before it goes, and the check couldn't run just now. Nothing was sent or charged. | Try again in a minute. |
| `directory_unavailable` | The company's directory (Entra ID or Okta) or its sign-in could not be reached. | Try again in a minute. Nothing changed. |
| `not_switched_on` | This kind of tool (social posting, running code) is not switched on yet. Nothing was charged. | Try again later. |
| `phone_unavailable` | The phone service is not available right now. Nothing was charged. | Try again later. |
| `rates_loading` | The day's exchange rates are still loading. | Try again in a few minutes, or pass the rate yourself. |
| `sandbox_unavailable` | The code sandbox is not available or did not answer. Nothing was charged. | Try again later. |
| `search_unavailable` | The search service is not available or did not answer. Nothing was charged. | Try again later. |
| `sending_unavailable` | Email to outsiders is not possible yet while the sending account is in review, or the email service turned the emails away. | Send to the owner's address for now, or try again later. |
| `service_busy` | The business's own email service asked to slow down. | Try again in a few minutes. |
| `social_unavailable` | The social posting service or Telegram did not answer, or the business's social workspace could not be opened. Nothing was charged. | Call again in a minute. When the message says so, tell Conecto's support. |
| `unavailable` | The tool, or a service it needs, is not available right now (or not switched on yet). Nothing was charged. | Try again later. |

## 504 Timed out

| Code | What it means | What to do |
| --- | --- | --- |
| `timeout` | The site took too long to send the page. | Try again later. |

---

Source: https://conecto.chat/docs/event-kinds

# Event kinds

Every kind of event an account can get, by area. Each carries the same fields, and its data holds the facts listed under it.

## The fields of every event

Every event has `event_id`, `kind`, `title`, `text`, `data`, `link` and `occurred_at`. [Events and webhooks](https://conecto.chat/docs/events.md) explains them, how to read events and how to send them to a channel.

To get one, subscribe a channel to its kind with `notify_subscribe`, to its whole area with `area.*`, or poll `account_events`. The lists under each kind name the fields of its `data`, read from the code that sends it. A bot's own events, `custom.<name>`, carry whatever the bot sent.

## Account

### `account.budget_alert`

A team reached the alert line of its budget (once a period: a month, a quarter, a fiscal year or a project).

`data` carries `team`, `spent_usd`, `budget_usd`, `alert_percent`, `period`, `budget_period` and `budget`. Sometimes it also carries `month`.

### `account.balance_low`

With auto-reload off, the balance is down to a fifth of what the last top-up left (once per top-up).

`data` carries `balance_usd`, `after_last_top_up_usd` and `auto_reload`. It can carry more fields than these.

### `account.join_requested`

Someone on one of the account's email domains asks to join it: approve or decline with `admin_decide_join_request`.

`data` carries `request_id`, `email`, `name`, `domain` and `decide_with`.

### `account.person_joined`

Someone joined the account with their work address, right away or once approved.

`data` carries `email`, `name`, `domain` and `team`. Sometimes it also carries `approved_by`.

### `account.dashboard_change`

A person changed something on a dashboard link, as the key that asked for the link: what (the tool), on which page, and the call (`account_get_call` has its result).

`data` carries `tool`, `action`, `area`, `call_id` and `bot`.

### `account.limit_request_answered`

Conecto answered a request for a higher limit: approved (with the amount granted) or declined, with its note.

`data` carries `request_id`, `limit`, `status`, `asked_for` and `granted`.

### `account.balance_empty`

With auto-reload off, the balance ran out: paid tools are refused until someone adds credit (once per top-up).

`data` carries `balance_usd`, `after_last_top_up_usd` and `auto_reload`. It can carry more fields than these.

## Calendar

### `calendar.booking_created`

Someone booked a meeting.

`data` carries `reference`, `meeting_type`, `start`, `end`, `name`, `email`, `phone`, `source`, `hosts`, `guests` and `reason`.

### `calendar.booking_moved`

A meeting moved to another time.

`data` carries `reference`, `meeting_type`, `start`, `end`, `name`, `email`, `phone`, `source`, `hosts`, `guests` and `reason`.

### `calendar.booking_cancelled`

A meeting was cancelled.

`data` carries `reference`, `meeting_type`, `start`, `end`, `name`, `email`, `phone`, `source`, `hosts`, `guests` and `reason`.

### `calendar.routed`

Someone answered a routing form and was sent on.

Sometimes it also carries `reference`, `meeting_type`, `start`, `end`, `name`, `email`, `phone`, `source`, `hosts`, `guests`, `reason`, `form`, `response_id`, `answers`, `route` and `to`.

## Company data

### `companies.matched`

A company list finished matching to the registers: how many rows matched, were ambiguous or not found, what that cost, and the results file (`account_get_call` shows the result).

`data` carries `match_id`, `rows`, `matched`, `ambiguous`, `not_found`, `no_country`, `register_unavailable`, `charged_usd` and `file_id`.

## E-signature

### `esign.completed`

Everyone signed a document.

`data` carries `request_id`, `title`, `file_id` and `signers`.

### `esign.declined`

A signer declined a document.

`data` carries `request_id`, `title`, `name`, `email` and `reason`.

### `esign.signed`

A signer signed a document others still have to sign: who signed and who is left (the last signature sends `esign.completed` instead).

`data` carries `request_id`, `title`, `name`, `email`, `signed`, `signers`, `waiting_on` and `asked_now`.

## Email

### `email.received`

An email arrived in one of the account's inboxes (with an inbox that saves attachments: files, the `file_ids` they became, and `attachments_not_saved` with why).

`data` carries `message_id`, `inbox`, `from`, `from_name` and `subject`. Sometimes it also carries `files` and `attachments_not_saved`.

## Files

### `files.added`

A file arrived from outside the bot (an upload link, or an email attachment saved by email-in), with its text once read, so you can file it (`files_edit`).

`data` carries `file_id`, `name`, `content_type`, `size_bytes`, `source`, `duplicate_of`, `text_status`, `text`, `text_truncated` and `ocr_pages`. Sometimes it also carries `email`.

## Forms

### `forms.response_received`

A form got a response.

`data` carries `form`, `response_id` and `answers`. Sometimes it also carries `actions` and `confirmed_to`.

## Help desk

### `helpdesk.ticket_created`

A new ticket opened: from an email, a phone message or a form response.

`data` carries `ticket_id`, `number`, `from` and `subject`.

### `helpdesk.customer_replied`

A customer replied on a ticket.

`data` carries `ticket_id`, `number`, `from` and `subject`.

## Hiring

### `hiring.application_received`

Someone applied to a job.

`data` carries `applicant_id` and `job`. Sometimes it also carries `name`, `email`, `phone`, `links`, `has_resume`, `flags` and `sealed`.

### `hiring.candidate_passed`

An application passed its job's filter once the bot's screening was saved: who, the match score and the screening's summary. The hiring team is also emailed.

`data` carries `applicant_id`, `job`, `name`, `email`, `match`, `match_score`, `summary`, `risk` and `filter`.

### `hiring.test_completed`

A candidate finished a skills test.

`data` carries `applicant_id` and `assessment`.

### `hiring.interview_booked`

An invited candidate booked their interview.

`data` carries `applicant_id`, `job`, `reference` and `start`.

## HR

### `hr.policy_acknowledged`

Someone confirmed they read a policy (`hr_send_policy`).

`data` carries `policy`, `version`, `person_id` and `name`.

### `hr.daily`

The day in HR, each morning from 7:00 in the HR time zone when there is something to say: who starts, whose last day it is, who is out, birthdays and work anniversaries, probations ending within 7 days, documents expiring within 30 days, and checklist tasks due or overdue.

Its `data` depends on the day, and its `text` says it in words.

## Inventory

### `inventory.low_stock`

An item fell to its reorder point (sent once until it is restocked).

`data` carries `sku`, `name`, `quantity`, `unit`, `reorder_point` and `locations`.

## Invoices

### `invoices.paid_online`

A customer paid an invoice on its page (`invoices_set_profile` `pay_online`): the payment is recorded on it and posted to the books.

`data` carries `invoice_id`, `number`, `amount`, `currency`, `balance` and `status`. It goes out at once.

### `invoices.quote_accepted`

A customer accepted a quote on its page.

`data` carries `document_id`, `number`, `total`, `currency`, `customer`, `name` and `note`.

### `invoices.quote_declined`

A customer declined a quote on its page.

`data` carries `document_id`, `number`, `total`, `currency`, `customer`, `name` and `note`.

### `invoices.overdue`

An invoice the business sent is past its due date and still owed. Sent once per invoice, the day after it falls due where the business is.

`data` carries `invoice_id`, `number`, `customer`, `customer_email`, `balance`, `currency`, `due_date` and `days_overdue`.

## Newsletters

### `newsletters.subscribed`

Someone confirmed their newsletter subscription.

`data` carries `newsletter`, `email` and `name`.

### `newsletters.unsubscribed`

Someone unsubscribed from a newsletter.

`data` carries `newsletter` and `email`.

### `newsletters.issue_refused`

A scheduled issue wasn't sent: when it fell due, it looked like cold outreach.

`data` carries `newsletter`, `issue_id` and `number`.

### `newsletters.sending_stopped`

The business's own email service failed (a refused login, no connection, or it turned an email down): newsletters wait and are tried again every 10 minutes until it works (once per failure, not on every retry).

`data` carries `host`, `error` and `retry_after_minutes`.

## Notifications

### `notify.answered`

A person answered a question you asked with `notify_request_approval`: the option they picked and their comment.

`data` carries `request_id`, `question`, `details`, `options`, `status`, `answer`, `comment`, `answered_at`, `reference`, `sent_to`, `via`, `expires_at` and `created_at`. Sometimes it also carries `needed` and `approvals`. It goes out at once.

## Outreach

### `outreach.replied`

Someone answered an outreach email: who, the campaign and their reply's text. Their follow-ups stopped. `outreach_set_status` keeps whether they are interested.

`data` carries `campaign_id`, `campaign`, `reply_id`, `email`, `name`, `contact_id`, `subject` and `text`.

### `outreach.paused`

An outreach campaign paused on its own: the key that made it could not pay for the next person (its budget, the account's ceiling, or the key was revoked), with the reason. Resume it with `outreach_resume` once that is fixed.

`data` carries `campaign_id`, `name` and `reason`.

### `outreach.mailbox_connected`

The owner connected a mailbox for outreach from the link `outreach_connect_mailbox` gave: its `mailbox_id`, address and daily limit.

`data` carries `mailbox_id`, `email`, `sender_name` and `daily_limit`.

## Phone

### `phone.message_left`

A caller left a message on the business's line (the transcript is in the event), also when the balance couldn't pay for the call and the line took the message for free.

`data` carries `call_id`, `from`, `to`, `duration_seconds`, `answered_by` and `transcript`. Sometimes it also carries `message_id`, `reason`, `why`, `recording_file_id`, `charged_usd`, `note` and `ticket`.

### `phone.call_ended`

A call your bot answered ended (the whole transcript is in the event).

`data` carries `call_id`, `from`, `to`, `duration_seconds`, `answered_by` and `transcript`. Sometimes it also carries `ticket`.

## Prospects

### `prospects.found`

A prospect search ended: how many prospects it found of those asked for and what that cost (`prospects_get` lists them).

`data` carries `search_id`, `status`, `asked`, `found` and `charged_usd`.

### `prospects.needs_input`

A prospect search stopped finding new prospects and asks whether to widen it, with its question. Answer with `prospects_answer` or end it with `prospects_stop` (once a question).

`data` carries `search_id`, `summary` and `questions`.

## Purchasing

### `purchasing.bill_due`

A supplier bill falls due within 3 days (or is past due when recorded). Sent once per bill.

`data` carries `bill_id`, `supplier`, `reference`, `status`, `overdue`, `days_overdue`, `currency`, `issue_date`, `due_date`, `planned_date`, `total`, `amount_paid`, `balance`, `order` and `days_left`.

## Social

### `social.post_published`

A post went out on a social network (with its link).

`data` carries `post_id`, `channel_id`, `network`, `network_name`, `channel`, `publish_at` and `url`.

### `social.post_failed`

A social post could not be published, with Postiz's reason. Its charge is refunded.

`data` carries `post_id`, `channel_id`, `network`, `network_name`, `channel`, `publish_at`, `reason` and `refunded`.

### `social.post_confirmed`

The owner pressed Post on a TikTok post's page, with who may see it and their other choices. `social.post_published` or `social.post_failed` follows.

`data` carries `check_id`, `channel_id`, `network`, `network_name`, `status`, `publish_at`, `expires_at`, `post_id` and `choices`. It goes out at once.

### `social.post_declined`

A TikTok post waiting for its owner was not posted: they said no, or its link ran out. Its charge is refunded.

`data` carries `check_id`, `channel_id`, `network`, `network_name`, `status`, `publish_at`, `expires_at`, `post_id`, `reason` and `refunded`.

### `social.channel_connected`

The owner connected a social account from a link `social_connect` gave.

`data` carries `channel_id`, `network`, `network_name`, `name`, `profile`, `picture` and `disabled`.

## Uptime

### `uptime.down`

A monitored site went down.

`data` carries `monitor_id`, `name`, `url` and `error`. It goes out marked urgent where the channel has a priority, like ntfy and Pushover.

### `uptime.up`

A monitored site is back up.

`data` carries `monitor_id`, `name`, `url` and `error`.

## Website analytics

### `analytics.traffic_spike`

More people are on a site right now than its alert's number.

`data` carries `site`, `site_id`, `visitors_now`, `alert_at` and `pages`.

### `analytics.weekly_summary`

A site's visits last week, every Monday morning.

`data` carries `site`, `site_id`, `period`, `change_percent`, `pages`, `sources` and `goals`. It can carry more fields than these.

### `analytics.goal_completed`

A visitor reached a goal set with notify (`analytics_set_goals`), with where their visit came from, its landing page, the pages seen, country, device and revenue.

`data` carries `site`, `site_id`, `goal`, `event`, `page`, `visit`, `source`, `channel`, `referrer`, `campaign`, `landing_page`, `pages`, `pageviews`, `seconds_on_site`, `country`, `device` and `props`. Sometimes it also carries `revenue`. It goes out at once.

### `analytics.broken_page`

A page answered an error (404 or worse) to a real visitor, with the page that links there. Once a week a page.

`data` carries `site`, `site_id`, `page`, `status` and `linked_from`.

## Website chat

### `chat.message_received`

A visitor wrote in the website chat (first: true on a new chat): answer with `chat_reply`. With a webhook brain it says what the brain answered (`answered_by`, reply or unanswered).

`data` carries `conversation_id`, `message_id`, `first`, `text`, `visitor`, `experience`, `page` and `reply_with`. It can carry more fields than these. It goes out at once.

## Whistleblowing

### `whistleblowing.report_received`

A report reached the whistleblowing channel: its case number, category and deadlines, never its content.

`data` carries `case_number`, `category`, `received_at` and `feedback_due`.

---

Source: https://conecto.chat/docs/tools

# Tools

Conecto has 581 tools in 52 areas. The tools directory gives each one a page with its inputs, its price, an example call and a real reply.

## Reading a tool's page

Each tool's page in the [tools directory](https://conecto.chat/tools.md) holds:

- What the tool does and when to use it, with the look-alike tools for other cases.
- Its price. A call that fails costs nothing.
- Its inputs, with their types and limits.
- An example call and the reply the tool really gave, for one of the example businesses.
- The call over MCP and over REST, and the codes it answers when it refuses.

Every page has its Markdown at its address plus `.md`, like https://conecto.chat/tools/crm/crm_save_contact.md, and https://conecto.chat/tools.md lists every area. `GET https://api.conecto.chat/v1/tools` gives the same catalog as JSON.

## Customers and sales

11 areas, 148 tools.

| Area | Tools | What it does |
| --- | --- | --- |
| [CRM](https://conecto.chat/tools/crm.md) | 41 | Contacts, companies and deals, with every email, call, invoice and meeting on one record. |
| [Prospects](https://conecto.chat/tools/prospects.md) | 7 | Businesses that could buy from you and who to reach there, with their work email checked. |
| [Outreach](https://conecto.chat/tools/outreach.md) | 13 | Email campaigns your agent writes, sent from your own mailbox, with every reply tracked in the CRM. |
| [Email](https://conecto.chat/tools/email.md) | 10 | Inboxes on your business’s own subdomain that send, receive and keep threads. |
| [Website chat](https://conecto.chat/tools/chat.md) | 9 | Your website’s chat widget, answered by your agent. |
| [Phone](https://conecto.chat/tools/phone.md) | 8 | Phone numbers your agent answers, with a transcript of every call. |
| [Calendar](https://conecto.chat/tools/calendar.md) | 13 | Booking pages, free times and meetings, like Calendly. |
| [Help desk](https://conecto.chat/tools/helpdesk.md) | 13 | Support tickets from email, with SLAs, queues and ratings. |
| [Help center](https://conecto.chat/tools/helpcenter.md) | 20 | A public help center your agent designs and writes. |
| [Forms](https://conecto.chat/tools/forms.md) | 12 | Forms and surveys on your own pages, from quote requests to NPS. |
| [Company & email lookups](https://conecto.chat/tools/lookups.md) | 2 | Company facts from a domain, and whether an address takes mail. |

## Marketing and the web

6 areas, 68 tools.

| Area | Tools | What it does |
| --- | --- | --- |
| [Newsletters](https://conecto.chat/tools/newsletters.md) | 15 | Newsletters with double opt-in, an archive and click counts. |
| [Social](https://conecto.chat/tools/social.md) | 13 | Posts to LinkedIn, Bluesky, Mastodon, Telegram and other networks. |
| [Websites](https://conecto.chat/tools/websites.md) | 11 | A website built from sections, with a blog, previewed before it goes live. |
| [Website analytics](https://conecto.chat/tools/analytics.md) | 18 | Cookie-free visitor stats, events your agent defines, and which channels bring the money. |
| [AI visibility](https://conecto.chat/tools/visibility.md) | 5 | How ChatGPT, Claude, Gemini and others describe your business. |
| [Links & QR codes](https://conecto.chat/tools/links.md) | 6 | Short links that count clicks, and QR codes. |

## Commerce and money

4 areas, 92 tools.

| Area | Tools | What it does |
| --- | --- | --- |
| [Invoices](https://conecto.chat/tools/invoices.md) | 24 | Quotes and invoices numbered without gaps, sent as PDFs, paid online. |
| [Bookkeeping](https://conecto.chat/tools/books.md) | 33 | Double-entry bookkeeping with bank matching, reports and DATEV export. |
| [Purchasing](https://conecto.chat/tools/purchasing.md) | 25 | Suppliers, purchase orders and bills, posted to the books. |
| [Inventory](https://conecto.chat/tools/inventory.md) | 10 | Stock by item and location, at moving-average cost. |

## M&A and corporate finance

5 areas, 28 tools.

| Area | Tools | What it does |
| --- | --- | --- |
| [Company data](https://conecto.chat/tools/companies.md) | 9 | Who runs a company, who owns it and what it has earned, from official registers and filings. |
| [Valuation](https://conecto.chat/tools/valuation.md) | 11 | DCF, WACC, trading multiples, LBO and peer benchmarks, worked the same way every time, free. |
| [Longlists](https://conecto.chat/tools/longlists.md) | 2 | Companies to buy, or the companies that could buy one, scored out of 100 with their reasons. |
| [Market data](https://conecto.chat/tools/markets.md) | 3 | How big an industry is, how much of a product is made and traded, and how its prices and costs move. |
| [Mergers & acquisitions](https://conecto.chat/tools/mergers.md) | 3 | Who bought whom, from merger authorities and SEC filings read every day, with a price only where a filing states one. |

## People

4 areas, 63 tools.

| Area | Tools | What it does |
| --- | --- | --- |
| [HR](https://conecto.chat/tools/hr.md) | 23 | People records, time off and onboarding checklists. |
| [Hiring](https://conecto.chat/tools/hiring.md) | 25 | A careers page, applications, stages and skills tests. |
| [Whistleblowing](https://conecto.chat/tools/whistleblowing.md) | 4 | The reporting channel EU employers with 50 or more staff must run. |
| [Directory](https://conecto.chat/tools/directory.md) | 11 | Your Microsoft Entra ID or Okta, run by your agent for joiners and leavers. |

## Your company’s own systems

6 areas, 46 tools.

| Area | Tools | What it does |
| --- | --- | --- |
| [Microsoft 365](https://conecto.chat/tools/microsoft365.md) | 11 | Your company’s own Outlook mail, calendars and OneDrive, as the mailboxes you name. |
| [Google Workspace](https://conecto.chat/tools/googleworkspace.md) | 11 | Your company’s own Gmail, Google Calendar and Drive, as the mailboxes you name. |
| [HubSpot](https://conecto.chat/tools/hubspot.md) | 7 | Your company’s own HubSpot contacts, companies, deals and tickets, through its private app. |
| [Salesforce](https://conecto.chat/tools/salesforce.md) | 6 | Your company’s own Salesforce records, queried and changed through its connected app. |
| [Connections](https://conecto.chat/tools/connect.md) | 6 | Your ERP, ticketing tool or any API, each connection limited to the calls it allows. |
| [Import](https://conecto.chat/tools/imports.md) | 5 | Records brought over from HubSpot, Pipedrive, Zendesk or a CSV. |

## Work and documents

6 areas, 59 tools.

| Area | Tools | What it does |
| --- | --- | --- |
| [Projects](https://conecto.chat/tools/projects.md) | 9 | Boards of numbered tasks, like Linear. |
| [E-signature](https://conecto.chat/tools/esign.md) | 10 | PDFs signed in the browser and sealed with a signing certificate. |
| [Documents](https://conecto.chat/tools/documents.md) | 8 | PDFs from Markdown, HTML or Word files, and filled Word templates. |
| [Files](https://conecto.chat/tools/files.md) | 13 | A private file store, searchable by the words inside. 1 GB free. |
| [Tables](https://conecto.chat/tools/tables.md) | 12 | Shared tables with typed columns, like Airtable. |
| [Views](https://conecto.chat/tools/views.md) | 7 | Charts and tables for a person, behind a link that opens once. |

## Operations and the account

7 areas, 70 tools.

| Area | Tools | What it does |
| --- | --- | --- |
| [Notifications](https://conecto.chat/tools/notify.md) | 9 | Messages to Slack, Teams, Discord, Telegram or a webhook. |
| [Schedules](https://conecto.chat/tools/schedules.md) | 6 | Tool calls on a timetable, or once at a set time. |
| [Uptime](https://conecto.chat/tools/uptime.md) | 6 | Checks every 1 to 60 minutes, alerts and a status page. |
| [Vault](https://conecto.chat/tools/vault.md) | 5 | Encrypted secrets your agent uses, kept out of the call log. |
| [Code](https://conecto.chat/tools/code.md) | 1 | Python or Node.js in a fresh, offline sandbox. |
| [Account](https://conecto.chat/tools/account.md) | 28 | Balance, call log, events and one search across everything. |
| [Account admin](https://conecto.chat/tools/admin.md) | 15 | The account page for your agent: people, teams, join codes and colleagues joining by work address. |

## Search, speech and images

3 areas, 7 tools.

| Area | Tools | What it does |
| --- | --- | --- |
| [Web](https://conecto.chat/tools/web.md) | 2 | Web search with each result’s title, link and snippet, and any page as Markdown. |
| [Speech](https://conecto.chat/tools/speech.md) | 3 | Transcripts in about 100 languages, and text read aloud. |
| [Images](https://conecto.chat/tools/images.md) | 2 | Images resized, cropped and converted, location data removed. |

---

Source: https://conecto.chat/docs/for-agents

# Files for AI agents

An agent learns Conecto from files, with no person in between. These are the files, where they live and what each one holds.

## Start here

| File | Address | What it holds |
| --- | --- | --- |
| SKILL.md | https://conecto.chat/SKILL.md | How to sign up, call, pay and keep the business safe, then every area with its prices and tools. |
| About Conecto | https://conecto.chat/ai-questions.md | What Conecto is, who founded it, what it costs and its key facts. The same facts as JSON at https://conecto.chat/ai-questions.json. |
| The docs | https://conecto.chat/docs/all.md | Every page of these docs in one Markdown file. |
| The docs' index | https://conecto.chat/docs/index.json | Each page's title, description, address and Markdown address. |
| The tools | https://conecto.chat/tools.md | Every area with its tools and prices, in Markdown. |
| The REST API | https://api.conecto.chat/v1/openapi.json | OpenAPI 3.1 with every route and every tool. |

## SKILL.md

https://conecto.chat/SKILL.md is the file an agent keeps in every session, and https://api.conecto.chat/v1/skill.md answers the same. Its sections:

- Start: one call
- Then connect over MCP, once
- Calling tools
- The business's own systems
- Running the account
- Money
- Rules that keep the business safe
- Areas and tools

Agents that look for skills on their own find it in the skills index at https://conecto.chat/.well-known/agent-skills/index.json, in the draft Agent Skills discovery format:

```json
{
  "$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json",
  "skills": [
    {
      "name": "conecto",
      "type": "skill-md",
      "description": "Use Conecto when a business needs a backend you can run yourself: CRM, email inboxes, phone numbers answered by an AI assistant, website chat, help desk and help center, AI visibility and more. One API call signs up with $1.00 free credit; every tool call is paid from a prepaid balance, and failed calls cost nothing.",
      "url": "/.well-known/agent-skills/conecto/SKILL.md",
      "digest": "sha256:34e940f023c9664df1f66a934abb6db9437f903263de49e1ae26fa36c19a0671"
    }
  ]
}
```

The digest is the SHA-256 of the file's bytes, so an agent can check the copy it fetched. The older index at https://conecto.chat/.well-known/skills/index.json lists the same file for Hermes Agent.

## The catalog

These answer without a key.

| Address | What it answers |
| --- | --- |
| `GET https://api.conecto.chat/v1` | What Conecto is, how to sign up, the prices in a few words and every area's MCP address. |
| `GET https://api.conecto.chat/v1/areas` | Every area with its summary and its number of tools. |
| `GET https://api.conecto.chat/v1/tools` | Every tool with its price, or one area's with `?area=crm`. |
| `GET https://api.conecto.chat/v1/tools/<name>` | One tool with its input schema and examples. |
| `https://conecto.chat/tools/<area>/<tool>.md` | One tool's page: its inputs, an example call, a real reply and its errors. |

[The REST API](https://conecto.chat/docs/api.md#discovery) shows each reply.

## OpenAPI

| File | Address |
| --- | --- |
| Every route and tool, OpenAPI 3.1 | `https://api.conecto.chat/v1/openapi.json` |
| One area, OpenAPI 3.0, for tools that import it (custom GPTs until OpenAI retires them on December 11, 2026) | `https://api.conecto.chat/v1/openapi/<area>.json` |
| One area, OpenAPI 2.0, for Power Platform | `https://api.conecto.chat/v1/openapi/<area>.swagger.json` |

Every page of these docs names the full file in a `<link rel="service-desc">` in its head.

## MCP servers

`https://api.conecto.chat/v1/mcp` serves every area a key may use, whether an agent sends its key or an assistant signs in, and `https://api.conecto.chat/mcp/<area>` one area at a time, for an agent with a key. [Connect your agent](https://conecto.chat/docs/connect.md#addresses) lists the addresses. A server answers `initialize` like this:

initialize, the reply:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-11-25",
    "capabilities": {
      "tools": {
        "listChanged": false
      }
    },
    "serverInfo": {
      "name": "conecto-crm",
      "version": "1.0.0",
      "title": "Conecto CRM"
    },
    "instructions": "Conecto CRM: Contacts, companies and deals in pipelines, with notes, tasks, tags, custom fields, saved segments, one search, full timelines, duplicate merging, bulk saves, reports and CSV export: the business's customer records. Every tool lists its price; reads are free up to 1,000,000 a month for the account (then $0.50 per 10,000), and a call that fails is never charged. Pay from your Conecto balance (GET https://api.conecto.chat/v1/balance)."
  }
}
```

## OAuth

A connector's sign-in follows OAuth 2.1. The authorization server's metadata:

The authorization server:

```json
{
  "issuer": "https://conecto.chat/api/bots/oauth",
  "authorization_endpoint": "https://conecto.chat/api/bots/oauth/authorize",
  "token_endpoint": "https://conecto.chat/api/bots/oauth/token",
  "registration_endpoint": "https://conecto.chat/api/bots/oauth/register",
  "revocation_endpoint": "https://conecto.chat/api/bots/oauth/revoke",
  "response_types_supported": ["code"],
  "grant_types_supported": [
    "authorization_code",
    "refresh_token",
    "urn:ietf:params:oauth:grant-type:jwt-bearer"
  ],
  "token_endpoint_auth_methods_supported": ["none"],
  "revocation_endpoint_auth_methods_supported": ["none"],
  "code_challenge_methods_supported": ["S256"],
  "scopes_supported": ["tools", "offline_access"],
  "authorization_response_iss_parameter_supported": true,
  "service_documentation": "https://conecto.chat/tools"
}
```

The connector's protected-resource metadata:

The connector:

```json
{
  "resource": "https://api.conecto.chat/v1/mcp",
  "authorization_servers": ["https://conecto.chat/api/bots/oauth"],
  "scopes_supported": ["tools"],
  "bearer_methods_supported": ["header"],
  "resource_name": "Conecto",
  "resource_documentation": "https://conecto.chat/docs/connect"
}
```

## These docs in Markdown

- Every page has a Markdown twin at its address plus `.md`, like https://conecto.chat/docs/keys.md, and its links are full addresses.
- A request for a page with `Accept: text/markdown` gets the twin at the page's own address.
- https://conecto.chat/docs/all.md holds every page in one file, in the order of the navigation.
- https://conecto.chat/docs/index.json lists every page with its title, description, address and Markdown address.

Terminal:

```bash
curl -H "Accept: text/markdown" https://conecto.chat/docs/quickstart
```

Each page also has buttons that copy its Markdown or open it in ChatGPT or Claude. The site's https://conecto.chat/llms.txt lists its main pages for language models.
