Permissões
Cada chave carrega uma lista de permissões, escolhida na criação. O formato é modulo:acao, sempre em inglês, e as ações são read, create, update e delete.
clients:readclients:createservice_orders:updateGET /public/v1/me devolve em key.permissions exatamente o que a chave tem.
Módulos e ações
Seção intitulada “Módulos e ações”| Módulo | Permissões |
|---|---|
Clientes clients | clients:read clients:create clients:update clients:delete |
Leads leads | leads:read leads:create |
Ordens de serviço service_orders | service_orders:read service_orders:create service_orders:update service_orders:delete |
Orçamentos quotes | quotes:read quotes:create quotes:update quotes:delete |
Vendas sales | sales:read sales:create sales:update |
Financeiro finance | finance:read finance:create finance:update finance:delete |
Agenda appointments | appointments:read appointments:create appointments:update appointments:delete |
Produtos e estoque products | products:read products:create products:update products:delete |
Serviços services | services:read services:create services:update services:delete |
Tarefas tasks | tasks:read tasks:create tasks:update tasks:delete |
Equipe team | team:read |
Webhooks webhooks | webhooks:read webhooks:create webhooks:update webhooks:delete |
Eventos events | events:read |
Nem todo módulo aceita as quatro ações. sales não tem delete porque o painel não exclui venda, e team e events são só de leitura.
Esta tabela sai do contrato da API, no mesmo arquivo que o painel e o servidor leem. Módulo novo aparece aqui sozinho. Ter a permissão marcada na chave não quer dizer que a rota daquele módulo já exista: a Referência é a lista do que responde hoje.
GET /public/v1/me responde a qualquer chave válida, sem exigir permissão específica.
Chaves criadas na primeira versão da API continuam valendo: leads:write vale como leads:create, e leads:read e team:read seguem iguais.
Permissão efetiva é uma interseção
Seção intitulada “Permissão efetiva é uma interseção”O que a chave pode de fato é o encontro de quatro coisas:
permissão da chave ∩ papel do membro ∩ permissões do membro ∩ plano da empresa
Basta uma delas dizer não para a chamada ser recusada. Por isso uma chave com clients:create ainda pode receber 403.
1. Permissão da chave
Seção intitulada “1. Permissão da chave”A chave precisa ter a permissão que a rota exige. Sem ela, a resposta é 403 com o código permission_missing. Rota pública sem permissão declarada também é negada: o padrão é negar, nunca liberar.
A captação de lead toca dois módulos, e a chave precisa das permissões dos dois:
POST /public/v1/leadsexigeleads:create. Quando a chamada abre a tarefa de contato, seja a padrão (corpo semtask), seja a que você descreve emtask, exige tambémtasks:create. Sem ela, a resposta é 403permission_missinge nada é gravado, nem o lead. Comtask: nullnenhuma tarefa é aberta, eleads:createbasta.- Se o telefone ou o e-mail já estava cadastrado, a resposta traz
deduplicated: true. Nesse caso, uma chave semleads:readnemclients:readrecebe só oobjecte oid, tanto doleadquanto datask, e não o nome, o e-mail, a situação e a origem de quem já estava na base. A tarefa vem reduzida porque o título padrão dela é “Entrar em contato com” seguido do nome do cadastro existente; no painel, o título continua completo. Uma chave que só cadastra não lê clientes.
A ordem de serviço também escreve em outros módulos em duas opções, e a regra é a mesma:
POST /public/v1/service_orderscomcreate_appointment: trueescheduled_startcria um compromisso na agenda, e exige tambémappointments:create. Semscheduled_startnenhum compromisso é criado, como no painel, e a permissão não é cobrada.POST /public/v1/service_orders/{id}/completecomlink_financial_transaction: truelança a receita no financeiro, e exige tambémfinance:create.
Sem a segunda permissão, a resposta é 403 permission_missing e nada é gravado: nem a OS, nem a conclusão. Sem as duas opções, a permissão de ordens de serviço basta.
As conversões de orçamento seguem a mesma regra, e cada permissão extra só é cobrada quando o efeito acontece de verdade:
POST /public/v1/quotes/{id}/convert_to_salesempre cria uma venda, e exige tambémsales:create.- Quando a requisição PEDE o lançamento no financeiro (
track_in_finance: trueou uma conta empayment_plan.account_id), exige tambémfinance:create. Quando o campo não vem e a venda vai para o financeiro porque a configuração da empresa lança as vendas (o padrão), a permissão NÃO é cobrada: esse lançamento é uma automação da empresa, como o contrato da aprovação (veja abaixo), e a tela do painel também deixa quem não vê o financeiro converter assim. - Mandar
track_in_financeou a conta exige a permissão de financeiro no membro: a janela de conversão do painel esconde os dois de quem não vê o financeiro (403member_permission_denied). decrement_stock: truebaixa o estoque dos produtos do catálogo e NÃO exigeproducts:update: baixar estoque é parte de vender, e os caminhos de venda do painel (inclusive o portal do vendedor) baixam sem a permissão de produtos.products:*só é exigido nas rotas do próprio catálogo (produtos, variações, categorias e estoque).POST /public/v1/service_orders/from_quoteexigeservice_orders:createequotes:readna chave, e a permissão de orçamentos no membro (a OS nasce com o conteúdo do orçamento, e converter o que a chave não pode ler seria fazer mais do que a pessoa faria) e, comcreate_appointment: trueescheduled_start, tambémappointments:create, como a criação de OS.
Sem a permissão extra, a resposta é 403 permission_missing e nada é gravado: nem a venda, nem a OS.
As vendas seguem a mesma regra. A chave precisa da permissão de vendas da rota e, quando o efeito acontece de verdade, da do módulo em que ele escreve:
- Criar venda que PEDE o lançamento no financeiro (
track_in_finance: trueou uma conta empayment_plan.account_id) exigefinance:create. Sem o campo, a venda vai para o financeiro pela configuração da empresa (o padrão), e isso NÃO cobrafinance:create: é automação da empresa, a mesma que a tela aplica a quem não vê o financeiro. A baixa de estoque (decrement_stock,truepor padrão) não exigeproducts:update: é parte de vender, como no painel. - Receber, estornar recebimento, reagendar parcelas, criar versão nova e cancelar a venda são ações de VENDAS, como na aba Recebimentos do painel, que o membro sem o financeiro opera: pedem só
sales:updatena chave e a permissão de vendas no membro, mesmo numa venda que está no financeiro ou que baixou estoque. O que essas ações mudam no financeiro (lançamentos) e no estoque (devolução) é automação da venda. - A permissão de financeiro só entra quando a requisição ESCOLHE algo do financeiro: uma conta (
account_idno recebimento oupayment_plan.account_idna venda e na versão) exigefinance:readefinance:create(na versão,finance:update) na chave, e a permissão de financeiro no membro. Decidirtrack_in_financena criação exige a permissão de financeiro no membro. A tela do painel esconde os dois de quem não vê o financeiro.
Sem a permissão extra, a resposta é 403 e nada é gravado.
O financeiro usa finance:read, finance:create, finance:update e finance:delete, e a permissão de financeiro no membro, nas três áreas (lançamentos, contas e categorias):
- Ler é
finance:read. Criar lançamento, transferência, recorrência, parcelamento, conta e categoria éfinance:create. Editar emark_paidsãofinance:update. Excluir éfinance:delete. - Os papéis são os do painel: categorias só o dono e os administradores criam, editam e excluem, e conta só eles excluem. Outro papel recebe 403
member_permission_denied. mark_paidnuma parcela de venda registra o recebimento da VENDA, e pede só a permissão de financeiro: o recebimento é consequência da ação, como no painel, e não cobrasales:*. É o mesmo princípio das vendas no sentido contrário: receber pela venda não cobrafinance:*.- Toda leitura do financeiro agenda a sincronização das vendas com o financeiro, como a tela. É automação da empresa e não cobra
sales:read.
Aprovar um orçamento pode criar um contrato, quando a empresa ligou o contrato automático da mensalidade. Essa criação é uma automação da empresa, que roda igual quando o cliente aprova pelo portal, e não pede permissão extra na chave: quotes:update basta para aprovar.
2. Papel do membro
Seção intitulada “2. Papel do membro”A chave age como um membro da empresa, escolhido na criação. O papel dele vale na API igual ao que vale no painel:
- OWNER e ADMIN passam por todas as áreas.
- MEMBER depende das permissões marcadas no perfil dele, tanto para ler quanto para escrever.
- VIEWER nunca escreve. Lê as áreas que tiver marcadas.
Uma chave nunca representa um membro de papel acima de quem a criou. Um ADMIN não emite chave que age como OWNER.
3. Permissões do membro
Seção intitulada “3. Permissões do membro”Dentro do papel MEMBER e VIEWER, o painel marca área por área o que a pessoa acessa. A API respeita a mesma marcação. Se a pessoa não vê o financeiro na tela, a chave que a representa não lê o financeiro pela API. A recusa é 403 com o código member_permission_denied.
A mesma marcação recorta listas que juntam áreas diferentes. GET /public/v1/team devolve a equipe que o painel mostraria ao membro: técnicos só com a permissão de técnicos, vendedores só com a de vendas, e membros do painel e auxiliares com a de tarefas. OWNER e ADMIN veem todos. Quem não tem uma dessas permissões recebe a lista sem aquelas pessoas, e não um erro.
Isso vale no instante. Mudou a marcação no painel, a chamada seguinte já sente, sem esperar nada expirar. E se o membro for suspenso ou removido da empresa, a chave para de autenticar: a resposta deixa de ser 403 e vira o 401 de Autenticação.
4. Plano da empresa
Seção intitulada “4. Plano da empresa”O plano precisa incluir a API, e as cotas de cadastro do plano valem igual pela API. As recusas são 403 com plan_feature_unavailable (o plano não inclui o recurso) e plan_limit_reached (a cota acabou). Assinatura fora de dia responde 403 com subscription_inactive.
Como descobrir qual das quatro barrou
Seção intitulada “Como descobrir qual das quatro barrou”O code do erro diz qual camada recusou:
permission_missing: recusou a chave. Crie uma chave com a permissão que falta, ou aponte a integração para uma chave que já a tenha.member_permission_denied: recusou o papel ou as permissões do membro. Ajuste o acesso desse membro no painel, ou emita a chave para outro membro.plan_feature_unavailable: recusou o plano. O plano da empresa não inclui esse recurso.plan_limit_reached: recusou a cota do plano. A cota do período acabou.subscription_inactive: recusou a assinatura. Regularize a assinatura no painel.access_denied: 403 sem causa mapeada. A API recusou e nenhum dos códigos acima se aplica. Se você receber este, mande orequest_idpara o suporte.
401, 403 e 404
Seção intitulada “401, 403 e 404”As três respostas querem dizer coisas diferentes, e a diferença importa na hora de depurar.
401, authentication_error. A API não sabe quem está chamando. Toda recusa de autenticação devolve a mesma resposta, com o código api_key_invalid. Veja Autenticação.
403, permission_error. A API sabe quem está chamando e não deixa. É uma das quatro camadas acima.
404, invalid_request_error. O recurso não existe, ou existe e é de outra empresa. Id de outra empresa responde 404, nunca 403: responder 403 confirmaria que aquele id existe em algum lugar. Caminho que não é rota da API também responde 404, com o código route_not_found.
Vale a leitura direta: 401 é problema de chave, 403 é problema de direito, 404 é problema de endereço ou de id.
Escolhendo as permissões de uma chave
Seção intitulada “Escolhendo as permissões de uma chave”- Marque só o que a integração usa. Uma integração que lê clientes não precisa de
clients:delete. - Uma chave por integração. Revogar uma não derruba as outras, e o registro de uso mostra quem chamou o quê.
- Emita a chave para o membro certo. Se a integração só precisa ler, emita para um membro que só lê: aí nem um erro de marcação na chave abre escrita.