Permissões
read — leitura; read write — leitura e gestão. Os clientes de API são gerenciados por um usuário conectado. O papel financeiro vê faturas e a assinatura, mas não funcionários nem redes.
Gerencie empresas, membros, acesso à VPN e rotas pela mesma API que o painel da empresa usa.
Primeira versão: 169 métodos do contrato atual — não 169 de 191 requisitos concluídos. O rascunho usa outros caminhos e processos. Matriz completa da primeira versão: SSO/SCIM, transferência de propriedade, implantação de firmware em roteadores, exportação de configurações e dados jurídicos das faturas estão excluídos. notification-channels é apenas um inventário legado: seu contrato e a entrega por email/webhook/in_app estão fora da primeira versão. Sete tipos de alerta estão disponíveis no monitoramento, na auditoria e na API; a entrega pela API de webhooks assinados separada continua no escopo. Por enquanto, roteadores e recursos são apenas inventário; billing-profile só armazena metadados, sem ligação com as faturas.
Caminho base: https://api.meduzavpn.com/api/business/v1. A interface usa a sessão atual do usuário. Para automação, crie um cliente de API no painel da empresa e guarde o segredo no momento da emissão.
curl -X POST https://api.meduzavpn.com/api/business/v1/oauth/token \ -d grant_type=client_credentials \ -d client_id=YOUR_CLIENT_ID \ -d client_secret=YOUR_SECRET curl https://api.meduzavpn.com/api/business/v1/organizations/ORGANIZATION_ID/members \ -H "Authorization: Bearer TOKEN"
Envie o token recebido em Authorization: Bearer TOKEN. O token vale por uma hora e apenas dentro da empresa que emitiu o cliente. O acesso é revogado quando o cliente é desativado ou quando o administrador que o criou perde as permissões.
read — leitura; read write — leitura e gestão. Os clientes de API são gerenciados por um usuário conectado. O papel financeiro vê faturas e a assinatura, mas não funcionários nem redes.
Para alterações, use Idempotency-Key. Ao editar, envie If-Match: "3" com a versão atual do objeto. Em caso de conflito 412, leia o objeto novamente.
POST /organizations a partir de uma sessão de usuário.subscription/quotes: quantidade de VPNs, período e operação purchase, renewal ou upgrade.quote_id e payment_method: stripe_card para subscription/checkout.invoices até aparecer payment_url e pague por esse link.pricing_id de catalog/vpn-locations e um Idempotency-Key obrigatório.O pacote começa em 5 VPNs. Preço base por VPN: $5.99 por mês ou $54.99 por ano. Desconto do pacote: 5–9 VPNs — 5%, 10–99 — 10%, a partir de 100 — 20%. Voltar ao navegador após o pagamento não libera o acesso sem verificar o pagamento.
A renovação mantém a quantidade e o período. Aumentar o pacote calcula um valor adicional pelo prazo restante. Para remover um servidor definitivamente, use POST /organizations/{organization_id}/vpns/{id}/retire com confirm: true e If-Match. A vaga é liberada após a remoção confirmada; o preço da assinatura não muda. A atribuição a um funcionário é enviada como member_id; sem ela, a VPN fica disponível para a empresa conforme as atribuições de acesso.
O campo access de PATCH /organizations/{organization_id}/vpns/{id}, com If-Match, define quem pode usar uma VPN da empresa. company abre-a a todos os membros da empresa cuja função permite conectar; as listas member_ids e group_ids são esvaziadas. restricted limita-a aos funcionários indicados e aos membros dos grupos indicados; listas vazias retiram o acesso de todos. company com listas não vazias é recusado com 422. As respostas GET e /me/vpn-grants incluem sempre data.access, também para VPNs criadas antes de o campo existir. Um pedido sem access, mas com member_ids ou group_ids, passa a VPN para restricted, como antes. A VPN dedicada de um funcionário é sempre restricted. As mudanças de modo ficam registradas na auditoria como vpn_access_changed; quando o acesso é restringido, as credenciais dos dispositivos que o perderam são revogadas.
curl -X PATCH https://api.meduzavpn.com/api/business/v1/organizations/ORGANIZATION_ID/vpns/VPN_ID \
-H "Authorization: Bearer TOKEN" \
-H 'If-Match: "3"' \
-H "Idempotency-Key: vpn-access-1" \
-H "Content-Type: application/json" \
-d '{"access":"company"}'Um conjunto descreve sites ou redes; uma regra escolhe a ação: uma VPN específica, direto ou bloqueio. Use os países e regiões de catalog/traffic-presets. No modo first-match as regras são verificadas de cima para baixo, no máximo 128; para “Restante do tráfego” o bloqueio não está disponível.
Salvar cria um rascunho. Execute a validação e depois a publicação com If-Match. Verifique policy-deployments: estar na fila e estar aplicado com confirmação do dispositivo são estados diferentes. Quem conecta à VPN é o aplicativo cliente.
GET /organizations/{id}/roles retorna os papéis integrados e personalizados, as definições de permissões e o indicador can_manage. O proprietário cria um papel personalizado com base no de administrador, funcionário ou financeiro, mantendo só as permissões necessárias. A atribuição é feita por PATCH members/{id}: role e custom_role_id. Mudanças de permissões também valem para os clientes de API criados por esse usuário.
O papel permite ações no painel. group_ids atribui ao funcionário VPNs e um pacote de roteamento; fazer parte de um grupo não dá permissões administrativas. O papel de proprietário não pode ser copiado para um personalizado. Um papel atribuído a funcionários não pode ser excluído.
Os dispositivos recebem um display_name, um proprietário e dados da VPN. PATCH devices/{id} altera apenas o nome, com verificação de If-Match. POST devices/{id}/revocations solicita a revogação; o status final é confirmado pelo nó. Seus próprios dispositivos estão disponíveis em /me/devices. O campo last_api_ip é o endereço de transporte da API, não o da conexão VPN. O nome e o modelo informados pelo aplicativo não são usados na autorização.
GET /organizations/{id}/employee-analytics mostra as conexões observadas, as mudanças de estado e o histórico por hora de 7 dias. Uma medição ausente não é substituída por zero; o número de sessões não é o tempo de trabalho do funcionário.
GET /organizations/{id}/activity retorna as solicitações de conexão registradas pelo nó: domínio ou IP solicitado, porta, protocolo, horário, decisão, dispositivo e funcionário. Filtros: from, to, member_id, action, search; páginas: cursor e limit. O domínio é enviado pelo cliente na solicitação de conexão, e não obtido decifrando o HTTPS.
A coleta vem desativada por padrão. O proprietário altera activity-settings via PATCH com {"enabled": true} e If-Match. A leitura exige activity.read. Com a coleta ativada, o aplicativo mostra um aviso ao funcionário; a emissão da chave exige uma confirmação atualizada de X-Corporate-Activity-Version após a verificação do dono da chave. Um cliente antigo não recebe chave para esse modo.
O armazenamento é limitado a 7 dias e 100.000 eventos por empresa; o buffer do nó guarda até 24 horas. coverage informa a atualidade, os dispositivos indisponíveis e as perdas do buffer. Não são registrados VPNs pessoais, tráfego direto do dispositivo, bloqueios locais antes de chegar ao nó, caminhos HTTPS, conteúdo das requisições nem avaliação de produtividade. Desativar a coleta não recupera o histórico perdido nem apaga na hora os registros já coletados: vale o prazo de retenção.
A resposta do registro contém analysis: distribuição por categorias, funcionários e horas, principais destinos e o número de active_minutes. Os resumos são calculados sobre todos os eventos guardados do período escolhido, independentemente da página do registro bruto. O filtro category leva aos eventos específicos.
Um minuto ativo é um minuto único de um funcionário em que o nó observou uma requisição. Não é a duração da visita a um site nem do trabalho: o tráfego em segundo plano conta, e as categorias podem se sobrepor no mesmo minuto. O tempo total é calculado separadamente e não é a soma das categorias.
O proprietário define até 64 regras classification_rules nas configurações de registro: domínio e categoria. Elas valem para subdomínios e têm prioridade sobre o catálogo integrado. Destinos desconhecidos ficam em uma categoria separada. As regras atuais classificam todo o período escolhido; a resposta informa a versão da classificação.
São processados os destinos das conexões corporativas, não o conteúdo HTTPS, URLs completas ou tráfego pessoal. A confirmação do aviso é salva uma vez por funcionário na empresa; mudar categorias, grupos ou o modo de coleta não exige confirmar de novo o mesmo aviso. Os indicadores de cobertura incompleta e truncated não devem ser lidos como ausência de atividade.
Crie webhooks com uma URL HTTPS pública na porta 443 e os eventos audit.event, * ou groups.created, members.updated e outras alterações de recursos. O segredo só é exibido na criação ou na rotação.
Meduza-Signature: t=UNIX_SECONDS,v1=HEX_SIGNATURE Meduza-Event-Id: EVENT_ID Meduza-Delivery-Id: DELIVERY_ID HEX_SIGNATURE = HMAC-SHA256(secret, timestamp + "." + RAW_JSON_BODY)
Verifique a assinatura pelos bytes originais do corpo, a idade permitida do timestamp e a repetição do event ID. Durante a rotação, mantenha o segredo anterior para os eventos já na fila. Qualquer 2xx é sucesso; as demais respostas são repetidas com intervalos crescentes, até oito tentativas. O histórico e o reenvio manual estão disponíveis em deliveries. Entregas bem-sucedidas e canceladas são guardadas por até 30 dias, no máximo 2.000 por webhook. A fila e os erros são limitados a 1.000 eventos; no estouro, os mais antigos são descartados e o contador dropped_deliveries informa a perda. Nesse caso, sincronize o estado pela API.
A entrega é pelo menos uma vez. Além das alterações feitas pela API, são enviadas as mudanças confirmadas de faturas (invoices.updated), assinaturas (subscriptions.updated), prontidão de VPN (vpns.updated) e os alertas (alerts.created). Consultar de novo sem mudança de estado não cria um novo evento. Isto não é um fluxo de tráfego de rede. IPs privados, redirecionamentos e chamadas a serviços internos são proibidos.
Carregando o contrato…
Nas listas de inventário, envie limit=1..200 e depois cursor de next_cursor, mantendo os demais parâmetros. Sem limit/cursor, clientes antigos recebem a lista completa: os dados nunca são cortados silenciosamente. Estão disponíveis status, member_id, user_id, vpn_id, search e created_from/created_to (RFC3339, limite inferior incluído, superior excluído). O acesso é verificado antes da filtragem e em cada página. Parâmetros desconhecidos ou repetidos retornam 422. As listas do registro de atividade usam um contrato separado. Parâmetros de cada método.
A auditoria administrativa é guardada por até 90 dias, no máximo os últimos 10.000 eventos por empresa; registros de idempotência expirados são limpos. Essa limpeza não apaga faturas nem assinaturas. As listas de inventário retornam items, total e next_cursor; a continuação aparece com limit/cursor explícito. Sem eles, a resposta completa continua compatível com clientes antigos. O registro activity suporta separadamente um cursor e os filtros documentados. Segredos não são repetidos nas respostas do cache de idempotência. A revogação confirmada da chave vem do servidor VPN; desativar uma associação bloqueia imediatamente novas emissões.
O monitoramento mostra as conexões e a carga reais. O histórico de destinos está disponível em um registro separado, que precisa ser ativado explicitamente. O conteúdo HTTPS e a avaliação de produtividade dos funcionários não fazem parte desses dados. SSO/SCIM e outros métodos do rascunho ampliado não fazem parte deste contrato implementado.
Erros de gestão retornam application/problem+json com status, detail e request_id. Erros de emissão do token OAuth usam o campo error.