Começo rápido
Este guia vai de uma credencial nova até uma página de reuniões. São duas requisições.
Antes de começar
Seção intitulada “Antes de começar”Você precisa de um client ID e um client secret, emitidos pela Salesbud
para a sua empresa. A credencial não é self-service: peça ao seu contato na
Salesbud, que também confirma se a feature API_ACCESS está ligada.
O secret aparece uma única vez, na criação. Guarde num gerenciador de segredos — não dá para lê-lo depois, só rotacionar.
-
Obtenha um token de acesso
Os tokens são emitidos por OAuth 2.0 client credentials. Envie a credencial como campos form-encoded:
Terminal window curl -X POST https://api.salesbud.com.br/oauth/token \-d 'grant_type=client_credentials' \-d "client_id=$SALESBUD_CLIENT_ID" \-d "client_secret=$SALESBUD_CLIENT_SECRET"const response = await fetch("https://api.salesbud.com.br/oauth/token", {method: "POST",headers: { "Content-Type": "application/x-www-form-urlencoded" },body: new URLSearchParams({grant_type: "client_credentials",client_id: process.env.SALESBUD_CLIENT_ID,client_secret: process.env.SALESBUD_CLIENT_SECRET,}),});const { access_token, expires_in } = await response.json();import os, requestsresponse = requests.post("https://api.salesbud.com.br/oauth/token",data={"grant_type": "client_credentials","client_id": os.environ["SALESBUD_CLIENT_ID"],"client_secret": os.environ["SALESBUD_CLIENT_SECRET"],},)access_token = response.json()["access_token"]O endpoint aceita apenas
application/x-www-form-urlencoded. Mandar JSON devolve415 UNSUPPORTED_MEDIA_TYPE.200 OK {"access_token": "eyJhbGciOiJSUzI1NiIs...","token_type": "Bearer","expires_in": 3600,"scope": "meetings.read calls.read"} -
Confirme o que o token pode fazer
GET /v1/contextinforma a empresa, os escopos e o limite de requisições em vigor para aquele token. É o jeito mais rápido de separar problema de configuração de bug de integração.Terminal window curl https://api.salesbud.com.br/v1/context \-H "Authorization: Bearer $SALESBUD_ACCESS_TOKEN" -
Leia uma página de reuniões
Terminal window curl "https://api.salesbud.com.br/v1/meetings?meeting_after=2026-01-01T00:00:00Z&limit=50" \-H "Authorization: Bearer $SALESBUD_ACCESS_TOKEN"Só voltam reuniões da sua empresa que terminaram o processamento. Veja Reuniões e ligações para entender o que é “terminou” e por que os registros de VoIP ficam em
/v1/calls. -
Percorra o resto do histórico
Devolva o
next_cursorsem alterar, mantendo todos os filtros idênticos, e itere pelohas_more— nunca pelo tamanho dedata.let cursor = null;do {const url = new URL("https://api.salesbud.com.br/v1/meetings");url.searchParams.set("meeting_after", "2026-01-01T00:00:00Z");url.searchParams.set("limit", "50");if (cursor) url.searchParams.set("cursor", cursor);const page = await fetch(url, {headers: { Authorization: `Bearer ${accessToken}` },}).then((r) => r.json());for (const meeting of page.data) await handle(meeting);cursor = page.pagination.next_cursor;} while (cursor);Uma página pode voltar curta — até vazia — com
has_moreemtrue. Isso é esperado: o serviço limita quanto varre por requisição. A Paginação explica as garantias.
Renovando o token
Seção intitulada “Renovando o token”Não existe refresh token. Client credentials é um fluxo máquina-a-máquina, sem
usuário para reconsentir, então a
RFC 6749 §4.4.3 diz para
não emitir um. Quando o token expira, chame /oauth/token de novo com a mesma
credencial.
Na prática: guarde o token por um pouco menos que o expires_in e reemita
também em 401 INVALID_ACCESS_TOKEN, não só por relógio — uma credencial pode
ser revogada antes de o prazo acabar.
Se quem lê é um modelo
Seção intitulada “Se quem lê é um modelo”Se o consumidor é um agente e não um serviço, dá para pular o cliente HTTP: o servidor MCP expõe estas mesmas operações como tools para Claude Desktop, Claude Code e Cursor, e cuida da renovação de token e dos retries. A credencial acima continua sendo necessária.
Falhas comuns na primeira chamada
Seção intitulada “Falhas comuns na primeira chamada”| Resposta | O que significa |
|---|---|
415 UNSUPPORTED_MEDIA_TYPE | O pedido de token foi enviado como JSON. Use form encoding. |
401 INVALID_CLIENT | Client ID ou secret errado, ou credencial revogada. |
403 API_ACCESS_DISABLED | A empresa não tem a feature API_ACCESS. Repetir não resolve. |
403 INSUFFICIENT_SCOPE | Falta um escopo que a rota exige — calls.read para ligações, e transcriptions.read somado ao escopo da coleção para transcrição. |
404 RESOURCE_NOT_FOUND | O id não existe, é de outra empresa, ou é da outra coleção. |