---
title: "API REST"
description: "Referência da API REST do CloudHub: as oito operações, o header X-Api-Key, os modelos de requisição e resposta e cada código de erro, com o que fazer em cada caso."
canonical: "https://docs.lacunasoftware.com/articles/cloudhub/rest-api"
locale: "pt-BR"
product: "CloudHub"
last_updated: "2026-10-12"
---

# API REST

A API do CloudHub tem oito operações. As bibliotecas cliente as encapsulam, mas qualquer cliente
HTTP pode chamá-las diretamente; esta página documenta o formato das mensagens. A mesma API é
descrita de forma interativa, em OpenAPI, em
[cloudhub.lacunasoftware.com/swagger](https://cloudhub.lacunasoftware.com/swagger).

## Convenções

- **URL base**: `https://cloudhub.lacunasoftware.com`.
- **Autenticação**: toda operação exige a sua chave de API no header `X-Api-Key`. Uma requisição sem
  ela, ou com uma chave desconhecida, recebe HTTP 401 com o corpo vazio.
- **JSON**: os corpos de requisição e de resposta são JSON, com nomes de propriedade em camelCase.
- **Valores binários** (hashes, certificados, assinaturas) trafegam como strings base64. As operações
  de certificado e de `sign-hash` devolvem uma string JSON pura, como `"MIIH…"`.
- **Enumerações** trafegam como strings, como `"SingleSignature"` ou `"CPF"`. Os valores numéricos
  que os clientes 1.x enviam (`1` para `SingleSignature`) continuam aceitos.
- **Timeouts**: a assinatura espera pelo provedor. Dê até dois minutos para o `sign-hash`.

| Operação | Finalidade |
|---|---|
| [`POST /api/sessions`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#post-apisessions) | Criar uma sessão em todos os provedores que têm um certificado para o signatário |
| [`POST /api/sessions/services/{name}`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#post-apisessionsservicesname) | Criar uma sessão em um único provedor |
| [`GET /api/sessions/services`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#get-apisessionsservices) | Descobrir provedores sem criar uma sessão |
| [`GET /api/sessions/services/{name}/availability`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#get-apisessionsservicesnameavailability) | Perguntar a um provedor se ele tem um certificado |
| [`GET /api/sessions/certificate`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#get-apisessionscertificate) | Ler o certificado da sessão |
| [`GET /api/v2/sessions/certificate`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#get-apiv2sessionscertificate) | Ler o certificado da sessão, com o alias e o provedor |
| [`POST /api/sessions/sign-hash`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#post-apisessionssign-hash) | Assinar um hash com o certificado da sessão |
| [`GET /api/sessions/custom-state`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#get-apisessionscustom-state) | Ler de volta o `customState` informado na criação da sessão |

## Sessões

### POST /api/sessions

Cria uma sessão. Com um identificador, o CloudHub faz a [descoberta](https://docs.lacunasoftware.com/articles/cloudhub/how-it-works#descoberta) e
devolve só os provedores que têm um certificado para ele; sem identificador, devolve todos os
provedores.

| Campo do corpo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `redirectUri` | string | Sim | URI absoluta para onde o CloudHub devolve o usuário, com `session` acrescentado. Precisa estar [cadastrada para a sua chave](https://docs.lacunasoftware.com/articles/cloudhub/how-it-works#uris-de-redirecionamento). |
| `identifier` | string | Não | O CPF ou CNPJ do signatário, só com os dígitos. |
| `identifierType` | `CPF` ou `CNPJ` | Não | Como interpretar `identifier`. Quando omitido, mais de 11 dígitos indica um CNPJ. |
| `type` | [tipo de sessão](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#trustservicesessiontypes) | Não | O que o usuário autoriza. O padrão é `SingleSignature`. |
| `lifetimeInSeconds` | inteiro | Não | O tempo de vida da sessão a pedir ao provedor. O provedor pode conceder menos. |
| `customState` | string | Não | Dados seus, guardados com a sessão e devolvidos por [`GET /api/sessions/custom-state`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#get-apisessionscustom-state). |
| `discover` | booleano | Não | Se a descoberta deve ser feita. O padrão é `true` quando `identifier` é informado. `false` devolve todos os provedores e passa `identifier` a cada um como dica de login. `true` exige `identifier`. |

```bash
curl https://cloudhub.lacunasoftware.com/api/sessions \
  -H "X-Api-Key: $CLOUDHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"identifier": "12345678909", "redirectUri": "https://app.example.com/sign/complete", "type": "SingleSignature"}'
```

A resposta é um [`SessionModel`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#sessionmodel):

```json
{
  "services": [
    {
      "serviceInfo": {
        "serviceName": "BirdID",
        "provider": "SOLUTI",
        "endpoint": "https://api.birdid.com.br/",
        "badgeUrl": "https://cdn.lacunasoftware.com/img/psc/birdid.png"
      },
      "authUrl": "https://api.birdid.com.br/oauth/authorize?client_id=…"
    }
  ]
}
```

Erros: `InvalidRedirectUri`, `UnauthorizedRedirectUri`, `IdentifierRequiredToDiscover`; HTTP 400
quando falta `redirectUri`.

### POST /api/sessions/services/\{name\}

Cria uma sessão em um único provedor, sem descoberta. Use quando o usuário já escolheu o provedor.
`name` é um `serviceName` como o CloudHub o devolve, por exemplo `BirdID`.

O corpo aceita os mesmos campos de [`POST /api/sessions`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#post-apisessions), exceto
`identifierType`. `identifier`, quando informado, é passado ao provedor como dica de login;
`discover` é ignorado.

A resposta é um único [`TrustServiceAuthParametersModel`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#trustserviceauthparametersmodel):
`serviceInfo` e `authUrl`.

Erros: `ServiceNotFound` (com `details.name`), `InvalidRedirectUri`, `UnauthorizedRedirectUri`.

## Descoberta

### GET /api/sessions/services

Faz a descoberta sem criar uma sessão e devolve os provedores que têm um certificado para o
identificador, como uma lista de [`TrustServiceInfoModel`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#trustserviceinfomodel). Esta resposta
não tem `authUrl`.

| Parâmetro de query string | Obrigatório | Descrição |
|---|---|---|
| `identifier` | Sim | O CPF ou CNPJ, só com os dígitos. |
| `identifierType` | Não | `CPF` (padrão) ou `CNPJ`. |

```bash
curl "https://cloudhub.lacunasoftware.com/api/sessions/services?identifier=12345678909" \
  -H "X-Api-Key: $CLOUDHUB_API_KEY"
```

Um provedor que não responde fica de fora da lista.

### GET /api/sessions/services/\{name\}/availability

Pergunta a um provedor se ele tem um certificado para o identificador. Aceita os mesmos parâmetros
de query string de [`GET /api/sessions/services`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#get-apisessionsservices).

```json
{
  "discoveryAvailable": true,
  "certificateFound": true
}
```

`discoveryAvailable` é `false` quando o provedor não conseguiu responder; nesse caso,
`certificateFound` é `null`.

Erros: `ServiceNotFound` (com `details.name`).

## Usando uma sessão

Estas operações recebem o valor `session` que a sua URI de redirecionamento recebeu. Elas falham
com `SessionInvalidOrAlreadyUsed` quando o CloudHub não conhece a sessão ou o provedor não a aceita
mais. As operações de certificado e de `sign-hash` também falham com `SessionExpired` depois que o
tempo de vida da sessão acaba.

### GET /api/sessions/certificate

Devolve o certificado da sessão, codificado em DER e depois em base64, como uma string JSON. Quando o
provedor tem vários certificados para o usuário, o CloudHub escolhe o que está dentro da validade e
foi emitido mais recentemente.

```bash
curl "https://cloudhub.lacunasoftware.com/api/sessions/certificate?session=9f2c…e81a" \
  -H "X-Api-Key: $CLOUDHUB_API_KEY"
```

```json
"MIIHGjCCBQKgAwIBAgI…"
```

### GET /api/v2/sessions/certificate

Devolve o mesmo certificado como um [`CertificateModel`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#certificatemodel), com o alias dele e o
nome do serviço do provedor:

```json
{
  "content": "MIIHGjCCBQKgAwIBAgI…",
  "alias": "a5f1…",
  "serviceName": "BirdID"
}
```

Passe o `alias` ao `sign-hash` como `certificateAlias` para assinar exatamente com esse certificado.

### POST /api/sessions/sign-hash

Assina um hash com a chave do usuário e devolve o valor da assinatura, em base64, como uma string
JSON.

| Campo do corpo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `session` | string | Sim | O valor da sessão. |
| `hash` | string | Sim | O hash a assinar, em base64. |
| `digestAlgorithmOid` | string | Um dos dois | O OID do algoritmo de hash, como `2.16.840.1.101.3.4.2.1` para SHA-256. Tem precedência sobre `digestAlgorithm`. |
| `digestAlgorithm` | string | Um dos dois | O nome do algoritmo, como `SHA-256`. |
| `certificateAlias` | string | Não | O certificado com que assinar, vindo de [`GET /api/v2/sessions/certificate`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#get-apiv2sessionscertificate). O padrão é o certificado que `GET /api/sessions/certificate` devolve. |

```bash
curl https://cloudhub.lacunasoftware.com/api/sessions/sign-hash \
  -H "X-Api-Key: $CLOUDHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"session": "9f2c…e81a", "hash": "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=", "digestAlgorithmOid": "2.16.840.1.101.3.4.2.1"}'
```

```json
"Qy1kZ3N0b3JlIHNpZ25hdHVyZSB2YWx1ZS4uLg…"
```

Erros: `DigestAlgorithmNameOrOidIsRequired`, `InvalidDigestAlgorithm`, `SessionExpired`,
`SessionInvalidOrAlreadyUsed`.

### GET /api/sessions/custom-state

Devolve o `customState` informado na criação da sessão, como uma string JSON, ou `null` quando não
houve nenhum. O parâmetro de query string `session` é obrigatório.

Erros: `SessionInvalidOrAlreadyUsed`.

## Modelos

### SessionModel

| Campo | Tipo | Descrição |
|---|---|---|
| `services` | [`TrustServiceAuthParametersModel`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#trustserviceauthparametersmodel)[] | Uma entrada por provedor. Vazia quando nenhum tem um certificado para o identificador. |

### TrustServiceAuthParametersModel

| Campo | Tipo | Descrição |
|---|---|---|
| `serviceInfo` | [`TrustServiceInfoModel`](https://docs.lacunasoftware.com/articles/cloudhub/rest-api#trustserviceinfomodel) | O provedor. |
| `authUrl` | string | Para onde enviar o usuário para autorizar nesse provedor. |

### TrustServiceInfoModel

| Campo | Tipo | Descrição |
|---|---|---|
| `serviceName` | string | O nome do provedor no CloudHub, como `BirdID`. Vai no caminho das operações de um único provedor. |
| `provider` | string | A empresa que opera o serviço, como `SOLUTI`. |
| `endpoint` | string | O endereço da API do provedor. |
| `badgeUrl` | string | O logotipo do provedor. Pode ser nulo. |

### CertificateModel

| Campo | Tipo | Descrição |
|---|---|---|
| `content` | string | O certificado, codificado em DER e depois em base64. |
| `alias` | string | O identificador do certificado no provedor. |
| `serviceName` | string | O provedor de onde o certificado veio. |

### GetServiceAvailabilityResponse

| Campo | Tipo | Descrição |
|---|---|---|
| `discoveryAvailable` | booleano | Se o provedor respondeu. |
| `certificateFound` | booleano ou nulo | Se ele tem um certificado para o identificador. Nulo quando não respondeu. |

### TrustServiceSessionTypes

`SingleSignature`, `MultiSignature`, `SignatureSession`, `AuthenticationSession`. Veja
[Tipos de sessão](https://docs.lacunasoftware.com/articles/cloudhub/how-it-works#tipos-de-sessão).

### IdentifierTypes

`CPF`, `CNPJ`.

## Erros

| Status HTTP | Corpo | Significado |
|---|---|---|
| 400 | Um problema de validação, com os campos | Um campo obrigatório falta ou está malformado, como `redirectUri`. |
| 401 | Vazio | O header `X-Api-Key` falta ou a chave é desconhecida. |
| 422 | `{ "code", "message", "details" }` | O CloudHub recusou a requisição. `code` é um dos códigos abaixo. |
| 500 | Uma string JSON com um código curto, como `"4F1A2B"` | Uma falha inesperada, muitas vezes no provedor. Informe o código ao suporte da Lacuna. |

```json
{
  "code": "UnauthorizedRedirectUri",
  "message": "Unauthorized redirect URI",
  "details": {
    "redirectUri": "https://app.example.com/sign/complete"
  }
}
```

| Código | Significado | O que fazer |
|---|---|---|
| `InvalidRedirectUri` | `redirectUri` não é uma URI absoluta. | Envie a URI completa, com esquema e host. |
| `UnauthorizedRedirectUri` | `redirectUri` não está cadastrada para a sua chave. `details.redirectUri` a mostra. | Peça ao suporte da Lacuna que a cadastre. Veja [URIs de redirecionamento](https://docs.lacunasoftware.com/articles/cloudhub/how-it-works#uris-de-redirecionamento). |
| `IdentifierRequiredToDiscover` | `discover` é `true`, mas não há `identifier`. | Envie o identificador ou retire `discover`. |
| `ServiceNotFound` | Nenhum provedor tem esse nome. `details.name` o mostra. | Use um `serviceName` devolvido pelo CloudHub. |
| `DigestAlgorithmNameOrOidIsRequired` | O `sign-hash` não tem `digestAlgorithm` nem `digestAlgorithmOid`. | Envie um dos dois. |
| `InvalidDigestAlgorithm` | O nome ou o OID do algoritmo de hash não é reconhecido. | Envie o OID que a sua biblioteca de assinatura informa. |
| `SessionInvalidOrAlreadyUsed` | O CloudHub não conhece a sessão, ou o provedor não a aceita mais, por exemplo porque ela já foi usada. | Crie uma nova sessão. |
| `SessionExpired` | O tempo de vida da sessão acabou. Pode acontecer no primeiro uso, quando o usuário demorou a autorizar. | Crie uma nova sessão e envie o usuário ao provedor de novo. |
