Saltar al contenido

Contrato de campos (payload schema)

Descubrí el contrato con la API

La API expone el contrato de campos de su organización como JSON Schema en GET /v1/payload-schema/{ph|pj} (ver Referencia). Bajá el schema y validá su payload localmente antes de enviarlo para reducir round-trips de 422. Esta página complementa esa referencia con el "por qué" y estrategias de descubrimiento.

Qué define el contrato de campos

Cada organización configura sus propios campos obligatorios, opcionales y deshabilitados desde Configuración → Campos configurables del backoffice. La superficie de la API pública v1 espeja la del portal de onboarding: lo que el portal muestra/exige al consumidor es lo que la API acepta del integrador.

Esto significa que el contrato puede cambiar en cualquier momento cuando el área de cumplimiento ajusta la configuración de Campos configurables.

Cómo descubrir qué campos pide su organización

Además del endpoint de schema, hay otros caminos prácticos:

1. Pedir la configuración al área de cumplimiento

La forma más directa: pedíle a su área de cumplimiento (o a la persona que opera Configuración → Campos configurables en el backoffice) la lista de campos required actuales para PH y PJ. Esa lista es la verdad operativa.

2. Iterar contra el 422

El bulk POST devuelve 422 Unprocessable Entity con detalle por campo en dot-notation cuando algo falta o está mal. Una estrategia válida de descubrimiento es:

  1. Enviar un payload mínimo ({"type": 1, "human": {...}}).
  2. Leer los errores del 422.
  3. Corregir y repetir.
  4. Repetir hasta 201 Created.

Este método es bueno para entender el contrato real al primer pase pero no es sustituto de coordinar con cumplimiento: hay campos que sólo aparecen como required cuando otros tienen ciertos valores (por ejemplo, spouse.* solo es required si marital_status=married y la organización lo configuró así).

Estructura del payload

El payload del bulk POST tiene esta forma anidada (ver Flujo de integración para el detalle):

jsonc
{
  "type": 1,                          // 1=PH, 2=PJ
  "denomination": "...",              // opcional
  "onboarding_flow": "apertura-estandar", // opcional, slug del flujo (default si se omite)

  "human": {                          // requerido si type=1
    "...": "campos top-level del titular",
    "residential_address": { /* ... */ },
    "work_address": { /* ... */ },    // opcional
    "spouse": { /* ... */ },          // opcional
    "fatca": { /* ... */ },           // opcional
    "source_of_funds": { /* ... */ },
    "investor_questionnaire": { "responses": [ /* {question_id, option_id} */ ] }
  },

  "company": {                        // requerido si type=2
    "...": "campos top-level de la empresa",
    "fiscal_address": { /* ... */ },
    "real_address": { /* ... */ },    // opcional si coincide con la fiscal
    "fatca": { /* ... */ },
    "source_of_funds": { /* ... */ },
    "investor_questionnaire": { "responses": [ /* {question_id, option_id} */ ] }
  },

  "beneficial_ownership": [ /* UBOs, sólo PJ */ ],
  "cbus": [ /* {cbu_cvu, currency_id} */ ],
  "related_humans": [ /* cotitulares/apoderados — cada uno con la forma de "human" */ ]
}

Catálogos globales

Los campos que aceptan ids de tablas globales (países, condiciones IVA / Ganancias, tipos societarios, tipos de entidad CNV) se resuelven contra los catálogos globales, no contra la configuración particular de cada organización. Para obtener los valores válidos:

bash
curl -H "Authorization: Bearer $TOKEN" \
  https://compliance.quantian.ar/api/v1/catalogs/countries
curl -H "Authorization: Bearer $TOKEN" \
  https://compliance.quantian.ar/api/v1/catalogs/condicion_iva
curl -H "Authorization: Bearer $TOKEN" \
  https://compliance.quantian.ar/api/v1/catalogs/condicion_ganancias
curl -H "Authorization: Bearer $TOKEN" \
  https://compliance.quantian.ar/api/v1/catalogs/tipo_societario
curl -H "Authorization: Bearer $TOKEN" \
  https://compliance.quantian.ar/api/v1/catalogs/cnv_entity_types

Requiere ability accounts:read. Cada catálogo devuelve {data: [{id, ...}]} con los valores activos. Usá los id de la respuesta para poblar los campos country_id, condicion_iva_id, condicion_ganancias_id, tipo_societario_id, cnv_entity_type_id del payload.

El endpoint de schema

GET /v1/payload-schema/{accountType} (accountType ∈ {ph, pj}) devuelve un JSON Schema Draft 2020-12 del payload completo del bulk POST para ese tipo de cuenta. Los campos que su organización exige para completar el legajo se listan en x-quantian-required-for-completion (dentro de human/company). El schema no usa required a nivel de entidad: el bulk POST acepta payloads parciales y lo faltante se completa después durante el onboarding. Los campos *_id llevan la extensión x-quantian-catalog con el catálogo correspondiente; las dependencias condicionales (ej. spouse si marital_status=married) se expresan con if/then y se anotan con x-quantian-depends-on.

Para beneficiarios finales, la API pide una versión simplificada: solo las personas controlantes finales (beneficial_ownership.tree como lista plana de nodos kind: "human" con su participación), no la cadena societaria completa.

Validá su payload contra este schema con cualquier validador JSON Schema estándar antes de hacer el POST /v1/accounts.

Extensiones x-quantian-* del schema

ExtensiónSignificado
x-quantian-catalogEl campo referencia un catálogo global (ej. countries).
x-quantian-catalog-endpointEndpoint donde obtener los valores válidos (ej. /v1/catalogs/countries).
x-quantian-required-for-completion(en human/company) Campos que la organización exige para completar el legajo. No son required para crear.
x-quantian-depends-on{field, value}: la sección/campo aplica solo cuando otro campo toma ese valor.
x-quantian-validatorsValidadores extra del lado server (ej. cuit) que el schema no puede expresar.
x-quantian-min-age / x-quantian-max-ageRestricción de edad (en años) para un campo fecha.
x-quantian-sourceEl conjunto de valores válidos proviene de otra config (ej. preguntas del perfil de inversor).