Início / Documentação da API

Autenticação

Os endpoints protegidos utilizam autenticação via HMAC no login. Após autenticar, todas as demais rotas protegidas exigem um Bearer token no cabeçalho:

Authorization: Bearer <token>

Assinatura HMAC-SHA256

A requisição de login não utiliza Bearer token. Em vez disso, o cliente assina cada requisição usando HMAC-SHA256 com o seu client_secret. Isso garante que apenas quem possui o secret pode autenticar, sem nunca transmiti-lo diretamente.

Algoritmo

  1. Obtenha o Unix timestamp atual em segundos inteiros.
  2. Monte a mensagem: {timestamp}:{client_id}
  3. Calcule HMAC-SHA256(key=client_secret, msg="{timestamp}:{client_id}") e encode o resultado em hexadecimal minúsculo.
  4. Envie os três valores como cabeçalhos HTTP da requisição de login.

A API rejeita requisições cujo timestamp diferir mais de ±5 minutos do horário do servidor.

Cabeçalhos gerados

Cabeçalho Valor
X-Client-ID UUID da conta (client_id)
X-Timestamp Unix timestamp (segundos inteiros)
X-Signature HMAC-SHA256(key=client_secret, msg="{timestamp}:{client_id}") em hex

Exemplos

cURL (bash)

CLIENT_ID="550e8400-e29b-41d4-a716-446655440000"
CLIENT_SECRET="seu_client_secret"
TIMESTAMP=$(date +%s)
MESSAGE="${TIMESTAMP}:${CLIENT_ID}"
SIGNATURE=$(echo -n "$MESSAGE" | openssl dgst -sha256 -hmac "$CLIENT_SECRET" | awk '{print $2}')

curl -X POST https://hub.lexxen.com/api/auth/login \
  -H "Content-Type: application/json" \
  -H "X-Client-ID: $CLIENT_ID" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "X-Signature: $SIGNATURE"

PHP

$clientId     = '550e8400-e29b-41d4-a716-446655440000';
$clientSecret = 'seu_client_secret';
$timestamp    = time();
$message      = "{$timestamp}:{$clientId}";
$signature    = hash_hmac('sha256', $message, $clientSecret);

$response = Http::withHeaders([
    'X-Client-ID' => $clientId,
    'X-Timestamp' => (string) $timestamp,
    'X-Signature' => $signature,
])->post('https://hub.lexxen.com/api/auth/login');

Java

String clientId     = "550e8400-e29b-41d4-a716-446655440000";
String clientSecret = "seu_client_secret";
long   timestamp    = System.currentTimeMillis() / 1000;
String message      = timestamp + ":" + clientId;

Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(clientSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
String signature = HexFormat.of().formatHex(mac.doFinal(message.getBytes(StandardCharsets.UTF_8)));

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://hub.lexxen.com/api/auth/login"))
    .header("Content-Type", "application/json")
    .header("X-Client-ID", clientId)
    .header("X-Timestamp", String.valueOf(timestamp))
    .header("X-Signature", signature)
    .POST(HttpRequest.BodyPublishers.noBody())
    .build();

Ruby

require 'openssl'
require 'net/http'

client_id     = '550e8400-e29b-41d4-a716-446655440000'
client_secret = 'seu_client_secret'
timestamp     = Time.now.to_i
message       = "#{timestamp}:#{client_id}"
signature     = OpenSSL::HMAC.hexdigest('SHA256', client_secret, message)

uri = URI('https://hub.lexxen.com/api/auth/login')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req['X-Client-ID']  = client_id
req['X-Timestamp']  = timestamp.to_s
req['X-Signature']  = signature

Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }

Endpoints


POST /auth/login

Autentica a conta usando assinatura HMAC nos headers e retorna um Bearer token.

Autenticação: Não utiliza Bearer token. A autenticação é feita por cabeçalhos HMAC.

Cabeçalhos obrigatórios

Cabeçalho Descrição
X-Client-ID UUID da conta (client_id)
X-Timestamp Unix timestamp (segundos) da requisição. Tolerância de ±5 minutos.
X-Signature HMAC-SHA256(key=secret, msg="{timestamp}:{client_id}") em hex — ver Assinatura HMAC-SHA256

Exemplo de requisição

POST /api/auth/login HTTP/1.1
Content-Type: application/json
X-Client-ID: 550e8400-e29b-41d4-a716-446655440000
X-Timestamp: 1704067200
X-Signature: a3f5b2c1d4e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2

Resposta — 200 OK

{
  "data": {
    "token": "1|abc123def456...",
    "expires_at": "2026-03-18T10:00:00.000000Z",
    "account": {
      "type": "company",
      "uuid": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Empresa Exemplo Ltda",
      "email": "[email protected]",
      "document_number": "12345678000195",
      "phone_number": "+5511999999999"
    },
    "services": [
      {
        "key": "pix_out",
        "label": "Pix Out",
        "enabled_at": "2026-01-01T00:00:00.000000Z"
      }
    ]
  }
}
Campo Tipo Descrição
token string Bearer token a ser enviado nas demais requisições
expires_at datetime|null Data/hora de expiração do token. null se sem expiração.
account.type string (enum) Ver AccountTypeEnum
account.uuid string (UUID) Identificador único da conta
account.name string Nome da conta
account.email string E-mail da conta
account.document_number string CPF ou CNPJ
account.phone_number string Telefone
services array Serviços habilitados para a conta
services[].key string Chave identificadora do serviço (ex.: pix_out, crypto_out)
services[].label string Nome legível do serviço
services[].enabled_at datetime Data em que o serviço foi habilitado

Erros

Status Descrição
401 X-Client-ID inválido ou assinatura incorreta

GET /solicitations

Lista solicitações da conta autenticada com filtros opcionais e paginação.

Autenticação: Bearer token obrigatório

Parâmetros de query

Parâmetro Tipo Obrigatório Descrição
external_ref string Não Filtrar pela referência externa (correspondência exata)
type string Não MANUAL ou AUTOMATIC
status string Não PENDING_REVIEW, APPROVED, REPROVED ou EXPIRED
initial_date date Não Data inicial (Y-m-d), deve ser ≤ hoje
final_date date Não Data final (Y-m-d), deve ser ≥ initial_date e ≤ hoje
page integer Não Número da página (padrão: 1)

Exemplo de requisição

GET /api/solicitations?status=PENDING_REVIEW&initial_date=2026-03-01&final_date=2026-03-17&page=1 HTTP/1.1
Authorization: Bearer 1|abc123def456...

Resposta — 200 OK

Lista paginada de Objeto Solicitation.

{
  "data": [
    {
      "id": 42,
      "external_ref": "pedido-789",
      "type": "MANUAL",
      "status": "PENDING_REVIEW",
      "seller": null,
      "details": {
        "pix_key": "12345678000195",
        "pix_key_type": "CNPJ",
        "amount": 15000,
        "fee_amount": 150,
        "meta": null
      },
      "created_at": "2026-03-07T14:00:00.000000Z",
      "updated_at": "2026-03-07T14:00:00.000000Z"
    }
  ],
  "links": {
    "first": "https://<host>/api/solicitations?page=1",
    "last": "https://<host>/api/solicitations?page=5",
    "prev": null,
    "next": "https://<host>/api/solicitations?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 5,
    "per_page": 15,
    "to": 15,
    "total": 70
  }
}

Erros

Status Descrição
401 Não autenticado
422 Erro de validação

GET /solicitations/summary/{period}

Retorna contagens das solicitações agrupados por status para um determinado período.

Autenticação: Bearer token obrigatório

Parâmetros de rota

Parâmetro Tipo Obrigatório Descrição
period string Não day, week, month, semester ou year. Omitir para retornar todos os registros.

Exemplo de requisição

GET /api/solicitations/summary/month HTTP/1.1
Authorization: Bearer 1|abc123def456...

Resposta — 200 OK

Array de entradas, uma por status mais uma entrada TOTAL.

Campo Tipo Descrição
status string Nome do status ou TOTAL
count integer Quantidade de solicitações
{
  "data": [
    { "status": "PENDING_REVIEW", "count": 12 },
    { "status": "APPROVED",       "count": 45 },
    { "status": "REPROVED",       "count": 3  },
    { "status": "EXPIRED",        "count": 1  },
    { "status": "TOTAL",          "count": 61 }
  ]
}

Erros

Status Descrição
401 Não autenticado
404 Valor de período inválido

GET /solicitations/{id}

Retorna uma única solicitação pelo ID.

Autenticação: Bearer token obrigatório

Parâmetros de rota

Parâmetro Tipo Obrigatório Descrição
id integer Sim ID da solicitação

Exemplo de requisição

GET /api/solicitations/42 HTTP/1.1
Authorization: Bearer 1|abc123def456...

Resposta — 200 OK

Um único Objeto Solicitation com vendedor e detalhes do tipo associado.

{
  "data": {
    "id": 42,
    "external_ref": "pedido-789",
    "type": "MANUAL",
    "status": "APPROVED",
    "seller": {
      "id": 10,
      "name": "João Silva",
      "email": "[email protected]",
      "phone_number": "+5511988887777",
      "document_number": "12345678900"
    },
    "details": {
      "pix_key": "[email protected]",
      "pix_key_type": "EMAIL",
      "amount": 15000,
      "fee_amount": 150,
      "meta": {
        "note": "Fatura #789"
      }
    },
    "created_at": "2026-03-07T14:00:00.000000Z",
    "updated_at": "2026-03-07T14:30:00.000000Z"
  }
}

Erros

Status Descrição
401 Não autenticado
404 Solicitação não encontrada

PATCH /solicitations/approve

Aprova uma ou mais solicitações em lote.

Autenticação: Bearer token obrigatório Autorização: A conta deve ter a permissão approve.

Corpo da requisição

Campo Tipo Obrigatório Descrição
ids integer[] Sim Array de IDs de solicitações a aprovar (mínimo: 1). Todos devem existir.

Exemplo de requisição

PATCH /api/solicitations/approve HTTP/1.1
Authorization: Bearer 1|abc123def456...
Content-Type: application/json

{
  "ids": [42, 43, 44]
}

Resposta — 200 OK

{
  "message": "Solicitations approved."
}

Erros

Status Descrição
401 Não autenticado
403 Conta sem permissão para aprovar
422 Erro de validação (IDs inválidos ou ausentes)

DELETE /solicitations/reprove

Reprova uma ou mais solicitações em lote.

Autenticação: Bearer token obrigatório Autorização: A conta deve ter a permissão reprove.

Corpo da requisição

Campo Tipo Obrigatório Descrição
ids integer[] Sim Array de IDs de solicitações a reprovar (mínimo: 1). Todos devem existir.

Exemplo de requisição

DELETE /api/solicitations/reprove HTTP/1.1
Authorization: Bearer 1|abc123def456...
Content-Type: application/json

{
  "ids": [42, 43]
}

Resposta — 200 OK

{
  "message": "Solicitations reproved."
}

Erros

Status Descrição
401 Não autenticado
403 Conta sem permissão para reprovar
422 Erro de validação (IDs inválidos ou ausentes)

POST /pix/out/solicitation

Cria um registro Pix Out com a chave e o valor e associa uma solicitação de pagamento.

  • Tipo MANUAL: a solicitação fica com status PENDING_REVIEW até ser aprovada manualmente.
  • Tipo AUTOMATIC: a solicitação é aprovada imediatamente e o envio ao gateway é disparado em fila.

Autenticação: Bearer token obrigatório

Corpo da requisição

Campo Tipo Obrigatório Descrição
pix_key string Sim Chave Pix de destino
pix_key_type string Sim Tipo da chave Pix. Ver PixKeyTypeEnum
amount integer Sim Valor em centavos (mínimo: 1)
type string Sim MANUAL ou AUTOMATIC
external_ref string Não Identificador de referência do seu sistema
meta object Não Metadados livres (qualquer objeto JSON)
seller object Não Dados do vendedor. Se informado, todos os subcampos são obrigatórios.
seller.name string Cond. Nome completo do vendedor
seller.email string Cond. E-mail do vendedor
seller.phone_number string Cond. Telefone do vendedor
seller.document_number string Cond. CPF ou CNPJ do vendedor

Exemplo de requisição

POST /api/pix/out/solicitation HTTP/1.1
Authorization: Bearer 1|abc123def456...
Content-Type: application/json

{
  "pix_key": "[email protected]",
  "pix_key_type": "EMAIL",
  "amount": 15000,
  "type": "MANUAL",
  "external_ref": "pedido-789",
  "meta": { "note": "Fatura #789" },
  "seller": {
    "name": "João Silva",
    "email": "[email protected]",
    "phone_number": "+5511988887777",
    "document_number": "12345678900"
  }
}

Resposta — 201 Created

{
  "data": {
    "pix_key": "[email protected]",
    "pix_key_type": "EMAIL",
    "amount": 15000,
    "fee_amount": 150,
    "meta": { "note": "Fatura #789" },
    "solicitation": {
      "id": 43,
      "external_ref": "pedido-789",
      "type": "MANUAL",
      "status": "PENDING_REVIEW",
      "seller": {
        "id": 11,
        "name": "João Silva",
        "email": "[email protected]",
        "phone_number": "+5511988887777",
        "document_number": "12345678900"
      },
      "created_at": "2026-03-08T10:00:00.000000Z",
      "updated_at": "2026-03-08T10:00:00.000000Z"
    }
  }
}

Erros

Status Descrição
401 Não autenticado
422 Erro de validação

GET /crypto/out/solicitations

Lista as solicitações de saque de criptomoeda da conta autenticada, em ordem decrescente de criação.

Autenticação: Bearer token obrigatório

Parâmetros de query

Parâmetro Tipo Obrigatório Descrição
page integer Não Número da página (padrão: 1)

Exemplo de requisição

GET /api/crypto/out/solicitations?page=1 HTTP/1.1
Authorization: Bearer 1|abc123def456...

Resposta — 200 OK

Lista paginada de Objeto Solicitation com details contendo os campos do saque de criptomoeda.

{
  "data": [
    {
      "id": 10,
      "external_ref": "order-001",
      "type": "MANUAL",
      "status": "PENDING_REVIEW",
      "seller": null,
      "details": {
        "address": "TRx9abc123...",
        "network": "TRC20",
        "coin": "USDT",
        "amount": 10.5,
        "fee_amount": 0,
        "lexxen_status": "pending"
      },
      "created_at": "2026-03-12T14:00:00.000000Z",
      "updated_at": "2026-03-12T14:00:00.000000Z"
    }
  ],
  "links": { "first": "...", "last": "...", "prev": null, "next": null },
  "meta": { "current_page": 1, "last_page": 1, "per_page": 15, "total": 1 }
}

Erros

Status Descrição
401 Não autenticado

POST /crypto/out/solicitations

Cria uma nova solicitação de saque de criptomoeda.

  • Tipo MANUAL: a solicitação fica com status PENDING_REVIEW até ser aprovada manualmente.
  • Tipo AUTOMATIC: a solicitação é aprovada imediatamente e o envio para o gateway LexxenCrypto é disparado em fila.

Autenticação: Bearer token obrigatório

Corpo da requisição

Campo Tipo Obrigatório Descrição
address string Sim Endereço de carteira de destino
amount number Sim Valor a enviar (ponto flutuante, ex.: 10.5)
network string Sim Rede blockchain (ex.: TRC20, ERC20)
coin string Sim Moeda (ex.: USDT)
type string Sim MANUAL ou AUTOMATIC
external_ref string Não Identificador de referência do seu sistema

Exemplo de requisição

POST /api/crypto/out/solicitations HTTP/1.1
Authorization: Bearer 1|abc123def456...
Content-Type: application/json

{
  "address": "TRx9abc123...",
  "amount": 10.5,
  "network": "TRC20",
  "coin": "USDT",
  "type": "MANUAL",
  "external_ref": "order-001"
}

Resposta — 201 Created

{
  "data": {
    "id": 10,
    "external_ref": "order-001",
    "type": "MANUAL",
    "status": "PENDING_REVIEW",
    "seller": null,
    "details": {
      "address": "TRx9abc123...",
      "network": "TRC20",
      "coin": "USDT",
      "amount": 10.5,
      "fee_amount": 0,
      "lexxen_status": null
    },
    "created_at": "2026-03-12T14:00:00.000000Z",
    "updated_at": "2026-03-12T14:00:00.000000Z"
  }
}

Erros

Status Descrição
401 Não autenticado
422 Erro de validação

Webhook de Saída

Sempre que o status de uma transação Pix Out ou Crypto Out é atualizado, o sistema envia automaticamente um POST para o endpoint de webhook configurado na conta. A entrega é assíncrona, processada pela fila webhooks.

Configuração

Os webhooks são configurados por conta através do painel administrativo (/admin/accounts/{id}). Cada conta pode ter:

Campo Descrição
URL Endpoint de destino (HTTP ou HTTPS)
Método POST, PUT ou PATCH
Ativo Chave para ativar ou suspender o envio
Cabeçalhos Headers adicionais enviados em todas as requisições (ex.: X-Api-Key)

Payloads enviados

Atualização de Status de Pix Out

POST https://seu-endpoint.com/webhook HTTP/1.1
Accept: application/json
Content-Type: application/json
X-Api-Key: seu-valor-de-header-customizado

{
  "id": 1,
  "identifier": "550e8400-e29b-41d4-a716-446655440000",
  "external_ref": "pedido-001",
  "amount": 15000,
  "pix_key": "[email protected]",
  "pix_key_type": "EMAIL",
  "status": "PAID",
  "reason": null,
  "end_to_end": "E9999901012026031000000000000001",
  "to_bank": "Banco do Brasil",
  "to_bank_branch": "0001",
  "to_bank_account": "12345-6",
  "ispb": null,
  "to_name": "João da Silva",
  "to_cnpj": "12345678000195",
  "created_at": "2026-03-08T10:00:00.000000Z",
  "updated_at": "2026-03-10T09:00:00.000000Z"
}

Atualização de Status de Crypto Out

POST https://seu-endpoint.com/webhook HTTP/1.1
Accept: application/json
Content-Type: application/json
X-Api-Key: seu-valor-de-header-customizado

{
  "identifier": "txn-abc-123",
  "address": "TRx9abc123...",
  "network": "TRC20",
  "coin": "USDT",
  "amount": 10.5,
  "fee": 0.5,
  "status": "confirmed"
}

Campos do payload

Campo Tipo Presente em Descrição
identifier string Todos Identificador único da transação no Hub
status string Todos Status atual. Ver PixOutStatusEnum ou CryptoWithdrawStatusEnum
amount number Todos Valor da transação (centavos para Pix, ponto flutuante para Crypto)
fee number Crypto Out Taxa aplicada pelo gateway
id integer Pix Out ID interno do PixOut
pix_key string Pix Out Chave Pix de destino
end_to_end string|null Pix Out Identificador E2E do Pix
address string Crypto Out Endereço de carteira de destino
network string Crypto Out Rede blockchain
coin string Crypto Out Moeda

Cabeçalhos

Toda requisição de webhook de saída inclui todos os headers configurados para a conta no painel administrativo. Os headers Accept: application/json e Content-Type: application/json são sempre enviados.

Histórico de tentativas

Cada tentativa de envio é registrada na tabela webhook_requests:

Campo Descrição
status Código HTTP da resposta (ex.: 200, 404, 500). 0 indica falha de conexão (timeout, erro de DNS, etc.).
body O payload enviado
response O corpo JSON retornado pelo seu endpoint (null se a resposta não for JSON)

O histórico pode ser consultado no painel administrativo, na aba Webhook da conta.

O worker da fila webhooks tenta reenviar jobs com falha até 3 vezes, com intervalos de backoff de 10s, 30s e 60s.


Referência

Enums

PixOutStatusEnum / PixInStatusEnum

Valor Descrição
PENDING Transação criada, aguardando processamento
PROCESSING Transação em processamento
AUTHORIZED Transação autorizada pelo gateway
WAITING_PAYMENT Aguardando confirmação de pagamento
PAID Transação concluída com sucesso
FAILED Transação falhou durante o processamento
REFUSED Transação recusada pelo gateway
REFUNDED Transação estornada
CHARGEDBACK Transação sofreu chargeback
DISPUTE Transação em disputa
BLOCKED Transação bloqueada

PixKeyTypeEnum

Valor Descrição
CPF CPF (pessoa física)
CNPJ CNPJ (pessoa jurídica)
PHONE Número de telefone
EMAIL Endereço de e-mail
EVP Chave aleatória (EVP)

SolicitationStatusEnum

Valor Descrição
PENDING_REVIEW Aguardando aprovação manual ou automática
APPROVED Solicitação aprovada e em processamento
REPROVED Solicitação reprovada
EXPIRED Solicitação expirada antes do processamento

SolicitationTypeEnum

Valor Descrição
MANUAL Requer aprovação manual
AUTOMATIC Aprovada automaticamente ao ser criada

PeriodEnum

Valor Descrição
day Dia atual
week Semana atual
month Mês atual
semester Semestre atual
year Ano atual

AccountTypeEnum

Valor Descrição
customer Conta de pessoa física
company Conta de pessoa jurídica

CryptoWithdrawStatusEnum

Valor Descrição
pending Transação criada, aguardando processamento
sent Transação enviada para a rede blockchain
confirmed Transação confirmada na rede blockchain
failed Transação falhou no processamento

Objetos comuns

Objeto PixOut

Campo Tipo Descrição
id integer ID interno no banco de dados
identifier string (UUID) Identificador único da transação
external_ref string|null Referência do seu sistema
amount integer Valor em centavos
pix_key string Chave Pix de destino
pix_key_type string (enum) Ver PixKeyTypeEnum
status string (enum) Ver PixOutStatusEnum / PixInStatusEnum
reason string|null Motivo de recusa ou falha informado pelo gateway
end_to_end string|null Identificador end-to-end do Pix (E2E ID)
to_bank string|null Nome do banco de destino
to_bank_branch string|null Agência do banco de destino
to_bank_account string|null Número da conta de destino
ispb string|null Código ISPB do banco de destino
to_name string|null Nome do titular da conta de destino
to_cnpj string|null CPF/CNPJ do titular da conta de destino
created_at datetime ISO 8601
updated_at datetime ISO 8601

Objeto Solicitation

Campo Tipo Descrição
id integer ID único da solicitação
external_ref string|null Referência do seu sistema
type string (enum) MANUAL ou AUTOMATIC
status string (enum) Ver SolicitationStatusEnum
seller object|null Dados do vendedor. Ver Objeto Seller
details object|null Dados específicos do tipo de transação. Ver Pix Out details ou Crypto Out details
created_at datetime ISO 8601
updated_at datetime ISO 8601

Objeto Solicitation.details — Pix Out

O campo details dentro de um Objeto Solicitation para saques Pix.

Campo Tipo Descrição
pix_key string Chave Pix de destino
pix_key_type string (enum) Ver PixKeyTypeEnum
amount integer Valor em centavos
fee_amount integer|null Taxa em centavos (preenchida após processamento)
meta object|null Metadados livres informados na criação

Objeto Solicitation.details — Crypto Out

O campo details dentro de um Objeto Solicitation para saques de criptomoeda.

Campo Tipo Descrição
address string Endereço de carteira de destino
network string Rede blockchain (ex.: TRC20, ERC20)
coin string Moeda (ex.: USDT)
amount number Valor solicitado (ponto flutuante)
fee_amount number Taxa aplicada pelo gateway (padrão 0 até o processamento)
lexxen_status string|null Status interno no gateway LexxenCrypto. Ver CryptoWithdrawStatusEnum. null enquanto não enviado.

Objeto Seller

Campo Tipo Descrição
id integer ID do vendedor
name string Nome completo
email string Endereço de e-mail
phone_number string Telefone
document_number string CPF ou CNPJ

Objeto Customer

Campo Tipo Descrição
id integer ID do pagador
name string Nome completo
email string Endereço de e-mail
phone_number string Telefone
document_number string CPF ou CNPJ

Respostas de erro

401 Não autenticado

{
  "message": "Unauthenticated."
}

403 Proibido

{
  "message": "This action is unauthorized."
}

404 Não encontrado

{
  "message": "No query results for model [Solicitation]."
}

422 Entidade não processável

{
  "message": "The ids field is required.",
  "errors": {
    "ids": [
      "The ids field is required."
    ]
  }
}