For developers
benflow API and MCP
Connect Hermes, OpenClaw, Claude Code or your store's system to the project board. With one key per connection, the AI or system opens cards, comments, follows what changed and organizes the queue.
Remote MCP
For AIs: Hermes, OpenClaw, Claude Code, Cursor and any MCP client over HTTP.
https://benflow.net/mcpREST API
For systems and automations: n8n, Zapier, the store system or the ERP.
https://benflow.net/api/v1Works with
HermesOpenClaw
- Claude Code
- Cursor
- n8n
- Zapier
Get started in 3 steps
- 1
Create the key
In the dashboard, under Connections, on the Outside AIs (MCP and API) row, tap Connect. Choose the AI or system, what the key can do and the cards' sector. Only the project admin creates keys, and each key is shown only once.
- 2
Paste it into the AI or system
The window shows the right snippet for each one, with the key already in it. The same snippets are right below, with the key's place marked.
- 3
Test the connection
Ask the AI to use the quem_sou tool or call GET /api/v1/eu: the response returns the project and the key's permissions.
curl https://benflow.net/api/v1/eu \
-H "Authorization: Bearer $BENFLOW_CHAVE"Connect your AI or your system
Hermes
The Nous Research agent that reads emails and chats on WhatsApp and Telegram.
In ~/.hermes/config.yaml, under mcp_servers:
mcp_servers:
benflow:
url: "https://benflow.net/mcp"
headers:
Authorization: "Bearer bfx_sua_chave"Then, in the chat with Hermes, send /reload-mcp. To check from the terminal: hermes mcp test benflow.
Guidance for the AI (optional). On connect, the MCP server already sends the AI the project, the key's permissions and how to use the tools. To reinforce it, paste this into its prompt:
Você está ligado ao Benflow, o quadro de chamados do projeto, como "Hermes do atendimento" (servidor MCP benflow).
Quando chegar um pedido (e-mail, WhatsApp, Telegram), abra o card com abrir_chamado, mandando referencia_externa (o Message-ID do e-mail ou o id da conversa) e o solicitante: a mesma referência não abre outro card.
Acompanhe com acompanhar, guardando o "agora" da resposta para a próxima vez, e avise quem pediu quando a etapa mudar ou a equipe comentar.
Antes de mudar prioridade ou responsáveis, olhe avaliar_fila e avaliar_carga e explique o motivo em decidir.Authentication
Authorization header, in Bearer format. The key starts with bfx_ followed by 43 characters. In the examples, it is in the BENFLOW_CHAVE environment variable.Authorization: Bearer bfx_sua_chave- One key per AI or system: the card and the comment show its name (for example, Hermes do atendimento), and turning one off does not affect the others.
- The key is shown only when it is created. benflow stores its hash (sha256) and the last 4 characters: if you lose it, create another.
- Turning a key off rejects it on the next call and cannot be undone. The cards and comments it made stay in the project.
- Up to 20 active keys per project. No cookie, no session and no CSRF: just the header.
What each key can do
| Permission | What it allows | On a new key |
|---|---|---|
| Read (every key) | Cards, public comments, history, queue, workload, people and sectors. | Always |
| Open cards | Open cards in To do, with the requester's contact. | On |
| Comment | Public comment (the requester sees it) or internal note. | On |
| Decide | Priority, assignees, due date, sector and the stage between To do, In progress and Closed. | Off |
A key can also have a sector: cards it opens without a sector go into it. The admin can change the permissions and the sector at any time, without replacing the key.
API reference
https://benflow.net/api/v1. Requests and responses in JSON (UTF-8), with field names in Portuguese, the same as in the MCP. Dates and times in ISO 8601 (UTC); due dates in YYYY-MM-DD. Everything applies only to the key's project, and the card number is the same as in the dashboard.Who the key is
GET/api/v1/eu
The project linked to the key and its permissions. It is the first test after pasting the key.
Permission: Read (every key)
curl https://benflow.net/api/v1/eu \
-H "Authorization: Bearer $BENFLOW_CHAVE"{
"chave": "Hermes do atendimento",
"projeto": {
"nome": "Aurora Móveis",
"endereco": "https://benflow.net/o/aurora-moveis"
},
"permissoes": {
"ler": true,
"abrir": true,
"comentar": true,
"decidir": false
}
}List cards
GET/api/v1/chamados
The project's cards, from the most recently changed to the oldest. With no filter, you get the open ones: To do, In progress, In staging and In production.
Permission: Read (every key)
In the URL (query)
etapastring- A stage (
a_fazer | em_andamento | em_homologacao | em_producao | concluido | fechado),abertos(default) ortodos. buscastring- Text in the title, description or original request, or the card number. Up to 200 characters.
responsavelinteger- Person id (see
GET /pessoas). setorinteger- Sector id (see
GET /pessoas). atrasadosboolean- Only cards past their due date.
referencia_externastring- Finds the card for an email or request already sent (up to 300 characters). Returns 0 or 1 card.
minha_iaboolean- Only the cards this key opened.
limiteinteger- From 1 to 100. Default: 30. The response total counts everything that matched the filter.
curl "https://benflow.net/api/v1/chamados?etapa=abertos&busca=cupom&limite=10" \
-H "Authorization: Bearer $BENFLOW_CHAVE"{
"total": 2,
"cards": [
{
"numero": 128,
"titulo": "Cupom FRETEGRATIS não aplica no carrinho",
"etapa": "a_fazer",
"etapa_nome": "A fazer",
"prioridade": "alta",
"tipo": "bug",
"setor": "Loja virtual",
"prazo": null,
"atrasado": false,
"responsaveis": [],
"origem": "IA de fora: Hermes do atendimento",
"card_principal": null,
"ia": null,
"aberto_em": "2026-10-19T12:41:07.512Z",
"atualizado_em": "2026-10-19T12:41:07.512Z",
"link": "https://benflow.net/o/aurora-moveis/c/128"
},
{
"numero": 131,
"titulo": "Parcelamento em 12x no checkout",
"etapa": "em_andamento",
"etapa_nome": "Em andamento",
"prioridade": "normal",
"tipo": "funcionalidade",
"setor": "Loja virtual",
"prazo": "2026-10-24",
"atrasado": false,
"responsaveis": [
{
"id": 9,
"nome": "Diego"
}
],
"origem": "Painel",
"card_principal": null,
"ia": {
"etapa": "desenvolvimento",
"percentual": 45,
"situacao": "rodando",
"agente": "Bento"
},
"aberto_em": "2026-10-17T18:02:44.120Z",
"atualizado_em": "2026-10-19T11:58:10.004Z",
"link": "https://benflow.net/o/aurora-moveis/c/131"
}
]
}Open a card
POST/api/v1/chamados
Opens the card in To do, with the key name as the source and the requester's contact. With the same referencia_externa, it returns the existing card instead of opening another one.
Permission: Open cards
201withcriado: truewhen the card is created;200withcriado: falseand the earlier card when the reference already existed.
In the body (JSON)
titulostringrequired- 3 to 200 characters.
descricaostring- The request in a few lines, up to 5,000 characters. A password or token pasted in the text is masked.
prioridadestringurgente | alta | normal | baixatipostringbug | melhoria | funcionalidadeprazostring- Date in YYYY-MM-DD format.
setorinteger- Sector id. Without it, the card goes into the key's sector.
responsaveisinteger[]- People ids, up to 10.
referencia_externastring- The email Message-ID, or the id of the conversation or request in the source system, up to 300 characters.
solicitanteobject- Who asked:
nome(up to 120),email(up to 200) andtelefone(up to 40), all optional.
curl -X POST https://benflow.net/api/v1/chamados \
-H "Authorization: Bearer $BENFLOW_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"titulo": "Cupom FRETEGRATIS não aplica no carrinho",
"descricao": "A cliente tentou usar o cupom pelo celular e o carrinho mostra Cupom inválido.",
"prioridade": "alta",
"tipo": "bug",
"referencia_externa": "<CAH7x2k9QmZ@mail.gmail.com>",
"solicitante": {
"nome": "Carla Souza",
"email": "carla@exemplo.com"
}
}'{
"criado": true,
"card": {
"numero": 128,
"titulo": "Cupom FRETEGRATIS não aplica no carrinho",
"etapa": "a_fazer",
"etapa_nome": "A fazer",
"prioridade": "alta",
"tipo": "bug",
"setor": "Loja virtual",
"prazo": null,
"atrasado": false,
"responsaveis": [],
"origem": "IA de fora: Hermes do atendimento",
"card_principal": null,
"ia": null,
"aberto_em": "2026-10-19T12:41:07.512Z",
"atualizado_em": "2026-10-19T12:41:07.512Z",
"link": "https://benflow.net/o/aurora-moveis/c/128"
}
}View a card
GET/api/v1/chamados/{numero}
Everything about a card: description, original request, requester, reference, comments and history (the last 30 changes).
Permission: Read (every key)
- The key reads public comments and the internal notes it left itself. The team's internal notes are left out.
- An archived or trashed card returns 404.
curl https://benflow.net/api/v1/chamados/128 \
-H "Authorization: Bearer $BENFLOW_CHAVE"{
"numero": 128,
"titulo": "Cupom FRETEGRATIS não aplica no carrinho",
"etapa": "em_andamento",
"etapa_nome": "Em andamento",
"prioridade": "alta",
"tipo": "bug",
"setor": "Loja virtual",
"prazo": null,
"atrasado": false,
"responsaveis": [
{
"id": 14,
"nome": "Julia"
}
],
"origem": "IA de fora: Hermes do atendimento",
"card_principal": null,
"ia": null,
"aberto_em": "2026-10-19T12:41:07.512Z",
"atualizado_em": "2026-10-19T14:13:05.877Z",
"link": "https://benflow.net/o/aurora-moveis/c/128",
"descricao": "A cliente tentou usar o cupom pelo celular e o carrinho mostra Cupom inválido.",
"pedido_original": null,
"solicitante": {
"nome": "Carla Souza",
"email": "carla@exemplo.com",
"telefone": null
},
"referencia_externa": "<CAH7x2k9QmZ@mail.gmail.com>",
"comentarios": [
{
"id": 911,
"autor": "Julia",
"texto": "Achei o problema no cálculo do frete, corrijo hoje.",
"interno": false,
"em": "2026-10-19T14:13:05.877Z"
}
],
"historico": [
{
"em": "2026-10-19T12:41:07.512Z",
"o_que": "Card aberto",
"quem": "Hermes do atendimento"
},
{
"em": "2026-10-19T14:12:31.090Z",
"o_que": "Responsáveis: entrou Julia",
"quem": "Diego"
},
{
"em": "2026-10-19T14:12:40.201Z",
"o_que": "Etapa: de A fazer para Em andamento",
"quem": "Julia"
}
]
}Comment
POST/api/v1/chamados/{numero}/comentarios
Replies on the card. Public (the default): the requester sees it, and on a card that came from Telegram the reply goes there. With interno, it becomes a team-only note.
Permission: Comment
In the body (JSON)
textostringrequired- 1 to 5,000 characters.
internoboolean- true for an internal note. Default: false.
curl -X POST https://benflow.net/api/v1/chamados/128/comentarios \
-H "Authorization: Bearer $BENFLOW_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"texto": "Oi, Carla! A equipe já está corrigindo o cupom. Aviso aqui assim que voltar a funcionar."
}'{
"id": 912,
"interno": false,
"card": 128
}Decide
PATCH/api/v1/chamados/{numero}
Changes priority, assignees, due date, sector and the entry stage. Send only what changes; the response returns the card as it ended up.
Permission: Decide
- The stage only changes on a card in To do or In progress with no team AI working on it (otherwise, 409). Staging, production and Done follow benflow's pipeline, not the key.
- Moving a card with a plan awaiting approval to In progress returns 403.
In the body (JSON)
prioridadestringurgente | alta | normal | baixaresponsaveisinteger[]- Replaces the whole list, up to 10 ids.
prazostring | null- YYYY-MM-DD; null removes the due date.
setorinteger | null- Sector id; null removes the sector.
etapastringa_fazer | em_andamento | fechadomotivostring- Why it decided, up to 2,000 characters. It goes into the history and, if the key can comment, becomes an internal note on the card.
curl -X PATCH https://benflow.net/api/v1/chamados/128 \
-H "Authorization: Bearer $BENFLOW_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"prioridade": "urgente",
"responsaveis": [
14
],
"prazo": "2026-10-20",
"motivo": "Três clientes relataram o mesmo erro hoje e a Julia é quem cuida do carrinho, com a menor carga da equipe."
}'{
"numero": 128,
"titulo": "Cupom FRETEGRATIS não aplica no carrinho",
"etapa": "a_fazer",
"etapa_nome": "A fazer",
"prioridade": "urgente",
"tipo": "bug",
"setor": "Loja virtual",
"prazo": "2026-10-20",
"atrasado": false,
"responsaveis": [
{
"id": 14,
"nome": "Julia"
}
],
"origem": "IA de fora: Hermes do atendimento",
"card_principal": null,
"ia": null,
"aberto_em": "2026-10-19T12:41:07.512Z",
"atualizado_em": "2026-10-19T12:55:19.330Z",
"link": "https://benflow.net/o/aurora-moveis/c/128"
}Follow what changed
GET/api/v1/acompanhar
The cards that changed since a given time: stage, assignees and fields, the team's public comments and the team AI's progress.
Permission: Read (every key)
- Store the response's
agoraand send it asdesdenext time. Up to 50 cards per response.
In the URL (query)
desdestring- Date and time in ISO 8601, for example 2026-10-19T14:00:00Z. Default: the last 24 hours; at most 7 days back.
numerointeger- A single card.
minha_iaboolean- Only the cards this key opened.
curl "https://benflow.net/api/v1/acompanhar?desde=2026-10-19T14%3A00%3A00Z" \
-H "Authorization: Bearer $BENFLOW_CHAVE"{
"agora": "2026-10-19T15:00:02.118Z",
"desde": "2026-10-19T14:00:00.000Z",
"cards": [
{
"numero": 128,
"titulo": "Cupom FRETEGRATIS não aplica no carrinho",
"etapa_nome": "Em andamento",
"link": "https://benflow.net/o/aurora-moveis/c/128",
"mudancas": [
"Responsáveis: entrou Julia, por Diego (2026-10-19T14:12:31.090Z)",
"Etapa: de A fazer para Em andamento, por Julia (2026-10-19T14:12:40.201Z)",
"Comentário de Julia (2026-10-19T14:13:05.877Z): Achei o problema no cálculo do frete, corrijo hoje."
],
"ia": null
}
]
}Assess the queue
GET/api/v1/fila
Open cards by stage and priority, bugs, unassigned, overdue, due in 3 days, what came in and went out this week, the oldest in To do and the team AI's queue. The observations are only counted facts.
Permission: Read (every key)
curl https://benflow.net/api/v1/fila \
-H "Authorization: Bearer $BENFLOW_CHAVE"{
"abertos": 23,
"por_etapa": {
"A fazer": 9,
"Em andamento": 8,
"Em homologação": 4,
"Em produção": 2
},
"por_prioridade": {
"urgente": 1,
"alta": 6,
"normal": 13,
"baixa": 3
},
"bugs_abertos": 7,
"sem_responsavel": 3,
"atrasados": 2,
"vencem_em_3_dias": 4,
"entraram_7_dias": 15,
"concluidos_7_dias": 11,
"mais_antigos_a_fazer": [
{
"numero": 97,
"titulo": "Filtro por cor some na busca do celular",
"prioridade": "normal",
"dias_esperando": 9,
"responsaveis": []
}
],
"ia_da_equipe": {
"rodando": 2,
"na_fila": 3,
"paradas": 0
},
"observacoes": [
"1 card(s) urgente(s) ou de alta prioridade sem responsável.",
"2 card(s) com o prazo vencido.",
"Na semana entraram 15 card(s) e 11 foram concluídos: a fila cresceu.",
"O card #97 espera em A fazer há 9 dias."
]
}Assess the workload
GET/api/v1/carga
Each person's workload (open, in progress, overdue, urgent and high, done this week), from the busiest to the least, and what each team Claude is doing now and has queued.
Permission: Read (every key)
curl https://benflow.net/api/v1/carga \
-H "Authorization: Bearer $BENFLOW_CHAVE"{
"pessoas": [
{
"id": 14,
"nome": "Julia",
"papel": "membro",
"abertos": 6,
"em_andamento": 4,
"atrasados": 1,
"urgentes_e_altas": 2,
"concluidos_7_dias": 5
},
{
"id": 9,
"nome": "Diego",
"papel": "admin",
"abertos": 4,
"em_andamento": 2,
"atrasados": 0,
"urgentes_e_altas": 1,
"concluidos_7_dias": 3
}
],
"sem_responsavel": 3,
"ia_da_equipe": [
{
"agente": "Bento",
"dono": "Diego",
"online": true,
"trabalhando_em": [
{
"numero": 131,
"titulo": "Parcelamento em 12x no checkout",
"etapa": "desenvolvimento",
"percentual": 45
}
],
"na_fila": 2
}
]
}People and sectors
GET/api/v1/pessoas
Who can be an assignee and the project's sectors, with the ids to open and decide.
Permission: Read (every key)
curl https://benflow.net/api/v1/pessoas \
-H "Authorization: Bearer $BENFLOW_CHAVE"{
"pessoas": [
{
"id": 9,
"nome": "Diego",
"papel": "admin"
},
{
"id": 14,
"nome": "Julia",
"papel": "membro"
},
{
"id": 21,
"nome": "Rafael",
"papel": "membro"
}
],
"setores": [
{
"id": 3,
"nome": "Atendimento"
},
{
"id": 4,
"nome": "Loja virtual"
}
]
}The card in the response
Card fields
numerointeger- The card number in the project, the same as in the dashboard (#128).
titulostring- The title.
etapastringa_fazer | em_andamento | em_homologacao | em_producao | concluido | fechadoetapa_nomestring- The stage name as shown on the board (A fazer, Em andamento...).
prioridadestringurgente | alta | normal | baixatipostring | nullbug | melhoria | funcionalidadesetorstring | null- The sector name.
prazostring | null- YYYY-MM-DD.
atrasadoboolean- Past due date on a card still open.
responsaveisobject[]{ id, nome }origemstring- Where the card came from, in Portuguese: IA de fora (with the key name), Telegram, E-mail, Widget do site, Link externo, Reunião, Terminal, the monitoring tool or Painel.
card_principalinteger | null- The parent card number, when this one is a subcard.
iaobject | null- The team AI's work on the card:
{ etapa, percentual, situacao, agente }. aberto_emstring- Date and time in ISO 8601 (UTC).
atualizado_emstring- The last change, in ISO 8601 (UTC).
linkstring- The card's address in the dashboard.
Only when viewing a card
descricaostring- The description, with passwords and tokens masked.
pedido_originalstring | null- The original request text, when the card keeps one.
solicitanteobject | null{ nome, email, telefone }referencia_externastring | null- The reference sent when opening.
comentariosobject[]{ id, autor, texto, interno, em }historicoobject[]{ em, o_que, quem }
{
"numero": 128,
"titulo": "Cupom FRETEGRATIS não aplica no carrinho",
"etapa": "a_fazer",
"etapa_nome": "A fazer",
"prioridade": "alta",
"tipo": "bug",
"setor": "Loja virtual",
"prazo": null,
"atrasado": false,
"responsaveis": [],
"origem": "IA de fora: Hermes do atendimento",
"card_principal": null,
"ia": null,
"aberto_em": "2026-10-19T12:41:07.512Z",
"atualizado_em": "2026-10-19T12:41:07.512Z",
"link": "https://benflow.net/o/aurora-moveis/c/128"
}MCP tools
https://benflow.net/mcp, on the Streamable HTTP transport and stateless: each request is a POST with the key in the header, and the response comes back as JSON, with no SSE stream. The server name is benflow, and the tools use the same fields as the API.| Tool | What it does | In the API | Permission |
|---|---|---|---|
quem_sou | The project and the key's permissions. | GET/eu | Read (every key) |
listar_chamados | Lists and filters cards. | GET/chamados | Read (every key) |
ver_chamado | Everything about a card. | GET/chamados/{numero} | Read (every key) |
abrir_chamado | Opens the card, without repeating the reference. | POST/chamados | Open cards |
comentar | Public comment or internal note. | POST/chamados/{numero}/comentarios | Comment |
acompanhar | What changed since last time. | GET/acompanhar | Read (every key) |
avaliar_fila | The project's queue. | GET/fila | Read (every key) |
avaliar_carga | The workload of each person and each Claude. | GET/carga | Read (every key) |
listar_pessoas | People and sectors, with ids. | GET/pessoas | Read (every key) |
decidir | Priority, assignees, due date, sector and entry stage. | PATCH/chamados/{numero} | Decide |
- On connect, the server sends the AI usage instructions: the project, the key's permissions and how to open without duplicates, follow and decide.
- In the MCP
decidir,motivois required (at least 3 characters); in the API, it is optional. - A rejected operation (missing permission, card not found, card limit) comes back as a result with
isErrorand the message, without breaking the AI's conversation. - A wrong key or an exceeded call limit comes back before the tool, as a JSON-RPC error with the HTTP status:
-32001, or-32029on 429. GETandDELETEon /mcp return 405: being stateless, there is no stream to open and no session to close.
No duplicate cards
- Send
referencia_externawith every card you open: the email Message-ID, the WhatsApp or Telegram conversation id, the order number in the system. - The same reference in the same project returns the existing card, with
criado: falseand status 200, and does not count toward the hourly card limit. - Two calls with the same reference at the same time: the database holds the second one, and it gets the first one's card.
- So the AI can reread the inbox or retry the call after a network error without opening two cards for the same request.
- To find a reference's card without opening anything, use
GET /chamados?referencia_externa=....
Follow the changes
- benflow does not call your AI yet when a card changes: the AI asks.
- Call
GET /acompanhar(or theacompanhartool) from time to time, sending the previous response'sagoraasdesde. - Only the cards that changed come back, with each change on one line and the team's public comments. The key's own comments are left out.
- Without desde, you get the last 24 hours; the furthest back is 7 days, and each response returns up to 50 cards.
- One check every few minutes fits easily within the limit of 600 calls every 10 minutes.
Errors
{ "error": "..." }, with the message in the language of the Accept-Language header (Portuguese, English or Spanish).| Status | When |
|---|---|
| 400 | A field out of format or limit, or nothing to change in decidir. |
| 401 | Invalid or turned-off key, or no header. |
| 402 | The project's free trial or subscription has ended. |
| 403 | The key lacks the permission, the project is deactivated or the card has a plan awaiting approval. |
| 404 | Card not found, archived or in the trash. |
| 409 | Stage out of the key's reach: the card is already past In progress or the team AI is working on it. |
| 429 | Call, new card or wrong key limit. The message says how long to wait. |
{
"error": "Esta chave não tem a permissão de decidir. Ligue em Conexões, IAs de fora."
}Limits
| What | Limit |
|---|---|
| Calls per key | 600 every 10 minutes, MCP and API combined |
| New cards per key | 60 per hour (a repeated reference does not count) |
| Wrong keys | 30 per IP address every 10 minutes |
| Active keys | 20 per project |
| List cards | 30 per response (up to 100 with limite) |
| Follow | Up to 7 days back and 50 cards per response |
| Texts | Title 3 to 200, description 5,000, comment 5,000 and reason 2,000 characters |
Security
The key is a secret
Whoever has the key acts in the project with its permissions. Keep it in an environment variable or a secrets vault, never in code. If it leaks, turn it off and create another.
Card text is data, not instructions
Titles, descriptions and comments come from clients and other people. Your AI should treat that text as data, never as orders (prompt injection).
Pasted secrets are masked
A password or token pasted in a description or comment is masked before it reaches the AI and before it is stored on the card.
The AI only sees what is its own
The key reads public comments and the internal notes it left itself. The team's internal notes are left out.
Ready to connect your AI?
Create the key in Connections and make your first card through the API in a few minutes.










