Convo Public API v1

Programmatic access to leads, conversations, agents, and analytics. Every endpoint is scoped to a single workspace via the API token you present. Generate a token at /app/settings/api-tokens.

Base URL:https://api.avelto.pl/api/v1

SDKs & spec

Download the OpenAPI 3.1 specification, import the Postman collection, or install the official TypeScript SDK to skip the wire-format wiring entirely.

OpenAPI 3.1

Full machine-readable spec. Generate clients in any language.

Download openapi.json →

Postman collection

Pre-wired requests with the Authorization header bound to a{{apiToken}} variable.

Download postman.json →

TypeScript SDK

Native fetch under the hood. Single retry on 5xx, never on 4xx. Works in Node, browsers, and edge runtimes.

pnpm add @convo/sdk

import { AveltoClient } from '@convo/sdk';
const client = new AveltoClient({ apiKey: process.env.AVELTO_TOKEN! });
const leads = await client.leads.list({ status: 'QUALIFIED' });

Authentication

Pass your token in the Authorization header on every request. Tokens look like convo_ followed by 32 hex characters. The plaintext is shown only once at creation — store it in your secrets manager.

Authorization: Bearer convo_a1b2c3d4e5f6...

Tokens are workspace-scoped. A token created in workspace A cannot read workspace B's data even if the underlying user has access to both — a token always carries the workspace it was issued in.

Scopes

Each endpoint requires one or more scopes. When creating a token, grant the smallest set that lets your integration do its job.

conversations:read

List conversations and read transcripts.

conversations:write

Send operator messages and update conversation state.

leads:read

Read lead records.

leads:write

Create or update leads.

agents:read

List workspace agents.

agents:write

Create or update agents (uncommon — UI-only today).

analytics:read

Read aggregate workspace analytics.

Rate limits

  • 60 requests / minute / IP — applies to unauthenticated callers.
  • 600 requests / minute / workspace / route — applies to token-authenticated callers; per-route so a flood on one endpoint doesn't starve others.
  • Sensitive endpoints (login / widget messages) ship tighter per-route throttles via @Throttle decorators.

Limits can be lifted on the Business plan. Contact hello@avelto.pl with your traffic profile.

Errors

Errors return a structured JSON body. Common statuses:

401Unauthorized

Missing, invalid, revoked, or expired token.

403Forbidden

Token is missing a required scope. The error body includes the missing scope name.

404Not Found

Resource does not exist OR exists in a different workspace (we do not leak the difference).

429Too Many Requests

Rate limit hit. Backoff per the Retry-After header.

5xxServer error

Bug on our side. The body includes a request ID — share it with support.

Endpoints

GET/api/v1/leadsleads:readLeads

List leads

Paginated list of leads in the workspace. Supports status filtering and a sort order (newest | score).

Response

[
  {
    "id": "uuid",
    "status": "QUALIFIED",
    "fields": { "name": "Anna Nowak", "email": "anna@example.com" },
    "score": 78,
    "conversationId": "uuid",
    "crmExternalId": null,
    "createdAt": "2026-04-30T12:00:00.000Z"
  }
]

Example

curl -H "Authorization: Bearer convo_xxx" \
  "https://api.avelto.pl/api/v1/leads?sort=score"
POST/api/v1/leadsleads:writeLeads

Create a lead

Manually create a lead — useful when wiring inbound webhooks from a form or third-party intake.

Request body

{
  "fields": {
    "name": "Anna Nowak",
    "email": "anna@example.com",
    "phone": "+48 111 222 333"
  },
  "source": "external-form"
}

Response

{
  "id": "uuid",
  "status": "NEW",
  "fields": { "name": "Anna Nowak" },
  "score": null,
  "conversationId": null,
  "createdAt": "2026-04-30T12:00:00.000Z"
}

Example

curl -X POST -H "Authorization: Bearer convo_xxx" \
  -H "Content-Type: application/json" \
  -d '{"fields":{"name":"Anna","email":"anna@example.com"}}' \
  "https://api.avelto.pl/api/v1/leads"
PATCH/api/v1/leads/:id/statusleads:writeLeads

Update lead status

Move a lead across pipeline stages (NEW / QUALIFIED / CONTACTED / WON / LOST). Returns the updated row.

Request body

{ "status": "WON" }

Response

{
  "id": "uuid",
  "status": "WON",
  "updatedAt": "2026-04-30T12:05:00.000Z"
}

Example

curl -X PATCH -H "Authorization: Bearer convo_xxx" \
  -H "Content-Type: application/json" \
  -d '{"status":"WON"}' \
  "https://api.avelto.pl/api/v1/leads/uuid/status"
GET/api/v1/conversationsconversations:readConversations

List conversations

Paginated conversation list. Filter by agentId, channelId, status, or comma-separated tagIds.

Response

[
  {
    "id": "uuid",
    "agentId": "uuid",
    "channelId": "uuid",
    "status": "OPEN",
    "createdAt": "2026-04-30T12:00:00.000Z"
  }
]

Example

curl -H "Authorization: Bearer convo_xxx" \
  "https://api.avelto.pl/api/v1/conversations?status=OPEN&limit=50"
GET/api/v1/conversations/:idconversations:readConversations

Fetch a conversation

Full conversation transcript including the message timeline, sentiment, tags, and assigned operator.

Response

{
  "id": "uuid",
  "status": "OPEN",
  "messages": [
    { "id": "uuid", "role": "USER", "content": "...", "createdAt": "..." },
    { "id": "uuid", "role": "ASSISTANT", "content": "...", "createdAt": "..." }
  ]
}

Example

curl -H "Authorization: Bearer convo_xxx" \
  "https://api.avelto.pl/api/v1/conversations/uuid"
POST/api/v1/conversations/:id/operator-messageconversations:writeConversations

Send an operator reply

Post an operator-authored message into a conversation that has been handed off. The reply is delivered through the conversation’s channel.

Request body

{ "content": "Hi Anna — happy to help. What size do you need?" }

Response

{
  "id": "uuid",
  "role": "ASSISTANT",
  "content": "...",
  "createdAt": "2026-04-30T12:10:00.000Z"
}

Example

curl -X POST -H "Authorization: Bearer convo_xxx" \
  -H "Content-Type: application/json" \
  -d '{"content":"Hi there"}' \
  "https://api.avelto.pl/api/v1/conversations/uuid/operator-message"
POST/api/v1/conversations/bulkconversations:writeConversations

Bulk close / reopen conversations

Close, reopen, assign, tag, or untag up to 200 conversations in a single round-trip.

Request body

{
  "ids": ["uuid-1", "uuid-2"],
  "action": "close"
}

Response

{ "updated": 2, "skipped": 0 }

Example

curl -X POST -H "Authorization: Bearer convo_xxx" \
  -H "Content-Type: application/json" \
  -d '{"ids":["uuid-1","uuid-2"],"action":"close"}' \
  "https://api.avelto.pl/api/v1/conversations/bulk"
GET/api/v1/agentsagents:readAgents

List agents

Workspace agents and their publish status. Useful for confirming which agent ID to bind a widget to.

Response

[
  {
    "id": "uuid",
    "name": "Sales agent",
    "status": "PUBLISHED",
    "modelProvider": "openai",
    "modelName": "gpt-4o-mini"
  }
]

Example

curl -H "Authorization: Bearer convo_xxx" \
  "https://api.avelto.pl/api/v1/agents"
GET/api/v1/agents/:idagents:readAgents

Fetch an agent

Single agent by id with its full system prompt + model configuration.

Response

{
  "id": "uuid",
  "name": "Sales agent",
  "systemPrompt": "...",
  "modelProvider": "openai",
  "status": "PUBLISHED"
}

Example

curl -H "Authorization: Bearer convo_xxx" \
  "https://api.avelto.pl/api/v1/agents/uuid"
GET/api/v1/channelsChannels

List channels

Inbound channels (WEBSITE, TELEGRAM, WHATSAPP, MESSENGER, VIBER, EMAIL, SLACK, DISCORD, SMS, VOICE).

Response

[
  {
    "id": "uuid",
    "type": "WEBSITE",
    "name": "Marketing site",
    "agentId": "uuid",
    "createdAt": "2026-04-30T12:00:00.000Z"
  }
]

Example

curl -H "Authorization: Bearer convo_xxx" \
  "https://api.avelto.pl/api/v1/channels"
POST/api/v1/knowledge/uploadKnowledge

Upload a knowledge file

Raw bytes in the request body. Set Content-Type to one of the supported MIMEs (PDF / DOCX / HTML / TXT / MD). Max 10 MB.

Response

{
  "id": "uuid",
  "type": "UPLOAD",
  "status": "PENDING",
  "fileName": "handbook.pdf"
}

Example

curl -X POST -H "Authorization: Bearer convo_xxx" \
  -H "Content-Type: application/pdf" \
  -H "X-Original-Name: handbook.pdf" \
  --data-binary @handbook.pdf \
  "https://api.avelto.pl/api/v1/knowledge/upload"
POST/api/v1/knowledge/crawlKnowledge

Crawl a URL into the knowledge base

Kicks off a multi-page URL crawl. Poll GET /knowledge/jobs/:id for progress.

Request body

{ "url": "https://docs.example.com", "depth": 1 }

Response

{
  "id": "uuid",
  "type": "CRAWL",
  "status": "PENDING",
  "url": "https://docs.example.com"
}

Example

curl -X POST -H "Authorization: Bearer convo_xxx" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://docs.example.com","depth":1}' \
  "https://api.avelto.pl/api/v1/knowledge/crawl"
POST/api/v1/integrations/webhookWebhooks

Subscribe to outbound webhook events

Returns the freshly minted signing secret EXACTLY ONCE. Receivers verify HMAC-SHA256(secret, "<unix>.<body>") against the X-Convo-Signature header.

Request body

{
  "type": "WEBHOOK",
  "url": "https://hooks.example.com/avelto",
  "events": ["lead.created", "conversation.closed"]
}

Response

{
  "id": "uuid",
  "type": "WEBHOOK",
  "url": "https://hooks.example.com/avelto",
  "events": ["lead.created", "conversation.closed"],
  "signingSecret": "wh_a1b2c3..."
}

Example

curl -X POST -H "Authorization: Bearer convo_xxx" \
  -H "Content-Type: application/json" \
  -d '{"type":"WEBHOOK","url":"https://hooks.example.com/avelto","events":["lead.created"]}' \
  "https://api.avelto.pl/api/v1/integrations/webhook"
GET/api/v1/integrationsWebhooks

List webhooks (and other integrations)

Returns every integration row in the workspace. Filter by type === "WEBHOOK" client-side or call client.webhooks.list() in the SDK.

Response

[
  {
    "id": "uuid",
    "type": "WEBHOOK",
    "url": "https://hooks.example.com/avelto",
    "events": ["lead.created"],
    "status": "CONNECTED",
    "createdAt": "2026-04-30T12:00:00.000Z"
  }
]

Example

curl -H "Authorization: Bearer convo_xxx" \
  "https://api.avelto.pl/api/v1/integrations"