{
  "openapi": "3.1.0",
  "info": {
    "title": "Galvida Credit API",
    "version": "1.4.0",
    "summary": "Cotizacion de credito automotriz LATAM por consulta, sin cuenta y sin planes.",
    "description": "Cotiza credito automotriz y responde la pregunta inversa (cuanto auto alcanza con un presupuesto) para Mexico, Colombia, Argentina, Chile y Peru. Amortizacion francesa, CAT real por TIR, pago final (balloon), auto usado como enganche, costo mensual adicional, esfuerzo sobre el ingreso y comparacion de plazos. MODELO DE COBRO: pago por consulta, sin planes, sin suscripcion y sin cuenta. Una llamada SIN X-API-Key recibe 3 consultas de descubrimiento gratis por IP y dia; al agotarlas la API responde HTTP 402 payment_required con el objeto accepts[] (formato x402) para que el agente resuelva el pago por su cuenta y reintente. Tambien se acepta saldo prepago con X-API-Key. Disenada para ser consumida por agentes: https://galvida.com/llms.txt",
    "contact": {
      "email": "soporte@galvida.com",
      "url": "https://galvida.com/api/"
    },
    "license": {
      "name": "Commercial",
      "url": "https://galvida.com/api/#precios"
    },
    "x-pricing": {
      "model": "pay-per-query",
      "unit_price_usd": 0.012,
      "volume_price_usd": 0.006,
      "volume_threshold": 100000,
      "minimum_charge_usd": 5.0,
      "free_discovery_per_ip_per_day": 3,
      "pricing_url": "https://galvida.com/api/pricing.json",
      "x402_manifest": "https://galvida.com/api/x402.json",
      "plans": "none",
      "account_required": false
    }
  },
  "servers": [
    {
      "url": "https://galvida.com/api/v1"
    }
  ],
  "security": [],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Opcional. Con clave se cobra contra el saldo prepago y no aplica el limite de descubrimiento por IP. Sin clave la llamada es anonima: 3 consultas gratis por IP y dia, luego HTTP 402 con accepts[]."
      },
      "X402Payment": {
        "type": "apiKey",
        "in": "header",
        "name": "X-PAYMENT",
        "description": "Pago por consulta en formato x402: el cliente firma el pago descrito en accepts[] y reenvia el comprobante en este header."
      }
    },
    "schemas": {
      "Usage": {
        "type": "object",
        "properties": {
          "plan": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": [
              "credits",
              "monthly"
            ]
          },
          "used": {
            "type": "integer"
          },
          "quota": {
            "type": "integer"
          },
          "remaining": {
            "type": [
              "integer",
              "null"
            ]
          },
          "period": {
            "type": "string"
          },
          "day": {
            "type": "string"
          },
          "day_used": {
            "type": "integer"
          },
          "daily_cap": {
            "type": "integer"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          },
          "usage": {
            "type": "object",
            "properties": {
              "plan": {
                "type": "string"
              },
              "mode": {
                "type": "string",
                "enum": [
                  "credits",
                  "monthly"
                ]
              },
              "used": {
                "type": "integer"
              },
              "quota": {
                "type": "integer"
              },
              "remaining": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "period": {
                "type": "string"
              },
              "day": {
                "type": "string"
              },
              "day_used": {
                "type": "integer"
              },
              "daily_cap": {
                "type": "integer"
              }
            }
          },
          "topup_url": {
            "type": "string"
          }
        }
      },
      "QuoteRequest": {
        "type": "object",
        "required": [
          "vehicle_price"
        ],
        "properties": {
          "country": {
            "type": "string",
            "enum": [
              "MX",
              "CO",
              "AR",
              "CL",
              "PE"
            ],
            "default": "MX",
            "description": "Pais. Define moneda, tasa y plazo por defecto."
          },
          "vehicle_price": {
            "type": "number",
            "description": "Precio del auto de contado. Max 1,000,000,000."
          },
          "down_payment_pct": {
            "type": "number",
            "default": 15,
            "description": "Enganche en efectivo, 0-99.99%."
          },
          "trade_in_value": {
            "type": "number",
            "default": 0,
            "description": "Auto usado entregado; se suma al enganche."
          },
          "term_months": {
            "type": "integer",
            "default": 48,
            "description": "Plazo 6-120 meses."
          },
          "annual_rate_pct": {
            "type": "number",
            "description": "Tasa anual. Si se omite usa la del pais."
          },
          "rate_type": {
            "type": "string",
            "enum": [
              "nominal",
              "effective"
            ]
          },
          "opening_fee_pct": {
            "type": "number",
            "default": 2,
            "description": "Comision de apertura, 0-20%."
          },
          "monthly_insurance": {
            "type": "number",
            "default": 0
          },
          "extra_monthly": {
            "type": "number",
            "default": 0,
            "description": "GPS, placas, tenencia, seguro adicional."
          },
          "balloon_pct": {
            "type": "number",
            "default": 0,
            "description": "Pago final / cuota balon, 0-80% del precio."
          },
          "income_monthly": {
            "type": "number",
            "description": "Ingreso mensual del cliente; activa effort_pct."
          },
          "compare_terms": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Plazos a comparar en la misma consulta, ej [36,48,60]."
          },
          "include_schedule": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "QuoteResult": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string"
          },
          "down_payment": {
            "type": "number",
            "description": "Enganche total = efectivo + auto usado."
          },
          "down_payment_cash": {
            "type": "number"
          },
          "trade_in_value": {
            "type": "number"
          },
          "principal": {
            "type": "number"
          },
          "opening_fee": {
            "type": "number"
          },
          "amount_financed": {
            "type": "number"
          },
          "balloon_amount": {
            "type": "number"
          },
          "balloon_pct": {
            "type": "number"
          },
          "monthly_rate_pct": {
            "type": "number"
          },
          "term_months": {
            "type": "integer"
          },
          "monthly_payment": {
            "type": "number",
            "description": "Cuota del credito, sin seguro ni extras."
          },
          "monthly_insurance": {
            "type": "number"
          },
          "monthly_extra": {
            "type": "number"
          },
          "monthly_total": {
            "type": "number",
            "description": "Lo que sale del bolsillo cada mes."
          },
          "total_interest": {
            "type": "number"
          },
          "total_paid": {
            "type": "number"
          },
          "total_cost_over_cash": {
            "type": "number",
            "description": "Sobrecosto contra pagar de contado."
          },
          "cat_pct": {
            "type": "number",
            "description": "CAT real por TIR, anualizado (1+r)^12-1."
          },
          "effort_pct": {
            "type": [
              "number",
              "null"
            ],
            "description": "Cuota / ingreso mensual, en %."
          },
          "effort_flag": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "healthy",
              "tight",
              "overextended",
              null
            ]
          },
          "tax_note": {
            "type": "string"
          },
          "amortization": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "AffordRequest": {
        "type": "object",
        "required": [
          "monthly_budget"
        ],
        "properties": {
          "country": {
            "type": "string",
            "enum": [
              "MX",
              "CO",
              "AR",
              "CL",
              "PE"
            ],
            "default": "MX"
          },
          "monthly_budget": {
            "type": "number",
            "description": "Lo que el cliente puede pagar al mes, todo incluido."
          },
          "down_payment_pct": {
            "type": "number",
            "default": 15
          },
          "trade_in_value": {
            "type": "number",
            "default": 0
          },
          "term_months": {
            "type": "integer"
          },
          "annual_rate_pct": {
            "type": "number"
          },
          "rate_type": {
            "type": "string",
            "enum": [
              "nominal",
              "effective"
            ]
          },
          "opening_fee_pct": {
            "type": "number",
            "default": 2
          },
          "monthly_insurance": {
            "type": "number",
            "default": 0
          },
          "extra_monthly": {
            "type": "number",
            "default": 0
          },
          "balloon_pct": {
            "type": "number",
            "default": 0
          }
        }
      },
      "AffordResult": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string"
          },
          "max_vehicle_price": {
            "type": "number",
            "description": "Precio maximo del auto que cabe en el presupuesto."
          },
          "down_payment_cash": {
            "type": "number"
          },
          "down_payment_total": {
            "type": "number"
          },
          "amount_financed": {
            "type": "number"
          },
          "opening_fee": {
            "type": "number"
          },
          "balloon_amount": {
            "type": "number"
          },
          "monthly_payment": {
            "type": "number"
          },
          "monthly_total": {
            "type": "number"
          },
          "budget_used_pct": {
            "type": "number"
          },
          "total_paid": {
            "type": "number"
          },
          "cat_pct": {
            "type": "number"
          },
          "capacity_for_debt": {
            "type": "number"
          }
        }
      },
      "Status": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "key_id": {
            "type": "string"
          },
          "plan": {
            "type": "string"
          },
          "mode": {
            "type": "string"
          },
          "channel": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "organic",
              "agent",
              null
            ]
          },
          "counter": {
            "type": "object",
            "properties": {
              "used": {
                "type": "integer"
              },
              "quota": {
                "type": "integer"
              },
              "remaining": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "percent": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "resets": {
                "type": "string",
                "enum": [
                  "never",
                  "monthly"
                ]
              }
            }
          },
          "today": {
            "type": "object"
          },
          "first_seen": {
            "type": [
              "string",
              "null"
            ]
          },
          "topup_url": {
            "type": "string"
          }
        }
      },
      "PaymentRequired": {
        "type": "object",
        "required": [
          "ok",
          "x402Version",
          "error",
          "accepts"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "x402Version": {
            "type": "integer",
            "example": 1
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "example": "payment_required"
              },
              "message": {
                "type": "string"
              }
            }
          },
          "pricing": {
            "type": "string",
            "format": "uri"
          },
          "free_discovery": {
            "type": "object",
            "properties": {
              "per_ip_per_day": {
                "type": "integer",
                "example": 3
              },
              "used_today": {
                "type": "integer"
              }
            }
          },
          "accepts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentOption"
            }
          }
        }
      },
      "PaymentOption": {
        "type": "object",
        "required": [
          "scheme",
          "unit_price_usd"
        ],
        "properties": {
          "scheme": {
            "type": "string",
            "enum": [
              "prepaid-key",
              "x402",
              "exact"
            ]
          },
          "network": {
            "type": "string",
            "example": "base"
          },
          "currency": {
            "type": "string",
            "example": "USDC"
          },
          "unit_price_usd": {
            "type": "number",
            "example": 0.012
          },
          "min_charge_usd": {
            "type": "number",
            "example": 5.0
          },
          "pay_to": {
            "type": "string"
          },
          "instructions": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      }
    },
    "responses": {
      "PaymentRequired": {
        "description": "La consulta se cobra por llamada y no hay descubrimiento gratis disponible. La respuesta es autosuficiente: incluye accepts[] con los metodos de pago, precio y destino de cobro.",
        "headers": {
          "X-Galvida-Free-Queries-Remaining": {
            "schema": {
              "type": "integer"
            },
            "description": "Consultas de descubrimiento restantes para esta IP hoy."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PaymentRequired"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/quote.php": {
      "post": {
        "operationId": "createQuote",
        "summary": "Cotiza un credito automotriz",
        "description": "Devuelve cuota, CAT real, costo total, esfuerzo sobre ingreso y tabla de amortizacion. Con compare_terms devuelve varios plazos en una sola consulta (1 consulta cobrada).\n\nSin X-API-Key la llamada es anonima: 3 consultas de descubrimiento gratis por IP y dia; al agotarlas responde 402 con accepts[] para autocobro.",
        "tags": [
          "credito"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cotizacion",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "request_id": {
                      "type": "string"
                    },
                    "api_version": {
                      "type": "string"
                    },
                    "input": {
                      "type": "object"
                    },
                    "result": {
                      "$ref": "#/components/schemas/QuoteResult"
                    },
                    "comparison": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "usage": {
                      "$ref": "#/components/schemas/Usage"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parametro invalido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Falta la API key o no es valida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "429": {
            "description": "Limite de 60 req/min",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {}
        ]
      },
      "get": {
        "operationId": "createQuoteGet",
        "summary": "Igual que POST, con parametros en querystring",
        "tags": [
          "credito"
        ],
        "parameters": [
          {
            "name": "api_key",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "vehicle_price",
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "down_payment_pct",
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "term_months",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "annual_rate_pct",
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cotizacion"
          }
        }
      }
    },
    "/afford.php": {
      "post": {
        "operationId": "createAffordability",
        "summary": "Cuanto auto alcanza con un presupuesto mensual",
        "description": "La pregunta inversa del nicho. Devuelve el precio maximo de auto que cabe en el presupuesto, el enganche necesario, el CAT y el porcentaje del presupuesto usado.\n\nSin X-API-Key la llamada es anonima: 3 consultas de descubrimiento gratis por IP y dia; al agotarlas responde 402 con accepts[] para autocobro.",
        "tags": [
          "credito"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AffordRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado de viabilidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "input": {
                      "type": "object"
                    },
                    "result": {
                      "$ref": "#/components/schemas/AffordResult"
                    },
                    "usage": {
                      "$ref": "#/components/schemas/Usage"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "El presupuesto no alcanza ni para seguro y cargos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {}
        ]
      }
    },
    "/status.php": {
      "get": {
        "operationId": "getStatus",
        "summary": "Contador de la cuenta (no gasta consulta)",
        "description": "Cuantas consultas llevas, cuantas quedan, porcentaje consumido, consumo de hoy y desde cuando existe la clave.",
        "tags": [
          "cuenta"
        ],
        "responses": {
          "200": {
            "description": "Estado de la cuenta",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            }
          },
          "401": {
            "description": "API key invalida"
          }
        }
      }
    },
    "/signup.php": {
      "post": {
        "operationId": "signup",
        "summary": "Prueba gratis (solo personas)",
        "description": "Emite una clave con 20 consultas de prueba, una sola vez, sin tarjeta. Requiere un navegador real: los scripts, SDK y agentes reciben 403 human_signup_only y se les dirige al prepago.",
        "tags": [
          "cuenta"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Clave emitida (se muestra una sola vez)"
          },
          "403": {
            "description": "Canal automatico: usar prepago"
          },
          "409": {
            "description": "Ese correo ya tiene clave"
          },
          "429": {
            "description": "3 altas por IP al dia"
          }
        }
      }
    },
    "/health.php": {
      "get": {
        "operationId": "health",
        "summary": "Diagnostico del despliegue (sin secretos)",
        "tags": [
          "cuenta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Estado del servicio"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "credito",
      "description": "Calculo y viabilidad"
    },
    {
      "name": "cuenta",
      "description": "Alta, saldo y estado"
    }
  ]
}
