Relm
CRM API-first para agentes de IA - contatos, empresas, negócios, pipelines e automações em mais de 41 ferramentas MCP, OAuth 2.1 ou chave bearer.
Documentação
Documentação da API
A Relm é API-first. Tudo o que você pode fazer no dashboard, um agente pode fazer via REST ou no servidor MCP nativo — com a mesma chave bearer.
URL base e autenticação
A API está em https://api.relmcrm.com. Autentique cada requisição com uma chave bearer com escopo no workspace. As chaves são exibidas uma única vez, com hash SHA-256 em repouso, e estão disponíveis nas variantes live e test.
Authorization: Bearer relm_live_...
Gere chaves no dashboard. Chaves relm_test_ gravam em um conjunto de dados de teste isolado, gratuito e invisível para cobrança e para o dashboard — desenvolva à vontade contra elas. O modo de teste é uma sandbox, não armazenamento: registros de teste são excluídos automaticamente 7 dias após a criação.
Início rápido
Crie seu primeiro contato em uma única chamada:
curl https://api.relmcrm.com/v1/contacts \
-H "Authorization: Bearer relm_live_..." \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "first_name": "Ada", "last_name": "Lovelace" }'
Resposta:
{
"id": "con_x8f3k2m9q2",
"object": "contact",
"email": "[email protected]",
"first_name": "Ada",
"last_name": "Lovelace",
"created_at": "2026-07-09T12:00:00.000Z"
}
SDK TypeScript
Prefere tipos em vez de curl? O SDK oficial é um wrapper sem dependências sobre a mesma API.
npm i relmcrm
import { Relm } from "relmcrm";
const relm = new Relm(process.env.RELM_KEY!);
const ada = await relm.contacts.create({ email: "[email protected]", first_name: "Ada" });
await relm.deals.create({ title: "Acme - annual", stage: "lead" });
// page through everything
for await (const c of relm.contacts.all()) console.log(c.id, c.email);
Chamadas com falha lançam um RelmError que você pode ler para se autocorrigir: e.status, e.validOptions, e.hint. Funciona em Node 18+, Bun, Deno e no navegador. No npm: npmjs.com/package/relmcrm.
Convenções
- IDs com prefixo —
con_contatos,cmp_empresas,deal_negócios,act_atividades. Autodescritivos e seguros para copiar e colar. - Envelope — endpoints de listagem retornam
{ "object": "list", "data": [...], "has_more": true, "next_cursor": "..." }. - Paginação por cursor — envie
?limit=100&cursor=.... Keyset sobre(created_at, id), estável sob gravações.limittem como padrão25e é limitado a100(valores maiores são ajustados). - Busca e filtros — endpoints de listagem aceitam
?q=para correspondência de substring sem diferenciar maiúsculas/minúsculas (contatos: nome, e-mail, telefone, LinkedIn; empresas: nome, domínio; negócios: título), além de filtros exatos como?company_id=,?stage=,?pipeline=(alias?pipeline_id=). Um filtro não reconhecido é rejeitado com400+valid_options, para que você nunca receba resultados sem filtro silenciosamente. - Idempotência — envie um cabeçalho
Idempotency-Keyem uma criação; uma nova tentativa retorna o registro original em vez de duplicar. - Concorrência otimista — todo registro carrega um
version; envieIf-Matchpara proteger contra atualizações perdidas. Uma gravação desatualizada retorna412 version_conflict. - Modos — a chave decide
testvslive; os dados nunca se cruzam.
Objetos principais
Contatos, empresas, negócios e atividades têm CRUD completo em /v1/<object> com ferramentas MCP correspondentes (relm_create, relm_list, relm_get, relm_update, relm_delete). As demais superfícies têm endpoints e ferramentas específicos.
| Objeto | Endpoint | O que é |
|---|---|---|
| Contato | /v1/contacts | Pessoas. E-mail opcional — leads apenas com telefone ou LinkedIn são aceitos. |
| Empresa | /v1/companies | Contas. Contatos e negócios se vinculam a elas. |
| Negócio | /v1/deals | Oportunidades em um pipeline + estágio. Carrega um valor. |
| Atividade | /v1/activities | Notas, chamadas, e-mails, reuniões. Pode ser retroativa via occurred_at. |
| Pipeline | /v1/pipelines | Pipelines nomeados, cada um com estágios ordenados. |
| Automação | /v1/automations | Regras acionadas por eventos "quando X então Y". |
| Sequência | /v1/sequences | Sequências de gotejamento em várias etapas com inscrição automática e condições de saída. |
| Modelo | /v1/templates | Modelos de e-mail reutilizáveis referenciados por automações e sequências. |
| Webhook | /v1/webhooks | Assine um endpoint https para eventos. Assinado com HMAC, com novas tentativas e dead-letter. |
| Busca | /v1/search | Busca entre objetos em contatos, empresas e negócios. |
| Schema | /v1/schema | Registro vivo e autodescritivo de objetos + campos + enums. |
Leia o schema primeiro
Antes de gravar, um agente deve GET /v1/schema para aprender quais objetos, campos e valores de enum existem. Se ele enviar um valor desconhecido, o erro informa exatamente o que é válido:
POST /v1/contacts { "type": "prospect" }
422 Unprocessable Entity (application/problem+json)
{
"type": "https://relmcrm.com/errors/unknown_value",
"title": "Unknown Value",
"status": 422,
"detail": "'prospect' is not a valid contact type.",
"code": "unknown_value",
"field": "contact type",
"valid_options": ["lead", "customer"]
}
Este é o contrato "nunca confuso": os agentes se autocorrigem a partir do erro em vez de falhar às cegas ou alucinar um campo. Precisa de um novo valor? Crie-o — relm_create_enum_value, relm_create_field, relm_create_type.
Gravações em lote
Importe muitos registros em uma única ida e volta com POST /v1/batch (ou a ferramenta MCP relm_batch). Cada operação é medida individualmente — o lote economiza idas e voltas, não cota.
POST /v1/batch
{ "operations": [
{ "method": "create", "object": "contact", "data": { "email": "[email protected]" } },
{ "method": "create", "object": "deal", "data": { "title": "Acme" } }
]}
Conecte via MCP
A Relm oferece um servidor nativo Model Context Protocol em https://api.relmcrm.com/mcp (Streamable HTTP, request/response). Toda operação de CRM é uma ferramenta MCP tipada. Nenhuma chave é necessária para initialize ou tools/list — o catálogo é público para que clientes e diretórios possam descobri-lo; tools/call exige uma credencial.
Duas formas de conectar. Se o seu cliente suporta OAuth (a maioria dos clientes de chat suporta), basta apontá-lo para a URL do servidor e ele o guiará pelo login — o cliente se registra, você aprova no navegador e nunca lida com um segredo. Se preferir colar uma chave, ou estiver configurando um servidor ou um job de CI, use uma chave de API em um cabeçalho:
{
"mcpServers": {
"relm": {
"type": "http",
"url": "https://api.relmcrm.com/mcp",
"headers": { "Authorization": "Bearer relm_live_..." }
}
}
}
Depois fale com ele em linguagem natural: "adicione estes cinco leads e abra um negócio para cada um no pipeline de vendas." O agente chama relm_describe_schema e então envia as gravações em lote. Um único POST MCP pode carregar uma matriz de chamadas de ferramenta; cada uma é medida por chamada.
OAuth 2.1
Para clientes que autorizam com OAuth, tudo é descobrível — não há nada para registrar manualmente:
- Metadados de recurso protegido:
https://api.relmcrm.com/.well-known/oauth-protected-resource - Metadados do servidor de autorização:
https://api.relmcrm.com/.well-known/oauth-authorization-server - Registro dinâmico de cliente:
POST https://api.relmcrm.com/oauth/register(RFC 7591) - Código de autorização + PKCE (
S256obrigatório) e tokens de atualização com rotação. Escopo:crm.
Um tools/call não autenticado retorna 401 com um cabeçalho WWW-Authenticate apontando para esses metadados, que é como um cliente sabe que deve oferecer um botão Conectar. As concessões OAuth atuam em dados reais; o modo de teste permanece apenas com chave de API.
Conecte via A2A
A Relm também fala Agent2Agent em https://api.relmcrm.com/a2a (JSON-RPC 2.0). Envie um message/send cuja parte de dados seja {"tool":"relm_...","arguments":{...}}; a Relm o executa de forma síncrona contra as mesmas ferramentas validadas e retorna uma Task terminal. O cartão do agente está em /.well-known/agent-card.json.
OpenAPI
Toda a superfície REST é descrita por uma especificação OpenAPI 3.1 legível por máquina — importe-a no seu gerador de clientes, Postman ou em uma cadeia de ferramentas de agente.
Webhooks
Assine um endpoint https para eventos de CRM. Registre com POST /v1/webhooks (ou relm_create_webhook) — a resposta retorna um secret de assinatura uma única vez. Eventos: contact.created, contact.updated, deal.created, deal.updated, deal.stage_changed (ou ["*"] para todos).
curl https://api.relmcrm.com/v1/webhooks \
-H "Authorization: Bearer relm_live_..." -H "Content-Type: application/json" \
-d '{ "url": "https://your.app/relm", "events": ["deal.stage_changed"] }'
# -> { "id": "wh_...", "secret": "whsec_...", ... } (store the secret; shown once)
Cada entrega é um POST JSON com os cabeçalhos Relm-Event, Relm-Delivery e Relm-Signature: t=<unix>,v1=<hmac>. Verifique recalculando HMAC-SHA256 de "<t>.<raw body>" com seu segredo:
import crypto from "node:crypto";
function verify(secret, rawBody, header) {
const { t, v1 } = Object.fromEntries(header.split(",").map(p => p.split("=")));
const expected = crypto.createHmac("sha256", secret).update(\`${t}.${rawBody}\`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}
Respostas não-2xx ou timeout fazem novas tentativas com backoff (1m, 5m, 30m, 2h, 6h) e dead-letter após 6 tentativas. Inspecione tentativas recentes em GET /v1/webhooks/{id}/deliveries. URLs em modo real devem ser https públicas (hosts privados, loopback e link-local são rejeitados); chaves em modo de teste podem apontar para localhost.
Erros
Todo erro é problem+JSON RFC-9457. type é uma URI estável (https://relmcrm.com/errors/<code>) que resolve para uma página de referência curta, com um title legível, um code de máquina e — quando útil — valid_options e um suggestion.
| Status | code | Significado |
|---|---|---|
| 400 | bad_request | JSON malformado ou parâmetro inválido. |
| 401 | unauthorized | Chave de API ausente ou inválida. |
| 403 | plan_limit / forbidden | Limite do plano atingido (Free permite 2 automações / 1 sequência) ou ação não permitida para esta chave. |
| 404 | not_found | Nenhum registro desse tipo neste workspace/modo. |
| 409 | conflict / idempotency_key_reused | Duplicado (ex.: e-mail — retorna o registro existente) ou chave de idempotência reutilizada. |
| 412 | version_conflict | Registro alterado desde a leitura — busque novamente e reaplique. |
| 422 | unknown_value / unknown_field / validation_failed / invalid_reference | Entrada não processável — veja valid_options e suggestion. |
| 429 | rate_limited / quota_exceeded / spend_cap_reached | Reduza o ritmo, cota mensal esgotada ou limite de gastos atingido. |
Limites de taxa e cotas
As requisições são limitadas por workspace por minuto e contabilizadas contra uma cota mensal. As respostas carregam os cabeçalhos X-RateLimit-* e X-Quota-*.
| Plano | Requisições mensais | Acima do limite |
|---|---|---|
| Free | 1.000 | Para imediatamente (429) |
| Pro — US$ 29/mês | 100.000 | Excedente medido, US$ 0,0001/req |
| Scale — US$ 249/mês | 2.000.000 | Excedente medido, US$ 0,0001/req |
Em planos pagos, você pode definir um limite rígido de gastos; em US$ 0, ele se comporta como Free e para na cota em vez de cobrar excedente. O modo de teste nunca conta.
Pronto para construir?
Gere uma chave gratuita e aponte seu agente para ela.