Findo Score API
Este manual de integración describe cómo consultar Findo Score Express, una API de scoring crediticio en tiempo real. Cubre el flujo de autenticación, los servicios de consulta disponibles y los formatos de salida esperados.
Flujo de integración
La integración comienza solicitando un access_token con las credenciales provistas. En las consultas posteriores, ese token se envía en el header Authorization junto con el client_id.
Base URL
| Ambiente | BASE_URL | Uso |
|---|---|---|
| Producción | https://api.score.findo.com.ar | Ambiente productivo. |
| QA | https://qa.api.score.findo.com.ar | Ambiente de pruebas e integración. |
Los ejemplos de esta documentación usan el ambiente QA. Los identificadores personales y nombres mostrados están ofuscados; reemplazarlos por datos habilitados para el ambiente correspondiente. Para ejecutar contra producción, cambiar únicamente el valor de BASE_URL.
Endpoints
| Método | Endpoint | Uso | |
|---|---|---|---|
| POST | {BASE_URL}/v1/oauth/token | Obtención del access token. | |
| GET | {BASE_URL}/v1/express | Consulta Express por CUIT/CUIL. | |
| GET | {BASE_URL}/v1/express/dni | Consulta Express por DNI. |
Autenticación
Este endpoint devuelve el access token que debe enviarse en las consultas posteriores.
Endpoint
| Método | Path | Content-Type |
|---|---|---|
| POST | /v1/oauth/token | application/x-www-form-urlencoded |
Parámetros de body
| Parámetro | Tipo | Req. | Descripción |
|---|---|---|---|
| client_id | string | SÍ | Identificador de cliente provisto por Findo. |
| client_secret | string | SÍ | Secret de cliente provisto por Findo. |
Body 200 OK
| Campo | Tipo | Descripción |
|---|---|---|
| access_token | string | JWT firmado con RS256. Se envía en el header Authorization de cada consulta. |
| expires_in | integer | Validez del token en segundos (86400 = 24 hs). |
Ejemplo de autenticación
BASE_URL="https://qa.api.score.findo.com.ar" curl "${BASE_URL}/v1/oauth/token" \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id=<tu_client_id>' \ --data-urlencode 'client_secret=<tu_client_secret>'
{
"access_token": "eyJhbGciOiAiUlMyNTYi...",
"expires_in": 86400
}
Express por CUIT/CUIL
Consulta el score Express usando un CUIT/CUIL como identificador principal.
Solicitud
| Método | Path | Descripción |
|---|---|---|
| GET | /v1/express | Devuelve el score para el CUIT/CUIL consultado. |
Headers
| Header | Valor | Req. | Descripción |
|---|---|---|---|
| Authorization | <token> | SÍ | Access token obtenido desde /v1/oauth/token. |
| client_id | <tu_client_id> | SÍ | Identificador de cliente provisto por Findo. |
| Content-Type | application/json | SÍ | Formato de contenido enviado. |
Parámetros
| Nombre | Tipo | Req. | Descripción |
|---|---|---|---|
| legal_id | string | SÍ | CUIT o CUIL sin guiones ni espacios. Ej: <cuit_o_cuil> |
| phone_number | string | NO | Teléfono asociado a la consulta. Ej: <telefono> |
Body 200 OK
| Campo | Tipo | Descripción |
|---|---|---|
| request_id | string | Identificador único de la consulta. |
| status | string | Estado de la consulta. Valores posibles: COMPLETED. |
| findo_score | object | Resultado devuelto por el motor de scoring para el CUIT/CUIL consultado. |
| findo_score.request_id | string | Identificador de la consulta en el motor de scoring. |
| findo_score.findo_score | number | Score devuelto por el servicio. |
| findo_score.estimated_income | number | Ingreso estimado devuelto por el servicio. |
| findo_score.individual_data_report | object | Reporte de créditos con variables agregadas del historial financiero. |
| findo_score.positive_report | object | Variables positivas asociadas a comportamiento regular. |
| findo_score.negative_report | object | Variables negativas asociadas a mora o comportamiento irregular. Puede venir vacío. |
Ejemplo de consulta
BASE_URL="https://qa.api.score.findo.com.ar" curl \ "${BASE_URL}/v1/express?legal_id=<cuit_o_cuil>" \ --header 'Content-Type: application/json' \ --header 'Authorization: <token>' \ --header 'client_id: <tu_client_id>'
Ejemplo 200 OK
{
"request_id": "97ed5055-100d-42ce-8356-544185aab784",
"status": "COMPLETED",
"findo_score": {
"request_id": "6873536b-c0a5-4b25-b273-23aaaee0a380",
"findo_score": 3,
"estimated_income": 2.0,
"individual_data_report": {
"finantial_history_number_ent_1": 1.0,
"finantial_history_number_ent_3": 1.0,
"finantial_history_number_ent_6": 1.0,
"finantial_history_number_ent_9": 1.0,
"finantial_history_number_ent_12": 1.0,
"finantial_history_number_ent_18": 1.0,
"finantial_history_number_ent_24": 1.0,
"finantial_history_amount_total_due_3": 0.0,
"finantial_history_amount_total_due_6": 0.0,
"finantial_history_amount_total_due_9": 0.0,
"finantial_history_amount_total_due_12": 0.0,
"finantial_history_amount_total_due_18": 4.0,
"finantial_history_amount_total_due_24": 4.0,
"finantial_history_variation_amount_total_due_between_3_1": null,
"finantial_history_variation_amount_total_due_between_6_3": null,
"finantial_history_variation_amount_total_due_between_9_6": null,
"finantial_history_variation_amount_total_due_between_12_9": null,
"finantial_history_variation_amount_total_due_between_18_12": -100.0,
"finantial_history_variation_amount_total_due_between_24_18": 0.0
},
"positive_report": {
"finantial_history_max_sit_1": 0.0,
"finantial_history_max_sit_3": 0.0,
"finantial_history_max_sit_6": 0.0,
"finantial_history_max_sit_9": 0.0,
"finantial_history_max_sit_12": 0.0
},
"negative_report": {
"finantial_history_amount_sit345_18": 4.0,
"finantial_history_amount_sit345_24": 4.0,
"finantial_history_max_sit_18": 5.0,
"finantial_history_max_sit_24": 5.0
}
}
}
El ejemplo conserva las variables del sample de respuesta. La semántica detallada de cada variable se documenta en la referencia del informe.
Express por DNI
Consulta el score Express usando un DNI como identificador principal. Si el DNI está asociado a más de un CUIT/CUIL, el body incluirá más de un resultado.
Solicitud
| Método | Path | Descripción |
|---|---|---|
| GET | /v1/express/dni | Devuelve una lista de resultados asociados al DNI consultado. |
Headers
| Header | Valor | Req. | Descripción |
|---|---|---|---|
| Authorization | <token> | SÍ | Access token obtenido desde /v1/oauth/token. |
| client_id | <tu_client_id> | SÍ | Identificador de cliente provisto por Findo. |
| Content-Type | application/json | SÍ | Formato de contenido enviado. |
Parámetros
| Nombre | Tipo | Req. | Descripción |
|---|---|---|---|
| dni | string | SÍ | DNI sin puntos, guiones ni espacios. Ej: <dni> |
Body 200 OK
| Campo | Tipo | Descripción |
|---|---|---|
| request_id | string | Identificador único de la consulta por DNI. |
| status | string | Estado general de la consulta por DNI. Valores posibles: COMPLETED, PARTIAL, FAILURE. PARTIAL indica que el DNI resolvió a más de un CUIT/CUIL y falló al menos una consulta individual. |
| dni | string | DNI consultado. |
| results | array | Lista de consultas individuales por CUIT/CUIL asociadas al DNI. |
| results[].legal_id | string | CUIT/CUIL utilizado para ejecutar la consulta Express. |
| results[].name | string | Nombre asociado al CUIT/CUIL. |
| results[].request_id | string | Identificador único de la consulta individual. |
| results[].status | string | Estado de la consulta individual. Valores posibles: COMPLETED, FAILURE. |
| results[].findo_score | object | Resultado devuelto por el motor de scoring para ese CUIT/CUIL. Presente cuando la consulta individual termina en COMPLETED. |
| results[].findo_score.request_id | string | Identificador de la consulta en el motor de scoring. |
| results[].findo_score.findo_score | number | Score devuelto para ese CUIT/CUIL. |
| results[].findo_score.estimated_income | number | Ingreso estimado devuelto para ese CUIT/CUIL. |
| results[].findo_score.individual_data_report | object | Reporte de créditos con variables agregadas del historial financiero. |
| results[].findo_score.positive_report | object | Variables positivas asociadas a comportamiento regular. |
| results[].findo_score.negative_report | object | Variables negativas asociadas a mora o comportamiento irregular. Puede venir vacío. |
| results[].error | object | Detalle del error. Presente cuando la consulta individual termina en FAILURE. |
| results[].error.code | string | Código de error de la consulta individual. |
| results[].error.description | string | Descripción del error de la consulta individual. |
status resume el resultado de todas las consultas individuales: COMPLETED si todas completaron, PARTIAL si algunas completaron y otras fallaron, y FAILURE si ninguna completó.
Ejemplo de consulta
BASE_URL="https://qa.api.score.findo.com.ar" curl \ "${BASE_URL}/v1/express/dni?dni=<dni>" \ --header 'Content-Type: application/json' \ --header 'Authorization: <token>' \ --header 'client_id: <tu_client_id>'
Ejemplo 200 OK
{
"request_id": "bd370a97-bf03-4dc2-b04b-6a8ed4bea04a",
"status": "COMPLETED",
"dni": "<dni_ofuscado>",
"results": [
{
"legal_id": "<cuit_o_cuil_1>",
"name": "<nombre_ofuscado_1>",
"request_id": "7fd9896d-c88a-4d0a-8929-d54a1d149911",
"status": "COMPLETED",
"findo_score": {
"request_id": "6873536b-c0a5-4b25-b273-23aaaee0a380",
"findo_score": 3,
"estimated_income": 2.0,
"individual_data_report": {
"finantial_history_number_ent_1": 1.0,
"finantial_history_number_ent_3": 1.0,
"finantial_history_number_ent_6": 1.0,
"finantial_history_number_ent_9": 1.0,
"finantial_history_number_ent_12": 1.0,
"finantial_history_number_ent_18": 1.0,
"finantial_history_number_ent_24": 1.0,
"finantial_history_amount_total_due_3": 0.0,
"finantial_history_amount_total_due_6": 0.0,
"finantial_history_amount_total_due_9": 0.0,
"finantial_history_amount_total_due_12": 0.0,
"finantial_history_amount_total_due_18": 4.0,
"finantial_history_amount_total_due_24": 4.0,
"finantial_history_variation_amount_total_due_between_3_1": null,
"finantial_history_variation_amount_total_due_between_6_3": null,
"finantial_history_variation_amount_total_due_between_9_6": null,
"finantial_history_variation_amount_total_due_between_12_9": null,
"finantial_history_variation_amount_total_due_between_18_12": -100.0,
"finantial_history_variation_amount_total_due_between_24_18": 0.0
},
"positive_report": {
"finantial_history_max_sit_1": 0.0,
"finantial_history_max_sit_3": 0.0,
"finantial_history_max_sit_6": 0.0,
"finantial_history_max_sit_9": 0.0,
"finantial_history_max_sit_12": 0.0
},
"negative_report": {
"finantial_history_amount_sit345_18": 4.0,
"finantial_history_amount_sit345_24": 4.0,
"finantial_history_max_sit_18": 5.0,
"finantial_history_max_sit_24": 5.0
}
}
},
{
"legal_id": "<cuit_o_cuil_2>",
"name": "<nombre_ofuscado_2>",
"request_id": "d2c003fa-1951-4a39-afd2-7f41bedeb716",
"status": "COMPLETED",
"findo_score": {
"request_id": "6873536b-c0a5-4b25-b273-23aaaee0a380",
"findo_score": 3,
"estimated_income": 2.0,
"individual_data_report": {
"finantial_history_number_ent_1": 1.0,
"finantial_history_number_ent_3": 1.0,
"finantial_history_number_ent_6": 1.0,
"finantial_history_number_ent_9": 1.0,
"finantial_history_number_ent_12": 1.0,
"finantial_history_number_ent_18": 1.0,
"finantial_history_number_ent_24": 1.0,
"finantial_history_amount_total_due_3": 0.0,
"finantial_history_amount_total_due_6": 0.0,
"finantial_history_amount_total_due_9": 0.0,
"finantial_history_amount_total_due_12": 0.0,
"finantial_history_amount_total_due_18": 4.0,
"finantial_history_amount_total_due_24": 4.0,
"finantial_history_variation_amount_total_due_between_3_1": null,
"finantial_history_variation_amount_total_due_between_6_3": null,
"finantial_history_variation_amount_total_due_between_9_6": null,
"finantial_history_variation_amount_total_due_between_12_9": null,
"finantial_history_variation_amount_total_due_between_18_12": -100.0,
"finantial_history_variation_amount_total_due_between_24_18": 0.0
},
"positive_report": {
"finantial_history_max_sit_1": 0.0,
"finantial_history_max_sit_3": 0.0,
"finantial_history_max_sit_6": 0.0,
"finantial_history_max_sit_9": 0.0,
"finantial_history_max_sit_12": 0.0
},
"negative_report": {
"finantial_history_amount_sit345_18": 4.0,
"finantial_history_amount_sit345_24": 4.0,
"finantial_history_max_sit_18": 5.0,
"finantial_history_max_sit_24": 5.0
}
}
}
]
}
En cada elemento de results, findo_score conserva el mismo formato de objeto que el endpoint por CUIT/CUIL.
Estados y errores
El status HTTP indica el resultado a nivel protocolo. Cuando el endpoint devuelve un body con status: FAILURE, el campo error.code identifica el caso funcional.
En /v1/express/dni, el status superior resume la consulta por DNI. Cada elemento de results tiene su propio status porque representa una consulta Express individual.
Estados HTTP
| Status | Significado | Detalle |
|---|---|---|
| 200 | Consulta procesada. | El body exitoso se documenta en cada endpoint. En consultas por DNI, revisar también el campo status. |
| 400 | Solicitud inválida. | Parámetros faltantes o inválidos, client_id faltante/inválido o configuración de cliente inválida. |
| 401 | No autenticado. | Token ausente o no enviado en el header Authorization. |
| 403 | No autorizado. | Token inválido, expirado o no autorizado para ejecutar la consulta. |
| 404 | Ruta inexistente. | El path solicitado no existe para la versión de API utilizada. |
| 500 | Error interno. | Fallo interno. Reintentar más tarde o contactar soporte si persiste. |
Body de error
Cuando una consulta devuelve un error estructurado, el body tiene este formato.
| Campo | Tipo | Descripción |
|---|---|---|
| request_id | string | Identificador único de la consulta. |
| status | string | Estado del error. Valor posible: FAILURE. |
| error | object | Detalle del error. |
| error.code | string | Código de error. |
| error.description | string | Descripción del error. |
Ejemplo de error
{
"request_id": "97ed5055-100d-42ce-8356-544185aab784",
"status": "FAILURE",
"error": {
"code": "E02",
"description": "legal_id invalid"
}
}
Las tablas siguientes listan los errores accionables para la integración. Ante un 500, conservar el request_id para seguimiento.
Errores Express CUIT/CUIL
| HTTP | Código | Caso |
|---|---|---|
| 400 | E01 | client_id requerido o inválido. |
| 400 | E02 | legal_id inválido. |
| 400 | E03 | legal_id requerido. |
| 400 | E04 | Consulta duplicada. |
| 500 | - | Fallo interno. |
Errores Express DNI
| HTTP | Código | Caso |
|---|---|---|
| 400 | E01 | client_id requerido. |
| 400 | E02 | dni inválido. |
| 400 | E03 | dni requerido. |
| 500 | - | Fallo interno. |
| 200 | results[].error | Fallo en una consulta individual por CUIT/CUIL. El error se informa dentro del elemento correspondiente de results. |
Integrá en minutos
Este script de Python cubre el flujo completo: obtiene el access token con tus credenciales y consulta el score Express por CUIT/CUIL o por DNI. Podés usarlo como punto de partida para tu integración.
| Requisito | Detalle |
|---|---|
| Python | 3.8 o superior |
| requests | pip install requests |
| FINDO_CLIENT_ID | Variable de entorno con tu Client ID |
| FINDO_CLIENT_SECRET | Variable de entorno con tu Client Secret. Nunca hardcodear. |
export FINDO_BASE_URL="https://qa.api.score.findo.com.ar" export FINDO_CLIENT_ID="tu_client_id" export FINDO_CLIENT_SECRET="tu_client_secret"
import os import sys import requests BASE_URL = os.getenv("FINDO_BASE_URL", "https://qa.api.score.findo.com.ar") CLIENT_ID = os.getenv("FINDO_CLIENT_ID") CLIENT_SECRET = os.getenv("FINDO_CLIENT_SECRET") def validate_cuil(cuil): if not cuil.isdigit() or len(cuil) not in (10, 11): raise SystemExit("Invalid CUIL. Use digits only and a length of 10 or 11.") def validate_dni(dni): if not dni.isdigit() or len(dni) not in (7, 8): raise SystemExit("Invalid DNI. Use digits only and a length of 7 or 8.") def get_access_token(): if not CLIENT_ID or not CLIENT_SECRET: raise SystemExit("Missing env vars: FINDO_CLIENT_ID and FINDO_CLIENT_SECRET") response = requests.post( f"{BASE_URL}/v1/oauth/token", headers={"Content-Type": "application/x-www-form-urlencoded"}, data={"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}, ) response.raise_for_status() access_token = response.json().get("access_token") if not access_token: raise SystemExit("No access_token in response") return access_token def build_headers(access_token): return { "Content-Type": "application/json", "Authorization": access_token, "client_id": CLIENT_ID, } def get_express_score_by_cuil(access_token, cuil, phone_number=None): params = {"legal_id": cuil} if phone_number: params["phone_number"] = phone_number return requests.get( f"{BASE_URL}/v1/express", headers=build_headers(access_token), params=params ) def get_express_score_by_dni(access_token, dni): return requests.get( f"{BASE_URL}/v1/express/dni", headers=build_headers(access_token), params={"dni": dni}, ) if __name__ == "__main__": if len(sys.argv) < 3: raise SystemExit("Usage: python example.py cuil <cuil> [phone_number] | python example.py dni <dni>") mode = sys.argv[1] value = sys.argv[2] token = get_access_token() if mode == "cuil": validate_cuil(value) phone_number = sys.argv[3] if len(sys.argv) > 3 else None response = get_express_score_by_cuil(token, value, phone_number) elif mode == "dni": validate_dni(value) response = get_express_score_by_dni(token, value) else: raise SystemExit("Invalid mode. Use 'cuil' or 'dni'.") print("Status:", response.status_code) print("Body:", response.text) response.raise_for_status()
# Solo con CUIL python example.py cuil <cuit_o_cuil> # Con CUIL y teléfono (opcional) python example.py cuil <cuit_o_cuil> <telefono> # Por DNI python example.py dni <dni>