Pular para o conteúdo

POST /vasp/customers

Cadastra cliente final do VASP (PF ou PJ)

Enrollment de cliente final. O documento entra em document (CPF ou CNPJ em texto, que o servidor canoniza e confere) ou em document_hash (SHA-256 do documento, que continua aceito); envie um dos dois. Se vierem os dois e divergirem, a resposta é 422 DOCUMENT_HASH_MISMATCH, e document tem precedência no cálculo do índice.

O servidor não guarda o documento em claro (LGPD). Com document, guarda só um índice cego e a cifra do valor. Só com document_hash, o servidor não tem o documento para cifrar e, por isso, não consegue exibi-lo. legal_name_hash segue em SHA-256.

Suporta replay idempotente via header Idempotency-Key. Escopo exigido: vasp:customers:write.

Item Valor
Método POST
Caminho /vasp/customers
URL https://crypto-api.sentinexrisk.com/api/v1/vasp/customers
Grupo VASP - Clientes
operationId createVASPCustomer
Versão do contrato 8.5.1

Chave de API do tenant no header X-API-Key (esquema ApiKeyAuth). A chave identifica o tenant e carrega os escopos; não existe header de tenant. Detalhes em Autenticação.

Nome Em Tipo Obrigatório Descrição
Idempotency-Key header string não Mesma chave + corpo idêntico = replay idempotente (200 com idempotent_replay=true); mesma chave + corpo diferente = 409. Até 255 caracteres.

Corpo obrigatório.

Tipo de mídia application/json.

Schema VASPCustomerCreateRequest, do tipo objeto.

Envie o documento do titular em document (texto) ou em document_hash (SHA-256); um dos dois é obrigatório. document_hash continua aceito para quem já integra por ele, mas, sozinho, não permite exibir o documento. Se vierem os dois e divergirem, a resposta é 422 DOCUMENT_HASH_MISMATCH.

Campo Tipo Obrigatório Descrição
client_id string (uuid) não Opcional. Id do cliente Sentinex que é o mesmo titular: o id devolvido por POST /clients, o mesmo que a análise KYT recebe como client_id. É gravado uma vez e não tem rota de alteração. Sem ele, o KYC externo deste cliente (convite e push) responde 403 client_link_required. UUID zero ou texto que não é UUID responde 400 invalid_client_id; cliente que não é desta empresa responde 422 client_not_found.
external_id string sim Id do cliente no seu sistema. Padrão: letras, números, ponto, underscore, dois-pontos, hífen. Até 128 caracteres.
type string sim Valores: PF, PJ.
document_hash string não SHA-256 hex do CPF/CNPJ, com prefixo sha256 opcional. Continua aceito. Envie document_hash ou document; um dos dois é obrigatório. Só com document_hash, o servidor não tem o documento para cifrar e não consegue exibi-lo em tela nem em laudo. Se vier junto de document e divergir, a resposta é 422 DOCUMENT_HASH_MISMATCH. Neste campo, nunca envie o documento em claro: para isso existe document.
document string não Opcional. CPF ou CNPJ do titular em texto, com ou sem pontuação (o CNPJ pode ser numérico ou alfanumérico). O servidor canoniza o valor (CPF só com os 11 dígitos; CNPJ em maiúsculas e sem pontuação) e confere os dígitos verificadores. O servidor não guarda o documento em claro: guarda só um índice cego, calculado com uma chave da empresa mantida fora do banco, que serve para buscar e comparar, e a cifra do valor, para exibição a quem tem permissão. Não é SHA-256 sem sal. document tem precedência no cálculo do índice. document_hash continua aceito; envie um dos dois. Se vierem os dois e divergirem, a resposta é 422 DOCUMENT_HASH_MISMATCH. O documento nunca é devolvido em resposta. Os exemplos deste contrato usam documentos fictícios. De 11 a 32 caracteres. Só de escrita: a API nunca devolve este campo. Exemplo: 123.456.789-01.
document_country string não ISO-3166 alpha-2 (default BR).
legal_name_hash string não SHA-256 hex do nome/razão social (opcional).
trade_name string não Até 255 caracteres.
incorporation_date string (date) não YYYY-MM-DD (PJ).
country string não ISO-3166 alpha-2 (default BR).
state string não Até 255 caracteres.
kyc_tier string não Default STANDARD. Valores: SIMPLIFIED, STANDARD, ENHANCED.
kyc_completed_at string (date-time) não
external_kyc_provider string não Até 255 caracteres.
external_kyc_reference_url string não URL https absoluta (máx. 2048 chars).
risk_classification string não Default MEDIUM. Valores: LOW, MEDIUM, HIGH, CRITICAL.
tags lista de string não Até 50 itens.
attributes objeto não JSON livre (máx. 16 KB). Chaves/valores com identificadores pessoais em claro (cpf, cnpj, email, phone, nomes) são rejeitados com 400.
consent_data_share boolean não
consent_data_share_at string (date-time) não
source string não Default api.
source_event_id string não Até 255 caracteres.
Janela do terminal
curl -X POST "https://crypto-api.sentinexrisk.com/api/v1/vasp/customers" \
-H "X-API-Key: $SENTINEX_API_KEY" \
-H "Idempotency-Key: <Idempotency-Key>" \
-H "Content-Type: application/json" \
-d @corpo.json

O arquivo corpo.json segue o schema do corpo acima.

Status Descrição
200 Replay idempotente (mesma Idempotency-Key + mesmo corpo)
201 Cliente criado

Replay idempotente (mesma Idempotency-Key + mesmo corpo)

Tipo de mídia application/json.

Tipo objeto.

Campo Tipo Obrigatório Descrição
success boolean não
idempotent_replay boolean não
data objeto (VASPCustomer) não Projeção retornada pelos endpoints /vasp/customers.
data.id string não Id do cliente, no formato UUID.
data.tenant_id string (uuid) não
data.client_id string ou null não Vínculo com o cliente Sentinex, no formato UUID; nulo quando a matrícula não o informou.
data.external_id string não
data.type string não Valores: PF, PJ.
data.document_country string não
data.trade_name string não
data.incorporation_date string (date-time) ou null não
data.country string não
data.state string não
data.kyc_tier string não Valores: SIMPLIFIED, STANDARD, ENHANCED.
data.kyc_completed_at string (date-time) ou null não
data.external_kyc_provider string não
data.external_kyc_reference_url string não
data.risk_classification string não Valores: LOW, MEDIUM, HIGH, CRITICAL.
data.tags lista de string não
data.attributes objeto não
data.consent_data_share boolean não
data.consent_data_share_at string (date-time) ou null não
data.screening_status string não
data.receita_status string não
data.source string não
data.source_event_id string não
data.created_at string (date-time) não
data.updated_at string (date-time) não

Cliente criado

Tipo de mídia application/json.

Tipo objeto.

Campo Tipo Obrigatório Descrição
success boolean não
data objeto (VASPCustomer) não Projeção retornada pelos endpoints /vasp/customers.
data.id string não Id do cliente, no formato UUID.
data.tenant_id string (uuid) não
data.client_id string ou null não Vínculo com o cliente Sentinex, no formato UUID; nulo quando a matrícula não o informou.
data.external_id string não
data.type string não Valores: PF, PJ.
data.document_country string não
data.trade_name string não
data.incorporation_date string (date-time) ou null não
data.country string não
data.state string não
data.kyc_tier string não Valores: SIMPLIFIED, STANDARD, ENHANCED.
data.kyc_completed_at string (date-time) ou null não
data.external_kyc_provider string não
data.external_kyc_reference_url string não
data.risk_classification string não Valores: LOW, MEDIUM, HIGH, CRITICAL.
data.tags lista de string não
data.attributes objeto não
data.consent_data_share boolean não
data.consent_data_share_at string (date-time) ou null não
data.screening_status string não
data.receita_status string não
data.source string não
data.source_event_id string não
data.created_at string (date-time) não
data.updated_at string (date-time) não

Estes são os códigos que o contrato declara para esta operação. Os limites que valem para toda a API, antes da autenticação, estão em Limites de requisição.

Status Descrição
400 Corpo JSON ilegível (texto em error), ou campos inválidos (invalid_customer, invalid_client_id, invalid_idempotency_key). Respondem invalid_customer o corpo sem document nem document_hash e o document com dígito verificador inválido.
401 A chave de API não autenticou a requisição, e nenhuma camada adiante rodou. error.code é missing_api_key (nenhuma chave em X-API-Key nem em Authorization: Bearer snxc_...) ou invalid_api_key (chave desconhecida, revogada ou expirada). Quando a plataforma não consegue verificar a chave, a resposta é 503 com api_key_verification_unavailable, e não 401: repita com backoff.
402 Conta sem direito comercial (TRIAL_EXPIRED): trial vencido, trial sem data ou empresa sem contrato. A requisição NÃO foi processada; uma triagem recusada assim é transação não triada, nunca aprovada.
403 Acesso recusado antes da operação, nesta ordem de camadas: o escudo de borda recusa travessia de diretório na URL (ErroTexto); a chave é recusada pelo IP de origem (api_key_ip_not_allowed); o ambiente da chave não é aceito por esta implantação (api_key_environment_required ou api_key_environment_not_allowed); a conta não pode usar a API (TenantAccessRefusalResponse: empresa_SUSPENDED, empresa_NOT_OPERATIONAL, API_ACCESS_DISABLED ou empresa_ACCESS_DENIED); a chave não tem o escopo da rota (insufficient_scope, com o escopo na mensagem). Não repita sem corrigir a causa.
404 Com chave válida, o caminho ou o método não corresponde a operação servida por esta implantação (error.code route_not_found). Confira método, caminho e o prefixo /api/v1.
409 external_id ou Idempotency-Key já existem (customer_already_exists, KYT_IDEMPOTENCY_CONFLICT)
413 Corpo acima de 1 MiB, recusado pelo escudo de borda antes da autenticação (code BODY_TOO_LARGE). Nada foi processado.
422 client_id não identifica cliente desta empresa (client_not_found), ou document e document_hash vieram juntos e divergem (DOCUMENT_HASH_MISMATCH). Nada foi gravado.
429 Limite de requisições atingido; nada foi processado. Formas, pela camada que recusou: limite da chave (ErrorResponseCoded, api_key_rate_limit_exceeded, 60 por minuto quando a chave não define outro valor, Retry-After: 60); limite global por hora (ErroLimite, retry_after 3600 e Retry-After: 3600); escudo de borda por IP (ErroLimite: RATE_LIMIT_HARD acima de 1.000 por minuto, com 300 segundos; IP_BANNED no bloqueio temporário; e a rajada com intervalo menor que 50 ms, que vem sem Retry-After e sem retry_after). A busca de clientes tem limite próprio (error rate_limited, com retry_after e detail) e o laudo também (error RATE_LIMIT_EXCEEDED, 120 por hora por IP, Retry-After: 3600). No sandbox, chamadas VASP autenticadas também usam sandbox_simulator_rate_limit_exceeded: 60 por minuto por key, 300 por minuto por empresa e 10.000 por dia UTC por empresa. Essa recusa inclui Retry-After, X-RateLimit-Limit e X-RateLimit-Remaining: 0. Espere o Retry-After quando ele vier.
500 Falha inesperada. A mensagem é genérica de propósito; guarde o X-Request-ID da resposta para o suporte e repita com espera.
503 API de cadastro ou transação da requisição indisponível; nenhum cliente foi criado. As camadas anteriores à operação também respondem 503, nada processado: limitador por IP ou da empresa sem contagem (ErroTexto), estado da conta (empresa_ACCESS_STATE_UNAVAILABLE) e limitador da chave (rate_limit_unavailable) e verificação da chave (api_key_verification_unavailable).

Corpo JSON ilegível (texto em error), ou campos inválidos (invalid_customer, invalid_client_id, invalid_idempotency_key). Respondem invalid_customer o corpo sem document nem document_hash e o document com dígito verificador inválido.

Tipo de mídia application/json.

Tipo um de: ErrorResponseCoded, ErroTexto.

Campo Tipo Obrigatório Descrição
success boolean sim Exemplo: false.
error objeto sim
error.code string sim Exemplo: missing_api_key.
error.message string sim Exemplo: X-API-Key header required.
Campo Tipo Obrigatório Descrição
success boolean sim Valores: false.
error string sim Exemplo: Carteira não encontrada..

A chave de API não autenticou a requisição, e nenhuma camada adiante rodou. error.code é missing_api_key (nenhuma chave em X-API-Key nem em Authorization: Bearer snxc_...) ou invalid_api_key (chave desconhecida, revogada ou expirada). Quando a plataforma não consegue verificar a chave, a resposta é 503 com api_key_verification_unavailable, e não 401: repita com backoff.

Resposta compartilhada ErroChaveNaoAutenticada do contrato.

Tipo de mídia application/json.

Schema ErrorResponseCoded, do tipo objeto.

Envelope de erro codificado (middlewares de API key e erros de negócio da superfície VASP). Trate error.code como contrato estável; error.message é texto livre.

Campo Tipo Obrigatório Descrição
success boolean sim Exemplo: false.
error objeto sim
error.code string sim Exemplo: missing_api_key.
error.message string sim Exemplo: X-API-Key header required.

Conta sem direito comercial (TRIAL_EXPIRED): trial vencido, trial sem data ou empresa sem contrato. A requisição NÃO foi processada; uma triagem recusada assim é transação não triada, nunca aprovada.

Resposta compartilhada TenantAccessPaymentRequired do contrato.

Tipo de mídia application/json.

Schema TenantAccessRefusalResponse, do tipo objeto.

Campo Tipo Obrigatório Descrição
success boolean sim Valores: false.
error string sim Exemplo: Seu período de teste terminou. Fale com a Sentinex Risk para estender o teste ou contratar um plano..
code string sim Valores: TRIAL_EXPIRED, TENANT_SUSPENDED, TENANT_NOT_OPERATIONAL, API_ACCESS_DISABLED, TENANT_ACCESS_DENIED, TENANT_ACCESS_STATE_UNAVAILABLE.
details objeto não
details.reason string não Presente em TRIAL_EXPIRED. Valores: TRIAL_WITHOUT_END_DATE, TRIAL_ENDED, POC_TRIAL_RETIRED, DEMO_WITHOUT_COMMERCIAL_ACCESS, NO_COMMERCIAL_ACCESS.
details.trial_ends_at string (date-time) não Presente em TRIAL_EXPIRED quando o trial tem data.
details.lifecycle_state string não Presente em empresa_NOT_OPERATIONAL.

Acesso recusado antes da operação, nesta ordem de camadas: o escudo de borda recusa travessia de diretório na URL (ErroTexto); a chave é recusada pelo IP de origem (api_key_ip_not_allowed); o ambiente da chave não é aceito por esta implantação (api_key_environment_required ou api_key_environment_not_allowed); a conta não pode usar a API (TenantAccessRefusalResponse: empresa_SUSPENDED, empresa_NOT_OPERATIONAL, API_ACCESS_DISABLED ou empresa_ACCESS_DENIED); a chave não tem o escopo da rota (insufficient_scope, com o escopo na mensagem). Não repita sem corrigir a causa.

Resposta compartilhada ErroAcessoNegado do contrato.

Tipo de mídia application/json.

Tipo um de: ErrorResponseCoded, TenantAccessRefusalResponse, ErroTexto.

Campo Tipo Obrigatório Descrição
success boolean sim Exemplo: false.
error objeto sim
error.code string sim Exemplo: missing_api_key.
error.message string sim Exemplo: X-API-Key header required.
Campo Tipo Obrigatório Descrição
success boolean sim Valores: false.
error string sim Exemplo: Seu período de teste terminou. Fale com a Sentinex Risk para estender o teste ou contratar um plano..
code string sim Valores: TRIAL_EXPIRED, TENANT_SUSPENDED, TENANT_NOT_OPERATIONAL, API_ACCESS_DISABLED, TENANT_ACCESS_DENIED, TENANT_ACCESS_STATE_UNAVAILABLE.
details objeto não
details.reason string não Presente em TRIAL_EXPIRED. Valores: TRIAL_WITHOUT_END_DATE, TRIAL_ENDED, POC_TRIAL_RETIRED, DEMO_WITHOUT_COMMERCIAL_ACCESS, NO_COMMERCIAL_ACCESS.
details.trial_ends_at string (date-time) não Presente em TRIAL_EXPIRED quando o trial tem data.
details.lifecycle_state string não Presente em empresa_NOT_OPERATIONAL.
Campo Tipo Obrigatório Descrição
success boolean sim Valores: false.
error string sim Exemplo: Carteira não encontrada..

Com chave válida, o caminho ou o método não corresponde a operação servida por esta implantação (error.code route_not_found). Confira método, caminho e o prefixo /api/v1.

Resposta compartilhada ErroRotaNaoEncontrada do contrato.

Tipo de mídia application/json.

Schema ErrorResponseCoded, do tipo objeto.

Envelope de erro codificado (middlewares de API key e erros de negócio da superfície VASP). Trate error.code como contrato estável; error.message é texto livre.

Campo Tipo Obrigatório Descrição
success boolean sim Exemplo: false.
error objeto sim
error.code string sim Exemplo: missing_api_key.
error.message string sim Exemplo: X-API-Key header required.

external_id ou Idempotency-Key já existem (customer_already_exists, KYT_IDEMPOTENCY_CONFLICT)

Tipo de mídia application/json.

Schema ErrorResponseCoded, do tipo objeto.

Envelope de erro codificado (middlewares de API key e erros de negócio da superfície VASP). Trate error.code como contrato estável; error.message é texto livre.

Campo Tipo Obrigatório Descrição
success boolean sim Exemplo: false.
error objeto sim
error.code string sim Exemplo: missing_api_key.
error.message string sim Exemplo: X-API-Key header required.

Corpo acima de 1 MiB, recusado pelo escudo de borda antes da autenticação (code BODY_TOO_LARGE). Nada foi processado.

Resposta compartilhada ErroCorpoAcimaDoLimite do contrato.

Tipo de mídia application/json.

Schema ErroTextoComCodigo, do tipo objeto.

Envelope de erro com a mensagem em texto em error e o código estável em code, na raiz do corpo. Na API de KYT aparece no corpo acima de 1 MiB (BODY_TOO_LARGE, 413) e na leitura do módulo contratado que não pôde ser feita (MODULE_STORE_UNAVAILABLE, 503).

Campo Tipo Obrigatório Descrição
success boolean sim Valores: false.
error string sim
code string sim Exemplo: BODY_TOO_LARGE.

client_id não identifica cliente desta empresa (client_not_found), ou document e document_hash vieram juntos e divergem (DOCUMENT_HASH_MISMATCH). Nada foi gravado.

Tipo de mídia application/json.

Schema ErrorResponseCoded, do tipo objeto.

Envelope de erro codificado (middlewares de API key e erros de negócio da superfície VASP). Trate error.code como contrato estável; error.message é texto livre.

Campo Tipo Obrigatório Descrição
success boolean sim Exemplo: false.
error objeto sim
error.code string sim Exemplo: missing_api_key.
error.message string sim Exemplo: X-API-Key header required.

Limite de requisições atingido; nada foi processado. Formas, pela camada que recusou: limite da chave (ErrorResponseCoded, api_key_rate_limit_exceeded, 60 por minuto quando a chave não define outro valor, Retry-After: 60); limite global por hora (ErroLimite, retry_after 3600 e Retry-After: 3600); escudo de borda por IP (ErroLimite: RATE_LIMIT_HARD acima de 1.000 por minuto, com 300 segundos; IP_BANNED no bloqueio temporário; e a rajada com intervalo menor que 50 ms, que vem sem Retry-After e sem retry_after). A busca de clientes tem limite próprio (error rate_limited, com retry_after e detail) e o laudo também (error RATE_LIMIT_EXCEEDED, 120 por hora por IP, Retry-After: 3600). No sandbox, chamadas VASP autenticadas também usam sandbox_simulator_rate_limit_exceeded: 60 por minuto por key, 300 por minuto por empresa e 10.000 por dia UTC por empresa. Essa recusa inclui Retry-After, X-RateLimit-Limit e X-RateLimit-Remaining: 0. Espere o Retry-After quando ele vier.

Resposta compartilhada ErroLimiteDeRequisicoes do contrato.

Header Tipo Descrição
Retry-After integer Segundos a esperar antes de repetir. Vem nos 429 dos limitadores (salvo a rajada do escudo) e no 503 de transação que conflitou (1 segundo).
X-RateLimit-Limit integer Teto da janela do limitador que respondeu, quando ele informa.
X-RateLimit-Remaining integer Requisições restantes na janela, quando o limitador informa.

Tipo de mídia application/json.

Tipo um de: ErrorResponseCoded, ErroLimite.

Campo Tipo Obrigatório Descrição
success boolean sim Exemplo: false.
error objeto sim
error.code string sim Exemplo: missing_api_key.
error.message string sim Exemplo: X-API-Key header required.
Campo Tipo Obrigatório Descrição
success boolean sim Valores: false.
error string sim Exemplo: Too many requests. Please try again later..
retry_after integer não Mínimo: 1. Exemplo: 3600.
code string não Exemplo: RATE_LIMIT_HARD.
reference string não Identificador curto do bloqueio, para citar ao suporte.
detail string não

Falha inesperada. A mensagem é genérica de propósito; guarde o X-Request-ID da resposta para o suporte e repita com espera.

Resposta compartilhada ErroInterno do contrato.

Tipo de mídia application/json.

Schema ErroTexto, do tipo objeto.

Envelope de erro com a mensagem em texto no campo error, sem código. É o formato dos handlers de cadastro, carteira, webhooks, ledger e leituras regulatórias, da recuperação de falha inesperada (500), da indisponibilidade das camadas de borda (503) e da recusa do escudo de borda por padrão de ataque (403). Ramifique pelo status HTTP; a mensagem é texto livre e pode mudar.

Campo Tipo Obrigatório Descrição
success boolean sim Valores: false.
error string sim Exemplo: Carteira não encontrada..

API de cadastro ou transação da requisição indisponível; nenhum cliente foi criado. As camadas anteriores à operação também respondem 503, nada processado: limitador por IP ou da empresa sem contagem (ErroTexto), estado da conta (empresa_ACCESS_STATE_UNAVAILABLE) e limitador da chave (rate_limit_unavailable) e verificação da chave (api_key_verification_unavailable).

Header Tipo Descrição
Retry-After integer Segundos a esperar antes de repetir. Vem nos 429 dos limitadores (salvo a rajada do escudo) e no 503 de transação que conflitou (1 segundo).

Tipo de mídia application/json.

Tipo um de: ErroTexto, TenantAccessRefusalResponse, ErrorResponseCoded.

Campo Tipo Obrigatório Descrição
success boolean sim Valores: false.
error string sim Exemplo: Carteira não encontrada..
Campo Tipo Obrigatório Descrição
success boolean sim Valores: false.
error string sim Exemplo: Seu período de teste terminou. Fale com a Sentinex Risk para estender o teste ou contratar um plano..
code string sim Valores: TRIAL_EXPIRED, TENANT_SUSPENDED, TENANT_NOT_OPERATIONAL, API_ACCESS_DISABLED, TENANT_ACCESS_DENIED, TENANT_ACCESS_STATE_UNAVAILABLE.
details objeto não
details.reason string não Presente em TRIAL_EXPIRED. Valores: TRIAL_WITHOUT_END_DATE, TRIAL_ENDED, POC_TRIAL_RETIRED, DEMO_WITHOUT_COMMERCIAL_ACCESS, NO_COMMERCIAL_ACCESS.
details.trial_ends_at string (date-time) não Presente em TRIAL_EXPIRED quando o trial tem data.
details.lifecycle_state string não Presente em empresa_NOT_OPERATIONAL.
Campo Tipo Obrigatório Descrição
success boolean sim Exemplo: false.
error objeto sim
error.code string sim Exemplo: missing_api_key.
error.message string sim Exemplo: X-API-Key header required.