For AI agents: a documentation index is available at the root level at /llms.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
GET /v1/backoffice/tenants/{tenantId}/accounts passa a devolver accountNumber em cada item. É o override local (accounts.account_number); sem número gravado o campo sai null. IB e painel deixam de precisar de GET /bank-account por linha.
POST /v1/accounts/{accountId}/pix/keys com email ou phone deixa de recusar com 422. A facade envia um OTP (e-mail ou SMS) e responde 202pending_verification com challengeId e o destino mascarado. O liquidante só é chamado depois do acerto.
POST /v1/accounts/{accountId}/pix/keys/verify confirma o código e cadastra a chave (201). Erros: code_invalid, code_expired, challenge_locked, challenge_not_found.
POST /v1/accounts/{accountId}/pix/keys/verify/resend reenvia (cooldown 60s, no máximo 3 envios). Falha no envio devolve 503otp_send_failed e o challenge não fica usável.
GET /v1/accounts/{accountId}/statement/advanced ganha order=desc para quem tem milhares de lançamentos no dia e só quer os mais recentes: a varredura começa pelo fim e para ao cruzar occurredAfter. Sem cursor nesse modo (400 invalid_cursor); a continuação é por tempo, com nextOccurredBefore → occurredBefore, limite inclusivo (dedupe pelo id).
Novos filtros occurredAfter / occurredBefore (RFC 3339 com fuso, inclusivos) em qualquer ordem. Só encurtam a varredura quando são a fronteira na direção da varredura; no sentido contrário são apenas filtro.
order na resposta passa a ecoar asc ou desc. Comportamento sem order não muda.
Nova credencial delegada: uma credencial por conta, assinada. Uma credencial com o escopo credentials.delegate emite credenciais filhas amarradas a uma conta, com escopos que são sempre subconjunto dos dela, publicKeyPem e allowedIps (1 a 20 CIDRs) obrigatórios. A emissão devolve status: "pending" e um activeFrom18h à frente — até lá a credencial responde 403credential_not_yet_active. Revogar é imediato, inclusive durante a carência. Ver Autenticação.
Credenciais delegadas chamam https://client.api.corpx.com e assinam toda requisição com JWS detached (ES256 ou PS256) sobre MÉTODO\nPATH?QUERY\nTIMESTAMP\nIDEMPOTENCY_KEY\nX-Content-SHA256, mais os headers X-Request-Timestamp (tolerância de 300s), X-Content-SHA256 e X-Request-Signature. No host antigo elas recebem 403signed_host_required. Guia novo: Assinatura de Requisição.
POST /v1/security/signature/verify devolve a string canônica que esperamos, o hash do corpo e o resultado da verificação, para você acertar a assinatura antes da primeira transação. Sempre 200, nunca cria nada.
Chaves públicas e allowlist de IP por credencial, em GET|POST .../credentials/{clientId}/public-keys, DELETE .../public-keys/{kid} e GET|PUT .../credentials/{clientId}/ip-allowlist. Cadastrar chave ou adicionar IP espera 18h (pendingUntil); aposentar chave ou remover IP é imediato. Tenant com credencial delegada tem a allowlist de IP calculada a partir das credenciais, e o PUT /v1/security/ip-allowlist manual passa a responder 409ip_allowlist_derived.
Assinatura de webhook por conta.POST /v1/webhooks aceita accountId: a assinatura passa a receber só os eventos daquela conta. O campo não é editável depois e credencial restrita a contas é obrigada a informá-lo (422account_id_required). Ver Assinatura por conta.
Travas de saída configuráveis pelo titular em GET|PUT /v1/accounts/{accountId}/security/locks: cashoutBlocked, cashoutHours e cashoutSourceIps. Apertar vale na hora; afrouxar espera 6 horas (pendingEffectiveAt), campo por campo. DELETE .../locks/pending cancela o afrouxamento e POST .../locks/pending/approve antecipa com PIN. Saída recusada devolve 423cashout_locked, 403cashout_outside_hours ou 403cashout_source_ip_not_allowed.
PIN transacional por operador em PUT /v1/accounts/{accountId}/security/pin, DELETE .../security/pin/{document}, POST .../security/pin/verify e GET .../security/pin/status. Quando a credencial exige PIN, as rotas de saída passam a pedir X-Acting-Document e X-Transaction-Pin (428pin_required). 3 erros travam por 15 minutos (429), 6 travam até redefinir (423). PIN de 6 a 12 dígitos, sem repetição, sequência ou data de nascimento (422weak_pin).
GET /v1/accounts/{accountId}/shared-access lista os tenants que operam a mesma conta bancária, com displayName, status, since e isCurrent. Só metadado público.
Nada muda para as integrações existentes. Credenciais atuais continuam em https://tenant.api.corpx.com sem assinar nada; contas sem trava e sem PIN operam como antes; assinatura de webhook sem accountId continua recebendo os eventos de todas as contas.
Duas seções no site. Navbar BaaS (tenant.api.corpx.com) e Internet banking (client.api.corpx.com). A home deixa de cair no Início Rápido do tenant.
llms.txt / llms-full.txt roteiam as duas audiências. Não assuma um único base URL. Filtre o OpenAPI por x-audience (baas, ib ou ambos). Cada summary leva o prefixo [BaaS], [IB] ou [BaaS · IB].
Contrato da API não muda. Paths, PIN e travas continuam os do 2.74.0.
GET /v1/accounts/{accountId}/limits/available é rota nova. Devolve as quatro janelas da MT (singleTransfer, daytime, nighttime, monthly) com usedBrl/availableBrl para PIX, TED, boleto e transferência interna. GET /v1/accounts/{accountId}/pix/limitsnão muda: continua só os tetos do liquidante, sem used.
TED, boleto e interna passam a ter teto local só quando o staff grava no backoffice. Sem teto, o comportamento é o de hoje (fail-open). Transferência interna continua consultando o MySQL (limites_cliente); se lá houver teto e a operação couber, autoriza sem hold no ledger.
Limite por operador em GET|PUT|DELETE /v1/accounts/{accountId}/limits/operators/{document}: o dono fatia o teto da conta (available = min). Apertar vale na hora; afrouxar espera 6h. PIX só reserva localmente quando existe teto de operador — o liquidante continua barrando o teto da conta.
Recusa de PIX com Limite restante: R$ X alinha o used da janela atual. Não há sync periódico nem no GET.
PATCH /v1/backoffice/accounts/{accountId}/limits aceita pixOut no mesmo formato das outras operações. Sem teto local, PIX continua fail-open no ledger; a MT segue barrando o teto da conta.
Reserve de PIX avalia min(conta local, operador) quando o teto da conta existe. GET /pix/limitsnão muda.
used passa a ser um contador atômico por janela (account_limit_usage), não SUM dos holds. Vários PIX da mesma conta ao mesmo tempo enfileiram na linha da janela; o teto não fura. Holds ficam só para saga e idempotência.
POST /v1/accreditations/{id}/documents passa a exigir sizeBytes (tamanho real do PDF, no máximo 20 MB). O valor entra na assinatura da uploadUrl: o PUT tem que mandar exatamente esses bytes.
O POST só reserva o slot.GET mantém o kind em missingDocumentKinds e documents[].deliveryStatus fica pending_upload até o objeto existir no arquivo KYC com tamanho > 0 (e passar pela varredura, quando ela estiver ligada). uploadedAt só aparece quando deliveryStatus é delivered.
kind=other tem teto de 10 arquivos por accreditation (422 too_many_files). PDF acima de 20 MB devolve 413 file_too_large.
Aprovar sem o objeto exige override. Slot vazio responde 409 documents_incomplete; forceIncompleteDocuments + reason grava a trilha documentsOverride*.
Página de aceite BYO: se a checagem de risco estiver indisponível, o aceite devolve 503risk_check_unavailable. É retentável — o titular tenta de novo em instantes.
Pagamento PIX out e boleto enviados sem Idempotency-Key passam a ser deduplicados pelo conteúdo. Duas requisições idênticas (mesma conta, valor e destino) reusam o mesmo pagamento. Continua valendo mandar o header: pagamento legitimamente repetido precisa de chave própria.
biometry.evidenceId só entra na accreditation depois da verificação de conteúdo. Enquanto o arquivo estiver em quarentena ou recusado, o POST devolve 422evidence_not_approved.
Página de consent: identidade ainda não aprovada ou expirada devolve 409identity_not_approved / identity_stale e a jornada permanece pendente — o titular refaz a captura pelo mesmo link.
POST /v1/accounts/{accountId}/transfers/internal/by-document devolve 503beneficiary_check_unavailable quando não for possível confirmar o destino. Retente ou use /transfers/internal/by-bank-account.
A documentação de pix.out.completed e pix.out.failed passa a descrever o body HTTP que de fato enviamos. O envelope continua o mesmo (id, type, occurredAt, schemaVersion, environment, tenantId, accountId, data). Dentro de data sempre vêm paymentId, status, currency ("BRL"), description, originalTransactionId, initiatedAt e completedAt (RFC 3339 com fração de segundo), além de endToEnd, identifier e amount.
payer só aparece quando o banco liquidante enviou os dados da conta origem.payee pode trazer bankIspb e pixKey. Não enviamos reconciliationId nesses eventos.
O JSON de “webhook entregue” no painel é só o objeto data, não o POST completo. O type outbound é pix.out.completed — não o evento de timeline pix_out.confirmed.
A documentação de pix.in.completed, qrcode.paid / expired / cancelled, pix.refund.completed / failed e boleto.paid / failed passa a descrever o payload que de fato enviamos. Os exemplos antigos inventavam reconciliationId, originalEndToEnd/refundEndToEnd no refund que nós disparamos, txid/expiredAt no QR e error como objeto no boleto.
pix.refund.completed tem o mesmo shape de pix.out.completed. O E2E da devolução é endToEnd; a transação original é originalTransactionId. originalEndToEnd / refundEndToEnd existem só em pix.refund.received.
O JSON de “webhook entregue” no painel continua sendo só data, não o POST completo.
POST /v1/accounts/{accountId}/pix/keys recusa keyTypeemail e phone. A resposta é 422key_type_temporarily_unavailable. CPF, CNPJ e chave aleatória (random) continuam cadastráveis.
Listar e apagar chaves desses tipos não muda. Quem já tem email ou telefone na conta continua vendo e pode remover. PIX out para chave email/telefone também segue igual.
POST /v1/accreditations/consent/{cst} sem cookie de sessão devolve 403 session_invalid e não grava decisão. A jornada permanece em pending_consent.
POST /v1/accreditations/consent/{cst}/start responde 409 quando a jornada não está pendente ou já há captura em andamento.
consent_facial_failed é só falha de verificação de identidade. Recusa por risco ou dispositivo continua castle_deny. Recusa explícita do titular continua consent_declined.
GET /v1/accounts/{accountId}/transfers/internal/lookup/{document} passa a devolver maskedName e o mesmo valor em holderName. O primeiro nome sai inteiro; os demais tokens viram primeira letra + ***. holderDocument sai rasurado (***.***.***-** / CNPJ equivalente) — sem dígitos no body.
branch, accountNumber e accountStatus continuam no JSON. O POST by-document não muda.
POST /v1/accounts/{accountId}/exports aceita format: "xlsx". O arquivo Excel tem as mesmas colunas do CSV (incluindo pixKey). Se uma aba encher, o restante vai para Statement_2, Statement_3, …
O export deixa de cortar o extrato. O PDF não trunca mais em 10 mil linhas; o CSV não trunca em 2 milhões. O PDF continua ajustando só o período (a partir de 21/05/2026 e até 24h atrás).
Transferência interna para as contas operacionais de tarifa passa a aparecer como TARIFA, no extrato, no detalhe e no CSV/PDF, com o CNPJ da contraparte rasurado.
Quando o valor volta dessas contas, a descrição fica ESTORNO DE TARIFA.
Pagamento de comissão (descrição ou identifier com “comissão”) aparece como REPASSE DE COMISSÃO no crédito e ESTORNO DE REPASSE DE COMISSÃO no débito. Não vira evento fee.*.
Os webhooks fee.charged e fee.refunded usam as mesmas descrições TARIFA e ESTORNO DE TARIFA.
qrcode.paid de QR dinâmico passa a trazer endToEnd, payer e receivedAt. Em alguns pagamentos esses campos saíam vazios, embora o dinheiro já tivesse creditado.
pix.in.completed passa a sair junto nesses mesmos pagamentos. O par documentado (pix.in.completed + qrcode.paid) deixa de faltar o evento de crédito.
CSV e PDF do export de extrato passam a trazer pixKey, o mesmo campo de cada item do extrato: num crédito, a chave desta conta que recebeu; num débito, a chave de destino. No CSV a coluna entra no final, sem deslocar as demais.