Ir para o conteúdo

Documentação

A API REST

Tudo o que se faz no painel, o seu próprio código também o pode fazer. Uma chave, um URL de base e exatamente as permissões que já tem. Nada aqui é um atalho para contornar o painel.

URL de base e autenticação

Todos os caminhos desta página ficam por trás do URL de base indicado abaixo, e cada pedido leva a sua chave num cabeçalho Authorization. Não há outra forma de entrar: sem cookie de sessão, sem basic auth, sem chave na query string.

shell
curl -s https://app.provibr.com/api/v1/me \
  -H "Authorization: Bearer pvk_..."
Não há CORS, e isso é deliberado e não uma falha. Uma chave bearer em JavaScript no navegador é uma chave exposta: qualquer visitante a consegue ler. Chame esta API a partir do seu próprio backend, nunca a partir de uma página no navegador de outra pessoa.
Os comandos e a saída do terminal estão em inglês em todo o lado, no painel e nestas páginas. Um só texto, uma só verdade: o que aqui se lê é literalmente o que o seu host vai devolver.

Chaves

Uma chave cria-se na sua página de perfil, em Chaves de API. É sua e de uma só conta: não é partilhada com os colegas e deixa de funcionar no momento em que sair dessa conta.

Uma chave é mostrada uma única vez, ao ser criada. Guardamos apenas um hash dela, por isso uma chave perdida não pode ser recuperada: crie uma nova e revogue a antiga.
  • Salvo indicação em contrário, uma chave expira ao fim de 90 dias. Pode escolher um prazo mais curto, ou nenhum; uma chave sem data de fim é uma chave que ninguém revoga em seu lugar.
  • Fazer a rotação significa criar uma chave nova e revogar a antiga, com um intervalo pelo meio em que ambas funcionam. Não há substituição direta da chave existente, porque isso deixaria sem chave a funcionar se algo corresse mal a meio.
  • É possível vincular uma chave a uma lista de endereços. Um pedido vindo de qualquer outro sítio é recusado antes de se ler seja o que for, e essa recusa não revela nada sobre a chave a quem o fez.
  • Cada membro tem no máximo 25 chaves. Uma chave revogada mantém a sua linha, pelo que se continua a ver mais tarde o que lhe era permitido fazer enquanto esteve em uso.
Os proprietários e os administradores veem todas as chaves da conta em Definições, com o membro a que cada uma pertence. Essa página é a revisão de acessos: é o único sítio onde se vê num relance quem consegue chegar a esta conta a partir de fora do painel.

O que uma chave pode fazer

Uma chave transporta âmbitos: leitura ou escrita, por cada parte do painel. O que pode realmente fazer é a interseção desses âmbitos com as permissões do membro a quem pertence.

Um âmbito nunca concede mais do que o membro já tem. Assinalar o acesso de escrita numa chave de alguém que não pode criar servidores não concede nada a essa chave; só pode estreitar aquilo que a chave está autorizada a fazer.

As permissões são lidas em direto, em cada pedido. Se algo for retirado a um membro, todas as chaves desse membro ficam imediatamente mais estreitas, sem que ninguém tenha de revogar seja o que for. É também por isso que uma chave sobrevive a uma mudança de função em vez de ser invalidada por ela.

Tudo o que um agente faz leva tempo

A sua infraestrutura só é alcançável através do agente que está dentro da sua própria rede, e esse agente liga-se para fora. Por isso, um endpoint que altera uma máquina não pode responder com o resultado: responde que a ordem foi aceite e entrega algo que se pode acompanhar.

  1. Envia-se o pedido e recebe-se uma resposta de aceitação, com um cabeçalho Location que aponta para o comando que foi criado. Esse cabeçalho é absoluto a partir do anfitrião: deve ser resolvido em relação à origem e não ao URL base acima, caso contrário pede-se um caminho que não existe.
  2. Esse mesmo comando vem também no corpo, mas embrulhado num campo command. A leitura abaixo devolve-o nu, sem esse embrulho: basta desembrulhá-lo uma vez e a primeira leitura costuma ser desnecessária.
  3. Lê-se o comando até o seu estado ser final: concluído, com falha, expirado ou cancelado. Só pendente não é final, e um estado desconhecido conta igualmente como final, de modo que um valor acrescentado mais tarde nunca deixa a leitura em aberto para sempre.
  4. Um comando que falhou traz o código de erro do próprio agente, com os seus argumentos: exatamente os mesmos que o painel apresenta.
shell
# 1. the order - answers 202 with a Location header
curl -s -D - -X POST https://app.provibr.com/api/v1/servers/<serverId>/actions/start \
  -H "Authorization: Bearer pvk_..."

# 2. the outcome - repeat until the status is final
curl -s https://app.provibr.com/api/v1/commands/<commandId> \
  -H "Authorization: Bearer pvk_..."
A leitura nunca funciona assim. Um inventário, um endereço ou uma fatura respondem de imediato, porque essa resposta vem da nossa base de dados e não do seu host.

O que se recebe

Cada ponto final diz com o que responde: 200 numa leitura, 201 quando algo foi criado, 202 quando o agente ainda tem trabalho a fazer. E todos descrevem o corpo que devolvem, com um nome próprio por recurso, pelo que o código gerado tem um tipo por recurso e não um por ponto final.

Convém ler com indulgência o que chega. Dentro desta versão só se acrescenta, pelo que pode aparecer um campo desconhecido: rejeitá-lo transformaria a nossa promessa de alterações aditivas numa rutura do lado do cliente. O que se envia é julgado com rigor: um nome de campo com uma gralha é recusado em vez de ignorado em silêncio.

Paginação

As listas respondem com uma página e um cursor; devolve-se esse cursor até vir vazio. Por predefinição, uma página contém 50 linhas e, no máximo, 100.

Nunca pare numa página curta. Algumas listas filtram linha a linha depois da leitura, pelas permissões de quem pede ou por aquilo de que um fornecedor é capaz, e devolvem legitimamente menos linhas do que as pedidas mesmo havendo mais para vir. O cursor é o único sinal de fim.

Erros

Todas as respostas que não são um sucesso têm a mesma forma, seja o que for que correu mal e onde quer que tenha corrido mal.

json
{
  "error": {
    "code": "validation_failed",
    "message": "Name is too long (max 64).",
    "detail": "server.validation.apiKeys.nameTooLong",
    "params": { "max": 64 },
    "requestId": "3f9c1b2a-..."
  }
}
code
A palavra sobre a qual ramificar. Vem de uma lista fechada, pelo que um valor desconhecido significa que se está a falar com uma versão mais recente do que aquela para a qual se construiu.
message
Uma frase em inglês, para quem lê um registo. Nunca ramifique por ela: a formulação pode mudar a qualquer momento.
detail
Uma chave estável, quando existe. É a mesma chave que o painel usa para a sua própria mensagem, o que permite escrever a frase no seu próprio idioma.
params
Os argumentos que pertencem a essa chave: um limite que foi excedido, um nome que já estava ocupado, o host que recusou.
requestId
O identificador deste pedido, presente também num cabeçalho da resposta. Indique-o quando nos perguntar alguma coisa.
Não existe em lado nenhum um estado que diga «existe mas ainda não foi construído». Um caminho que esta versão não oferece é um simples not-found, porque um roteiro não é algo que uma mensagem de erro deva revelar.
Um not-found significa uma de duas coisas, e a chave estável diz qual. Ou esta parte da API está desligada aqui, ou o recurso não está na conta. Este segundo caso abrange de propósito tanto um identificador que não existe como um que não se pode ver, porque distingui-los permitiria sondar que linhas existem.

Quanto se pode pedir

São permitidos 120 pedidos por minuto e por chave, e 600 por conta, somando todas as suas chaves. Esse segundo limite existe para que vinte chaves não possam colocar vinte vezes a carga no mesmo host.

Todas as respostas indicam o limite, quanto dele resta e quando a janela é reposta. Uma recusa acrescenta quanto tempo se deve esperar; siga esse número em vez de um atraso à sua escolha.

Repetir um pedido em segurança

Tudo o que cria alguma coisa aceita um cabeçalho idempotency-key à sua escolha. Repita o mesmo pedido com o mesmo valor e receberá de volta o primeiro resultado, em vez de uma segunda máquina, de uma segunda chave ou de um segundo comando.

Reutilizar esse valor para um pedido diferente é recusado de propósito. Uma chave que significa duas coisas não significa nada, e a alternativa, fazer também a segunda coisa em silêncio, é como se acaba com uma máquina que ninguém encomendou.

Também é possível enviar um x-request-id próprio. Volta na resposta e aparece nos nossos registos, que é a forma mais barata de emparelhar uma linha do seu lado com uma linha do nosso.

Fornecedores

No encaminhamento desta API não há um único nome de fornecedor. Que sistemas se podem ligar, que campos as respetivas credenciais aceitam e de que são capazes é o que o endpoint de discovery responde, e o corpo que se envia para criar uma integração é construído a partir desse mesmo registo. Um fornecedor que entra em funcionamento aparece em ambos sem que um único endpoint mude.

O contrário também é verdade. Ao pedir a uma máquina algo que o seu fornecedor não sabe fazer (uma consola numa conta de alojamento, um disco num servidor de jogos), obtém-se uma recusa que nomeia a capacidade em falta, antes de qualquer coisa ser enviada para o agente.

Todos os endpoints

Agrupados como a especificação os agrupa. Cada caminho vem depois do URL de base e, ao lado, está o âmbito que o endpoint exige; onde não está nada, basta uma chave válida.

Esta lista é uma citação e por isso mantém-se em inglês em todos os idiomas: os caminhos, os âmbitos e os resumos são literalmente o que a especificação diz, e traduzi-los mostraria uma palavra diferente da resposta que se recebe.
Algumas partes estão por trás de um interruptor de lançamento, e a descrição abrange-as quer esteja ligado quer não, pelo que um único cliente gerado serve para qualquer instalação. Que interruptor um ponto final precisa está indicado ao lado; se esta instalação o tem ligado consta da descrição legível por máquina mais abaixo. Desligado, o caminho responde com um not-found: não há chave nem papel que o ligue.

Self

The key itself: what it may do, and managing the keys of this member.

  • GET /api-keysapi-keys:manageList the API keys of the member behind this key, including revoked ones.
  • POST /api-keys201api-keys:manageCreate an API key. The secret is returned once and never again.
  • DELETE /api-keys/{keyId}api-keys:manageRevoke an API key belonging to the member behind this key.
  • GET /dashboardThe dashboard tiles as numbers: servers, agents, capacity, credit, incidents, notifications.
  • GET /meDescribe the organization, member and permissions behind this API key or app session.
  • GET /organizationsList every account this member can work in, oldest membership first.
  • POST /organizations/{organizationId}/activateSwitch the active account of this session. Returns the account you are now in.
  • POST /ws-ticketMint a single-use ticket for the realtime WebSocket.

Discovery

What this platform can integrate with. Read this first if you build forms: a provider that goes live shows up here without any change to the endpoints below.

  • GET /integration-typesagents:readList the integration types this platform can manage, with their capabilities.

Servers

Virtual machines, hosting accounts and game servers. Everything that changes a machine is asynchronous: you get 202 with a command to poll.

  • GET /serversservers:readList the servers this key may see, oldest first.
  • POST /servers202servers:writeOrder a server: a VM on a hypervisor, a hosting account on a control panel, or a game server on a game panel. Returns 202 with the command to poll.
  • DELETE /servers/{serverId}202servers:writeDelete a server. Returns 202 with a command when the provider is asked to remove it, or 200 when only the platform record is removed.
  • GET /servers/{serverId}servers:readFetch one server, including its agent, integration, capabilities and actions.
  • POST /servers/{serverId}/actions/{verb}202servers:writeRun a power action on a server (start, stop, shutdown, suspend, resume, restart, kill). Returns 202 with the command to poll.
  • POST /servers/{serverId}/actions/network-install202servers:writeInstall a server over the network with a PXE profile. Returns 202 with the command to poll.
  • POST /servers/{serverId}/actions/refresh-firewall-log202servers:writeAsk the agent for the most recent firewall log lines. Returns 202; the lines are in the command result.
  • POST /servers/{serverId}/actions/refresh-firewall-rules202servers:writeAsk the agent to read the current firewall rules and digest. Returns 202; poll the command, then read GET /firewall-rules.
  • POST /servers/{serverId}/actions/refresh-hardware202servers:writeAsk the agent to read the current disk and NIC layout. Returns 202; poll the command, then read GET /hardware.
  • POST /servers/{serverId}/actions/reinstall202servers:writeReinstall a server from an OS template: same vmid, same IP, everything on disk is lost. Returns 202 with the command to poll.
  • POST /servers/{serverId}/actions/sync-ip-filter202servers:writePush the allocated IP addresses into the VM firewall ipset. Returns 202 with the command to poll.
  • GET /servers/{serverId}/addressesservers:readList the IP addresses currently allocated to this server.
  • POST /servers/{serverId}/addressesservers:writeAllocate an IP address to this server, from a pool or a specific address. Synchronous: returns 200 with the allocation and whether the VM firewall picked it up.
  • DELETE /servers/{serverId}/addresses/{allocationId}servers:writeRelease an IP allocation back to the pool. Synchronous: returns 200 and whether the VM firewall picked it up.
  • GET /servers/{serverId}/commandsservers:readList the commands issued against this server, newest first.
  • POST /servers/{serverId}/disks202servers:writeAttach an extra disk to a server. Returns 202 with the command to poll.
  • DELETE /servers/{serverId}/disks/{disk}202servers:writeDetach a disk, optionally destroying the volume. Returns 202 with the command to poll.
  • PATCH /servers/{serverId}/disks/{disk}202servers:writeGrow a disk. Use "boot" as the disk key to grow the boot disk. Returns 202 with the command to poll.
  • GET /servers/{serverId}/firewall-rulesservers:readReturn the last observed firewall rules and the platform's ipfilter intent.
  • PUT /servers/{serverId}/firewall-rules202servers:writeReplace the customer-owned firewall rules. The digest from the last GET is required and acts as an optimistic lock. Returns 202 with the command to poll.
  • GET /servers/{serverId}/hardwareservers:readReturn the most recent hardware observation (disks, NICs, firewall state).
  • GET /servers/{serverId}/metricsservers:readRead the cpu, memory, disk and network series of one server for a window.
  • POST /servers/{serverId}/nics202servers:writeAttach an extra network interface. Note that this turns the VM ipfilter off while the new NIC has no addresses. Returns 202 with the command to poll.
  • DELETE /servers/{serverId}/nics/{nic}202servers:writeDetach a network interface. net0 is protected. Returns 202 with the command to poll.

Commands

The poll side of every asynchronous endpoint. A 202 hands you a command id and a Location header; this is where you read how it ended.

  • GET /commandsservers:readagents:readList commands across the organization, newest first.
  • GET /commands/{commandId}servers:readagents:readPoll one command: its state, result and error code.

Agents

The agents that run inside your own network and do the actual work.

  • GET /agentsagents:readList the agents of this account, oldest first.
  • POST /agents201agents:writeCreate an agent. The activation code and the installation one-liner are returned once and never again.
  • DELETE /agents/{agentId}agents:writeRemove an agent from the panel. Only possible when it is pending or revoked and has no integrations or servers left.
  • GET /agents/{agentId}agents:readGet one agent, including whether it is connected right now.
  • PATCH /agents/{agentId}agents:writeChange the name and/or the description of an agent.
  • POST /agents/{agentId}/actions/reissue-install-linkagents:writeIssue a new activation code and installation one-liner for this agent. Any outstanding enrollment token is superseded; the secrets are returned once.
  • POST /agents/{agentId}/actions/revokeagents:writeRevoke an agent: it loses its certificate and wipes its identity and credential vault. Repeating this is a no-op.
  • POST /agents/{agentId}/actions/update202agents:writeTell an agent to update itself to the release on this environment. Returns 202 with the command to poll.

Integrations

The connections from an agent to your infrastructure. Credentials are delivered to the agent once and are never readable back.

  • GET /integrationsagents:readList the integrations of this account, oldest first.
  • POST /integrations202agents:writeCreate an integration and deliver its credentials to the agent. Returns 202 with the credential push to poll.
  • DELETE /integrations/{integrationId}agents:writeDelete an integration. Refuses while servers are still attached.
  • GET /integrations/{integrationId}agents:readGet one integration, with what the provider behind it can do.
  • PATCH /integrations/{integrationId}agents:writeUpdate the name, provider settings, placement limits or enabled state. Credentials cannot be changed here.
  • POST /integrations/{integrationId}/actions/import-unmanagedagents:writeImport resources that exist on the remote system but not in Provibr, from an earlier unmanaged listing.
  • POST /integrations/{integrationId}/actions/list-remote202agents:writeAsk the agent to list something on the remote system (templates, plans, eggs, unmanaged resources). Which kinds exist is in the integration's remoteListings. Returns 202 with the command to poll.
  • POST /integrations/{integrationId}/actions/resend-credentials202agents:writeSend a complete new set of credentials to the agent. Returns 202 with the credential push to poll.
  • POST /integrations/{integrationId}/actions/test202agents:writeAsk the agent to test the connection to this system. Returns 202 with the command to poll.
  • GET /integrations/{integrationId}/install-methodagents:readGet the current install method, or — with ?method= — what switching to another one would do. Changes nothing.
  • PUT /integrations/{integrationId}/install-methodagents:writeSet the install method of this integration. Refuses when published, installable operating systems would lose their source.
  • GET /integrations/{integrationId}/os-linksagents:readList the operating systems linked to this integration, with the provider template and/or PXE profile behind each.
  • DELETE /integrations/{integrationId}/os-links/{osId}agents:writeClear one source for this operating system. The other source stays. Clearing a source that was not set is not an error.
  • PUT /integrations/{integrationId}/os-links/{osId}agents:writeSet one source (provider template or PXE profile) for this operating system on this integration. Leaves the other source untouched.

IPAM

Address space: groups, prefixes, allocations, reservations, child blocks and VLAN pools.

  • DELETE /ipam/allocations/{allocationId}ipam:writeRelease an address allocation or reservation. Sets released_at; the row stays as history.
  • GET /ipam/child-policiesipam:read⚑ ipamAutoAllocationList the child-prefix policies of this account, oldest first.
  • POST /ipam/child-policies201ipam:write⚑ ipamAutoAllocationCreate a child-prefix policy. Returns 201 with the policy.
  • DELETE /ipam/child-policies/{policyId}ipam:write⚑ ipamAutoAllocationDelete a child-prefix policy. Refuses while reservations from it are still live.
  • GET /ipam/child-policies/{policyId}ipam:read⚑ ipamAutoAllocationGet one child-prefix policy.
  • PATCH /ipam/child-policies/{policyId}ipam:write⚑ ipamAutoAllocationReplace a child-prefix policy. Send the whole policy, not just the changed fields.
  • POST /ipam/child-policies/{policyId}/actions/reserveipam:write⚑ ipamAutoAllocationLease a child prefix (and a VLAN id when the policy has a pool) according to this policy. Repeat with the same idempotencyKey to get the same reservation back.
  • GET /ipam/child-reservationsipam:read⚑ ipamAutoAllocationList the child-prefix reservations of this account, oldest first. Includes released rows.
  • POST /ipam/child-reservations/{reservationId}/actions/set-stateipam:write⚑ ipamAutoAllocationMove a reservation to another state. Releasing from quarantine takes two steps: release_pending, then released.
  • GET /ipam/groupsipam:readList the IPAM groups of this account, oldest first.
  • POST /ipam/groups201ipam:writeCreate an IPAM group. Returns 201 with the group.
  • DELETE /ipam/groups/{groupId}ipam:writeDelete an IPAM group. Refuses while prefixes, plans or plan placements still point at it.
  • GET /ipam/groups/{groupId}ipam:readGet one IPAM group.
  • PATCH /ipam/groups/{groupId}ipam:writeReplace an IPAM group. Send the whole group, not just the changed fields.
  • GET /ipam/prefixesipam:readList the IPAM prefixes of this account, oldest first. Includes child blocks.
  • POST /ipam/prefixes201ipam:writeCreate an IPAM prefix. Pass parentId to carve a child block out of an existing one. Returns 201.
  • DELETE /ipam/prefixes/{prefixId}ipam:writeDelete an IPAM prefix. Refuses while child blocks, active allocations, plans or plan placements point at it. Also removes the released-allocation history of this block.
  • GET /ipam/prefixes/{prefixId}ipam:readGet one IPAM prefix, with its address usage.
  • PATCH /ipam/prefixes/{prefixId}ipam:writeReplace an IPAM prefix. Send the whole prefix; parentId is ignored (a block cannot move).
  • GET /ipam/prefixes/{prefixId}/allocationsipam:readList the address allocations of one prefix, oldest first. Includes released rows unless status=active.
  • POST /ipam/reservationsipam:writeReserve one or more addresses without a server. Already-taken addresses are skipped and returned by name.
  • GET /ipam/vlan-poolsipam:read⚑ ipamAutoAllocation⚑ networkAutomationList the VLAN pools of this account, oldest first.
  • POST /ipam/vlan-pools201ipam:write⚑ ipamAutoAllocation⚑ networkAutomationCreate a VLAN pool on a network fabric. Returns 201 with the pool.
  • DELETE /ipam/vlan-pools/{poolId}ipam:write⚑ ipamAutoAllocation⚑ networkAutomationDelete a VLAN pool. Refuses while any reservation (including released ones) or policy points at it.
  • GET /ipam/vlan-pools/{poolId}ipam:read⚑ ipamAutoAllocation⚑ networkAutomationGet one VLAN pool.
  • PATCH /ipam/vlan-pools/{poolId}ipam:write⚑ ipamAutoAllocation⚑ networkAutomationReplace a VLAN pool. Send the whole pool. The fabric cannot change while reservations are live.
  • GET /ipam/vlan-reservationsipam:read⚑ ipamAutoAllocation⚑ networkAutomationList the VLAN reservations of this account, oldest first. Includes released rows.
  • POST /ipam/vlan-reservations/{reservationId}/actions/set-stateipam:write⚑ ipamAutoAllocation⚑ networkAutomationMove a reservation to another state. Releasing from quarantine takes two steps: release_pending, then released.

Plans

What your customers can order: VPS plans, hosting plans and game plans.

  • GET /plans/gamecatalog:readList the game plans of this account, oldest first.
  • POST /plans/game201catalog:writeCreate a game plan. Returns 201 with the plan.
  • GET /plans/game/{planId}catalog:readGet one game plan.
  • PATCH /plans/game/{planId}catalog:writeReplace a game plan. Send the whole plan, not just the changed fields.
  • POST /plans/game/{planId}/actions/{verb}catalog:writeActivate or deactivate a game plan. Verbs: activate, deactivate.
  • GET /plans/vpscatalog:readList the VPS plans of this account, oldest first.
  • POST /plans/vps201catalog:writeCreate a VPS plan. Returns 201 with the plan.
  • GET /plans/vps/{planId}catalog:readGet one VPS plan.
  • PATCH /plans/vps/{planId}catalog:writeReplace a VPS plan. Send the whole plan, not just the changed fields.
  • POST /plans/vps/{planId}/actions/{verb}catalog:writeActivate or deactivate a VPS plan. Verbs: activate, deactivate.
  • GET /plans/webcatalog:readList the hosting plans of this account, oldest first.
  • POST /plans/web201catalog:writeCreate a hosting plan. Returns 201 with the plan.
  • GET /plans/web/{planId}catalog:readGet one hosting plan.
  • PATCH /plans/web/{planId}catalog:writeReplace a hosting plan. Send the whole plan, not just the changed fields.
  • POST /plans/web/{planId}/actions/{verb}catalog:writeActivate or deactivate a hosting plan. Verbs: activate, deactivate.

Billing

Read-only: subscription, invoices, payments and credit.

  • GET /billing/creditbilling:readRead the prepaid credit balance of this account, in cents.
  • GET /billing/credit/ledgerbilling:readList the credit ledger entries of this account, newest first.
  • GET /billing/invoicesbilling:readList the billing documents of this account, newest first.
  • GET /billing/invoices/{invoiceId}billing:readRead one billing document, including its line items.
  • GET /billing/paymentsbilling:readList the payments of this account, newest first.
  • GET /billing/subscriptionbilling:readRead the subscription of this account: status, capacity and monthly price.

Events

The audit log of this account. Page until nextCursor is null - a short page does not mean the end.

  • GET /eventsactivity:readList audit events of this account, newest first. Page until nextCursor is null; a short page does not mean the end.

Notifications

The inbox of the signed-in member, grouped per subject, plus which categories reach that member over which channel. App sessions only: a notification is addressed to a person, and an API key is a machine secret - use Events for machine access to what happened.

  • GET /notification-preferencesThe notification matrix of the signed-in member: per category, per channel, on or off.
  • PUT /notification-preferencesSet part or all of the notification matrix in one call. Returns the matrix as it now stands.
  • GET /notificationsList the notifications of the signed-in member, grouped per subject, newest first. Page until nextCursor is null.
  • POST /notifications/{notificationId}/readMark one notification as read. Returns the new unread badge count.
  • POST /notifications/read-allMark every unread notification of this member as read. Returns the new unread badge count.
  • GET /notifications/unread-countThe unread badge count of this member: unread subjects, not rows.

Tickets

Support conversations with the Provibr desk. App sessions only: every message has an author, and an API key is a machine secret with no person behind it - use Events for machine access to what happened.

  • GET /ticketsList the support conversations of this account, most recent activity first. Page until nextCursor is null.
  • POST /tickets201Open a support conversation. Returns the ticket including its first message.
  • GET /tickets/{ticketId}One support conversation: the header and the whole thread, oldest message first.
  • POST /tickets/{ticketId}/closeClose a support conversation. Returns the conversation as it now stands.
  • POST /tickets/{ticketId}/messagesReply to a support conversation. Returns the conversation as it now stands.

Webhooks

Endpoints that receive lifecycle events, and the delivery history of each of them.

  • GET /webhook-deliveries/{deliveryId}webhooks:read⚑ lifecycleBindingsRead one webhook delivery, including every attempt that was made.
  • POST /webhook-deliveries/{deliveryId}/actions/cancelwebhooks:write⚑ lifecycleBindingsCancel a delivery. Returns the state reached: cancelled (nothing was sent) or cancel_requested (a request is in flight and its remote effect is unknown).
  • POST /webhook-deliveries/{deliveryId}/actions/resend202webhooks:write⚑ lifecycleBindingsSend an existing delivery again under a NEW delivery ID. The receiver will process the event a second time; this is not a retry.
  • POST /webhook-deliveries/{deliveryId}/actions/retry202webhooks:write⚑ lifecycleBindingsRetry a failed delivery under the same delivery ID. The body and its signature stay byte-identical.
  • GET /webhookswebhooks:read⚑ lifecycleBindingsList the webhook endpoints of this account, oldest first.
  • POST /webhooks201webhooks:write⚑ lifecycleBindingsCreate a webhook endpoint. Returns 201 with the endpoint and the signing secret — shown once and never again.
  • DELETE /webhooks/{webhookId}webhooks:write⚑ lifecycleBindingsDelete a webhook endpoint. Its lifecycle bindings AND its entire delivery history are deleted with it.
  • GET /webhooks/{webhookId}webhooks:read⚑ lifecycleBindingsRead one webhook endpoint, including its full revision history.
  • PATCH /webhooks/{webhookId}webhooks:write⚑ lifecycleBindingsPublish a new revision of a webhook endpoint. Omitted fields are carried over from the current revision.
  • POST /webhooks/{webhookId}/actions/rotate-secretwebhooks:write⚑ lifecycleBindingsRotate the HMAC signing secret. Publishes a new revision and returns the secret once; earlier deliveries stay verifiable with their own key ID.
  • POST /webhooks/{webhookId}/actions/test202webhooks:write⚑ lifecycleBindingsQueue a synthetic test delivery. Returns 202 with a deliveryId; nothing has been sent yet.
  • GET /webhooks/{webhookId}/deliverieswebhooks:read⚑ lifecycleBindingsList the deliveries of one webhook endpoint, newest first.

Devices

The phones and tablets the Provibr app runs on. App sessions only, and a push token is never returned - registering a device is the opt-in for push, forgetting one is the way back.

  • GET /devicesList the devices of the signed-in member, active ones first, including disabled ones.
  • POST /devicesRegister this device for push, or refresh the registration it already has.
  • DELETE /devices/{deviceId}Stop sending push to one of your devices. Returns the device as it now stands.

A descrição legível por máquina

A mesma informação sob a forma de um documento OpenAPI 3.1, gerado a partir do código que serve estes endpoints em vez de escrito ao lado dele. Entregue-o a um gerador de clientes, a um editor ou a um conjunto de testes.

shell
curl -s https://app.provibr.com/api/v1/openapi.json
O documento é público e não precisa de chave: descreve o que existe, não o que a sua conta contém.

Dentro desta versão, as alterações são adições: novos endpoints, novos campos opcionais, novos valores numa lista. Leia com tolerância os campos que não conhece e não trate como fatal um código de erro que não conhece.