Ir al contenido

Documentación

La API REST

Todo lo que se hace en el panel lo puede hacer también su propio código. Una clave, una URL base y exactamente los permisos que ya se tienen. Nada de esto es un atajo para saltarse el panel.

URL base y autenticación

Todas las rutas de esta página cuelgan de la URL base de abajo, y cada petición lleva su clave en una cabecera Authorization. No hay otra manera de entrar: ni cookie de sesión, ni autenticación básica, ni clave en la cadena de consulta.

shell
curl -s https://app.provibr.com/api/v1/me \
  -H "Authorization: Bearer pvk_..."
No hay CORS, y eso es una decisión deliberada, no un olvido. Una clave bearer en el JavaScript del navegador es una clave filtrada: cualquier visitante puede leerla. Llame a esta API desde su propio backend, nunca desde una página abierta en el navegador de otra persona.
Los comandos y la salida del terminal están en inglés en todas partes, en el panel y en estas páginas. Un solo texto, una sola verdad: lo que se lee aquí es literalmente lo que devolverá su host.

Las claves

Una clave se crea en la propia página de perfil, en «Claves de API». Pertenece a una sola persona y a una sola cuenta: no se comparte con los compañeros y deja de funcionar en el momento en que esa persona abandona la cuenta.

Una clave se muestra una sola vez, al crearla. De ella guardamos solo un hash, así que una clave perdida no se puede recuperar: cree una nueva y revoque la anterior.
  • Una clave caduca al cabo de 90 días salvo que se elija otra cosa. Se puede escoger un plazo más corto, o ninguno; una clave sin fecha de fin es una clave que hay que acordarse de revocar a mano.
  • Rotar consiste en crear una clave nueva y revocar la anterior, con un momento intermedio en el que las dos funcionan. No se puede rotar el secreto de una clave sin cambiar de clave, porque eso dejaría sin ninguna clave utilizable si algo saliera mal a mitad de camino.
  • Una clave se puede atar a una lista de direcciones. Una petición que llegue desde cualquier otro sitio se rechaza antes de leer nada, y ese rechazo no le dice nada sobre la clave a quien llama.
  • Un miembro tiene como máximo 25 claves. Una clave revocada conserva su fila, así que después se puede seguir viendo qué se le permitía hacer mientras estuvo activa.
Los propietarios y los administradores ven todas las claves de la cuenta en «Ajustes», junto con el miembro al que pertenece cada una. Esa página es la revisión de accesos: es el único sitio donde se ve de un vistazo quién puede llegar a esta cuenta desde fuera del panel.

Qué puede hacer una clave

Una clave lleva permisos: de lectura o de escritura, por cada parte del panel. Lo que puede hacer realmente es la intersección de esos permisos y los del miembro al que pertenece.

Un permiso de la clave nunca concede más de lo que el miembro ya tiene. Marcar el acceso de escritura en la clave de alguien que no puede crear servidores no le concede nada a esa clave; solo puede restringir lo que la clave tiene permitido hacer.

Los permisos se leen en vivo, en cada petición. Si se le retira algo a un miembro, todas sus claves quedan más restringidas al instante, sin que nadie tenga que revocar nada. Por eso mismo una clave sobrevive a un cambio de rol en lugar de quedar invalidada por él.

Todo lo que hace un agente lleva tiempo

Su infraestructura solo es accesible a través del agente que está dentro de su propia red, y ese agente conecta hacia fuera. Por eso un endpoint que modifica una máquina no puede responder con el resultado: responde que la orden se ha aceptado y entrega algo con lo que hacer el seguimiento.

  1. Se envía la petición y llega una respuesta de aceptación, con una cabecera Location que apunta al comando que se ha creado. Esa cabecera es absoluta desde el host: hay que resolverla contra el origen y no contra la URL base de arriba, o se acaba pidiendo una ruta que no existe.
  2. Ese mismo comando viene también en el cuerpo, pero envuelto en un campo command. La lectura de abajo lo devuelve desnudo, sin esa envoltura: basta con desenvolverlo una vez y la primera lectura suele ser innecesaria.
  3. Se lee el comando hasta que su estado es definitivo: completado, fallido, caducado o cancelado. Solo pendiente no es definitivo, y un estado desconocido cuenta también como definitivo, de modo que un valor añadido más adelante nunca deja el bucle abierto para siempre.
  4. Un comando fallido lleva el código de error del propio agente, con sus parámetros: los mismos que el panel muestra en pantalla.
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_..."
La lectura nunca funciona así. Un inventario, una dirección o una factura responden al momento, porque esa respuesta sale de nuestra base de datos y no de su host.

Lo que se recibe

Cada endpoint dice con qué responde: 200 en una lectura, 201 cuando se ha creado algo, 202 cuando el agente todavía tiene trabajo por hacer. Y todos describen el cuerpo que devuelven, con un nombre propio por recurso, de modo que el código generado tiene un tipo por recurso y no uno por endpoint.

Conviene leer con indulgencia lo que llega. Dentro de esta versión solo se añade, así que puede aparecer un campo desconocido: rechazarlo convertiría nuestra promesa de cambios aditivos en una ruptura del lado del cliente. Lo que se envía se juzga con rigor: un nombre de campo con una errata se rechaza en lugar de ignorarse en silencio.

La paginación

Las listas responden con una página y un cursor; ese cursor se devuelve una y otra vez hasta que sale vacío. Una página contiene 50 filas por defecto y 100 como máximo.

Nunca hay que parar ante una página corta. Algunas listas filtran fila a fila después de leer, por los permisos o por lo que es capaz de hacer un proveedor, y devuelven legítimamente menos filas de las pedidas aunque todavía queden más. El cursor es la única señal de final.

Los errores

Toda respuesta que no sea un éxito tiene la misma forma, con independencia de qué haya fallado y de dónde haya fallado.

json
{
  "error": {
    "code": "validation_failed",
    "message": "Name is too long (max 64).",
    "detail": "server.validation.apiKeys.nameTooLong",
    "params": { "max": 64 },
    "requestId": "3f9c1b2a-..."
  }
}
code
La palabra sobre la que ramificar. Sale de una lista cerrada, así que un valor desconocido significa que se está hablando con una versión más nueva que aquella sobre la que se construyó.
message
Una frase en inglés, para quien lea un registro. Nunca hay que ramificar sobre ella: la redacción puede cambiar.
detail
Un identificador estable, cuando lo hay. Es el mismo que el panel utiliza para componer su propio mensaje, así que la frase se puede redactar en el idioma que corresponda.
params
Los parámetros que acompañan a ese identificador: un límite que se ha superado, un nombre que ya estaba ocupado, el host que ha rechazado la conexión.
requestId
El identificador de esta petición, presente también en una cabecera de la respuesta. Conviene citarlo al consultarnos algo.
En ningún sitio hay un estado que diga «existe pero todavía no está construido». Una ruta que esta versión no ofrece devuelve sencillamente un «no encontrado», porque una hoja de ruta no es algo que deba revelar un mensaje de error.
Un no encontrado significa una de dos cosas, y la clave estable dice cuál. O esta parte de la API está apagada aquí, o el recurso no está en la cuenta; y eso segundo cubre a propósito tanto un identificador que no existe como uno que no se puede ver, porque distinguirlos permitiría tantear qué filas hay.

Cuánto se puede pedir

Se pueden hacer 120 peticiones por minuto y por clave, y 600 por cuenta sumando todas sus claves. Ese segundo límite existe para que veinte claves no puedan cargar veinte veces el mismo host.

Cada respuesta indica el límite, cuánto queda de él y cuándo se reinicia la ventana. Un rechazo añade además cuánto conviene esperar; hay que respetar ese número en lugar de una demora elegida por cuenta propia.

Repetir una petición con seguridad

Todo lo que crea algo acepta una cabecera idempotency-key elegida por quien llama. Si se repite la misma petición con el mismo valor, se recupera el primer resultado en lugar de obtener una segunda máquina, una segunda clave o un segundo comando.

Reutilizar ese valor para una petición distinta se rechaza a propósito. Un valor que significa dos cosas no significa nada, y la alternativa, hacer también en silencio la segunda cosa, es la manera de acabar con una máquina que nadie pidió.

También se puede enviar un x-request-id propio. Vuelve en la respuesta y aparece en nuestros registros, que es la forma más barata de poner una línea del registro propio junto a una línea del nuestro.

Los proveedores

En el enrutado de esta API no hay ni un solo nombre de proveedor. Qué sistemas se pueden conectar, qué campos llevan sus credenciales y de qué son capaces lo responde el endpoint de descubrimiento, y el cuerpo que se envía para crear una integración se construye a partir de ese mismo registro. Un proveedor que entra en servicio aparece en los dos sin que cambie ni un solo endpoint.

También funciona al revés. Pedirle a una máquina algo que su proveedor no sabe hacer (una consola en una cuenta de hosting, un disco en un servidor de juego) devuelve un rechazo que nombra la capacidad que falta, antes de que se envíe nada al agente.

Todos los endpoints

Agrupados igual que los agrupa la especificación. Cada ruta va detrás de la URL base y a su lado figura el permiso que exige el endpoint; donde no figura nada, basta con una clave válida.

Esta lista es una cita y por eso se queda en inglés en todos los idiomas: las rutas, los permisos y los resúmenes son literalmente lo que dice la especificación, y traducirlos mostraría una palabra distinta de la respuesta que se recibe.
Algunas partes están detrás de un interruptor de despliegue, y la descripción las recoge tanto si está encendido como si no, de modo que un único cliente generado sirve para cualquier instalación. Qué interruptor necesita un endpoint aparece a su lado; si esta instalación lo tiene encendido figura en la descripción legible por máquina de más abajo. Apagado, la ruta responde con un no encontrado: no hay clave ni rol que lo encienda.

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.

La descripción legible por máquina

La misma información en forma de documento OpenAPI 3.1, generado a partir del código que sirve estos endpoints en vez de escrito al lado. Se le puede entregar a un generador de clientes, a un editor o a un conjunto de pruebas.

shell
curl -s https://app.provibr.com/api/v1/openapi.json
El documento es público y no necesita ninguna clave: describe lo que existe, no lo que contiene su cuenta.

Dentro de esta versión, los cambios son añadidos: endpoints nuevos, campos opcionales nuevos, valores nuevos en una lista. Conviene leer con tolerancia los campos desconocidos y no tratar como fatal un código de error que no se conozca.