Manual de integración

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.

Flujo de autenticación de API Sequence diagram: Cliente autentica con Auth Server y luego llama al Scoring Server con el token. Cliente Auth Server /v1/oauth/token Scoring Server /v1/express POST /v1/oauth/token { client_id, client_secret } access_token (JWT) GET /v1/express · GET /v1/express/dni Authorization: <access_token> · client_id: <tu_client_id> scoring response Solicitud Retorno

Base URL

AmbienteBASE_URLUso
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étodoEndpointUso
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.
Endpoint de autenticación

Autenticación

Este endpoint devuelve el access token que debe enviarse en las consultas posteriores.

Endpoint

MétodoPathContent-Type
POST /v1/oauth/token application/x-www-form-urlencoded

Parámetros de body

ParámetroTipoReq.Descripción
client_id string Identificador de cliente provisto por Findo.
client_secret string Secret de cliente provisto por Findo.

Body 200 OK

CampoTipoDescripció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

cURL
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>'
200 · JSON
{
  "access_token": "eyJhbGciOiAiUlMyNTYi...",
  "expires_in":   86400
}
Endpoint de consulta

Express por CUIT/CUIL

Consulta el score Express usando un CUIT/CUIL como identificador principal.

Solicitud

MétodoPathDescripción
GET /v1/express Devuelve el score para el CUIT/CUIL consultado.

Headers

HeaderValorReq.Descripción
Authorization <token> Access token obtenido desde /v1/oauth/token.
client_id <tu_client_id> Identificador de cliente provisto por Findo.
Content-Type application/json Formato de contenido enviado.

Parámetros

NombreTipoReq.Descripción
legal_id string 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

CampoTipoDescripció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

cURL
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

200 · JSON
{
  "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.

Endpoint de consulta

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étodoPathDescripción
GET /v1/express/dni Devuelve una lista de resultados asociados al DNI consultado.

Headers

HeaderValorReq.Descripción
Authorization <token> Access token obtenido desde /v1/oauth/token.
client_id <tu_client_id> Identificador de cliente provisto por Findo.
Content-Type application/json Formato de contenido enviado.

Parámetros

NombreTipoReq.Descripción
dni string DNI sin puntos, guiones ni espacios.
Ej: <dni>

Body 200 OK

CampoTipoDescripció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

cURL
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

200 · JSON
{
  "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

StatusSignificadoDetalle
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.

CampoTipoDescripció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

400 · JSON
{
  "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

HTTPCódigoCaso
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

HTTPCódigoCaso
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.
Quick start

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.

Requisitos
RequisitoDetalle
Python3.8 o superior
requestspip install requests
FINDO_CLIENT_IDVariable de entorno con tu Client ID
FINDO_CLIENT_SECRETVariable de entorno con tu Client Secret. Nunca hardcodear.
Variables de entorno
bash
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"
example.py
Python
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()
Ejecución
bash
# 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>