Verifika API

Autenticación

Todas las requests deben incluir tu API key en el header x-api-key. Obtén tu key desde el dashboard.

x-api-key: vfk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Cada llamada exitosa a analizar-comprobante consume 1 crédito. clasificar-ejemplo no consume créditos.

Modo Sandbox

Modo Sandbox — Prueba sin gastar créditos

Al generar tus llaves desde el dashboard, recibes automáticamente una llave de prueba con prefijo test_. Úsala exactamente igual que tu llave de producción: el motor detecta el prefijo y devuelve una respuesta simulada sin ejecutar Claude Vision ni consumir créditos.

Cómo activarlo

Reemplaza tu llave vfk_ por tu llave test_ y agrega el parámetro simulate_scenario al body:

x-api-key: test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Parámetro simulate_scenario

{
  "imageBase64":        "...",
  "mimeType":           "image/jpeg",
  "simulate_scenario":  "success"   // "success" | "review" | "fraud"
}

Escenarios disponibles

simulate_scenariopuntaje_combinadoaccion_recomendadastatus
"success" 99 PRE_APROBADO pre_aprobado
"review" 59 PENDIENTE_HUMANO pendiente
"fraud" 16 RECHAZADO rechazado

La respuesta sandbox incluye "sandbox": true y "scenario": "..." para que puedas identificarla en tus tests. La estructura del JSON es idéntica a producción.

Ejemplo — cURL Sandbox

curl -X POST \
  https://qztcjvslcyzrgxrdrptx.supabase.co/functions/v1/analizar-comprobante \
  -H "x-api-key: test_TU_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "imageBase64": "BASE64_AQUI",
    "mimeType": "image/jpeg",
    "simulate_scenario": "success"
  }'

Nota: simulate_scenario solo tiene efecto con llaves test_. Con llaves vfk_ de producción el parámetro es ignorado y se ejecuta el análisis real.

POST /functions/v1/analizar-comprobante

Analiza una imagen de comprobante bancario y retorna un veredicto con puntaje_combinado de 0–100. El score combina 50% determinista (campos presentes) + 50% IA visual. Score ≥50 → PRE_APROBADO. Score 50–65 con alertas → PENDIENTE_HUMANO. Score <50 → RECHAZADO.

Request body

{
  "imageBase64":        "string",  // requerido — imagen en base64
  "mimeType":           "string",  // "image/jpeg" | "image/png" | "image/webp"
  "cuenta_receptora":  {            // opcional — objeto preferido sobre campos planos
    "banco":   "string",
    "titular": "string",
    "numero":  "string",
    "tipo":    "string"   // "Ahorros" | "Corriente"
  },
  "banco_seleccionado": "string",  // opcional — alternativa plana si no envías cuenta_receptora
  "titular":            "string",  // opcional — alternativa plana
  "numero_cuenta":      "string",  // opcional — alternativa plana
  "monto_limite":       number,   // opcional — pagos ≥ este monto → acción RETENER
  "transfer_code":      "string",  // opcional — referencia bancaria del pagador (6–20 alfanumérico)
  "ejemplos_locales":   "array"    // opcional — [{texto_ocr: string}] biblioteca local (anónimos)
}

Response

{
  "ok":                       true,
  "status":                   "pre_aprobado",    // "pre_aprobado" | "pendiente" | "rechazado"
  "accion_recomendada":       "PRE_APROBADO",    // "PRE_APROBADO" | "PENDIENTE_HUMANO" | "RETENER" | "RECHAZADO"
  "puntaje_combinado":        76,                // 0–100. detScore(0–50) + round(aiScore/2)(0–50)
  "puntaje_deterministico":   38,                // 0–50. campos presentes: logo, ref, fecha, monto, beneficiario
  "banco":                    "Banco Agrícola",
  "monto":                    "$150.00",
  "coincidencias": {
    "cuenta":  "match",           // "match" | "mismatch" | "inconclusive"
    "titular": "match",           // comparación normalizada (sin tildes, case-insensitive)
    "banco":   "match"
  },
  "metadata_imagen": {
    "formato":                    "jpeg",
    "software":                   null,             // nombre del software si EXIF lo contiene
    "dimensiones":               "1080x1920px",
    "datetime_exif":              null,
    "software_edicion_detectado": false            // true → rechazo automático (Photoshop, GIMP, etc.)
  },
  "rechazo_automatico":        false,             // true si imagen ilegible, alterada o EXIF de edición
  "razon_rechazo":             null,              // descripción si rechazo_automatico=true
  "instruccion_usuario":       "Comprobante pre-aprobado. Puedes proceder con el pedido.",
  "senales_de_alerta":         ["..."],
  "creditos_restantes":        24
}

Ejemplo — cURL

curl -X POST \
  https://qztcjvslcyzrgxrdrptx.supabase.co/functions/v1/analizar-comprobante \
  -H "x-api-key: vfk_TU_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "imageBase64": "BASE64_AQUI",
    "mimeType": "image/jpeg",
    "banco_seleccionado": "Banco Agrícola",
    "titular": "María González",
    "numero_cuenta": "770000849870",
    "tipo_cuenta": "Ahorros",
    "transfer_code": "ABC12345"
  }'

Ejemplo — JavaScript

const response = await fetch(
  'https://qztcjvslcyzrgxrdrptx.supabase.co/functions/v1/analizar-comprobante',
  {
    method: 'POST',
    headers: {
      'x-api-key': 'vfk_TU_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      imageBase64: base64Image,
      mimeType: 'image/jpeg',
      banco_seleccionado: 'Banco Agrícola',
      titular: 'María González',
      numero_cuenta: '770000849870',
      tipo_cuenta: 'Ahorros',
      transfer_code: 'ABC12345',  // opcional
    }),
  }
);
const result = await response.json();
console.log(result.veredicto, result.puntaje, result.business_verdict);
POST /functions/v1/clasificar-ejemplo

Extrae banco y texto OCR de una imagen de comprobante y lo guarda en tu Biblioteca de Patrones. No consume créditos.

Request body

{
  "imageBase64": "string",  // requerido
  "mimeType":    "string"   // "image/jpeg" | "image/png"
}

Response

{
  "banco":     "Banco Agrícola",
  "texto_ocr": "...",
  "guardado":  true,
  "id":        "uuid"
}

Códigos de error

CódigoErrorDescripción
401api_key_invalidaAPI key incorrecta o inactiva
402sin_creditosSin créditos disponibles — comprar más
400Imagen requeridaFalta el campo imageBase64
400formato_codigo_invalidotransfer_code fuera del rango 6–20 caracteres alfanuméricos
500Error internoError del servidor — reintentar