Facturación
Consulta cómo se factura el uso de SpicyAPI en USD: cotizaciones, retenciones, cargos finales, fondos, límites de gasto y facturas.
Dinero, no créditos
Los precios se expresan en dólares estadounidenses: «$0.008 por imagen», «$0.042 por segundo de salida». Los fondos prepagados, las aportaciones promocionales y las líneas de crédito se denominan en dólares, pero un límite de crédito no es un saldo en efectivo.
Evitar un sistema de créditos es una decisión deliberada. Ese sistema añade una conversión entre «recarga X y recibe Y de bono» y «cuánto vale un crédito», lo que dificulta calcular el costo real por unidad. El precio que ves es el que pagas.
Cómo funciona el pago
- Primero añade fondos. Una cuenta nueva empieza con un saldo de $0 y no hay un nivel gratuito. Una tarea enviada antes de añadir fondos se rechaza con
40201y no tiene costo. - Al aceptar una tarea, se reserva su precio estimado. Esto se llama retención. El dinero sigue siendo tuyo, pero no puede pagar otra tarea al mismo tiempo.
- Si la tarea termina correctamente, pagas lo que realmente se utilizó, sin superar la retención. El importe restante vuelve a tu saldo.
- Las tareas fallidas o vencidas normalmente liberan toda la retención. Algunos rechazos de contenido se cobran al precio aceptado únicamente si la página del modelo informa expresamente de esa excepción. Consulta
settledycostpara conocer el cargo final. - Los límites de gasto de cada clave de API impiden que un script fuera de control vacíe tu saldo.
El resto de esta página explica cada paso en detalle.
Añadir fondos
Añade fondos en Facturación, dentro de la consola, con tarjeta, criptomonedas o transferencia manual cuando aparezca esa opción. También puedes activar la recarga automática para que los trabajos largos no se detengan cuando el saldo baje. El saldo pagado no vence; el crédito promocional vence en la fecha que aparece en Facturación.
Para ver los pasos, las opciones de pago, cuándo llegan los fondos y cómo funciona la recarga automática, consulta Configuración de la cuenta. Las recargas generalmente no se reembolsan en efectivo; la política de reembolsos detalla las excepciones, como un cargo duplicado.
Tres fases
Todas las tareas pasan por las mismas tres fases de facturación. No tienes que hacer nada en ellas; las describimos para que puedas interpretar tu historial de saldo con confianza.
holdsettlereleaseRetención
Al crear una tarea retenemos fondos para el uso estimado. El importe es exactamente el estimatedCost devuelto por createTask.
Una retención reserva las fuentes de financiación utilizadas por esa tarea; no es un cargo final. Los fondos prepagados reservados, las aportaciones disponibles o el crédito aprobado no pueden financiar otra tarea al mismo tiempo. Aparece como held en GET /api/v1/chat/credit y como «Retenido» en la consola.
La retención y el registro de la tarea se guardan en una sola transacción de base de datos. No existe un estado intermedio en el que haya una tarea sin retención, o al revés.
Liquidación o liberación
succeeded→ se liquida según el uso real, con el límite de la retención aceptada. Los fondos no utilizados se liberan a sus fuentes originales; no se cobra después ningún importe que supere esa retención.failed/expired→ normalmente se libera el importe completo. La página de un modelo puede indicar expresamente que ciertos falloscontent_rejectedse cobran al precio aceptado. Los registros históricoscanceledtambién liberan el importe completo, pero actualmente no se pueden cancelar las tareas aceptadas.
Cuando termina la liquidación, recordInfo informa settled: true y cost es definitivo. Mientras settled sea false, cost todavía puede cambiar.
Proceso de recuperación
Si nuestro proceso se interrumpe durante la ejecución, un proceso de recuperación encuentra las retenciones asociadas a tareas que ya alcanzaron un estado final y completa su liquidación o liberación según el resultado registrado.
La liquidación y la liberación comparten una clave de deduplicación, por lo que el ciclo de facturación de cada tarea termina exactamente una vez: los reintentos no pueden contabilizarlo dos veces.
Consulta la liquidación, además del estado de la tarea
Las tareas fallidas o vencidas normalmente liberan toda la retención. Algunos rechazos de contenido se cobran al precio aceptado únicamente si la página del modelo informa expresamente de esa excepción. Consulta settled y cost para conocer el cargo final. Un rechazo cobrado mantiene state: "failed" con errorCode: "content_rejected"; una vez liquidado, settled es true y cost es positivo. Los demás fallos y las tareas vencidas liberan automáticamente toda la retención.
Consultar tu saldo
La forma más rápida es la página Facturación de la consola: muestra tu saldo disponible, el importe retenido y todos los movimientos. Desde tu código, llama a:
GET /api/v1/chat/creditcurl https://api.spicyapi.ai/api/v1/chat/credit \
-H "Authorization: Bearer $SPICY_API_KEY"const res = await fetch('https://api.spicyapi.ai/api/v1/chat/credit', {
headers: { Authorization: `Bearer ${process.env.SPICY_API_KEY}` },
});
const body = await res.json();
if (body.code !== 200) throw new Error(`${body.code} ${body.msg}`);
const balance = body.data;
console.log(balance.funding ?? balance);import os, requests
res = requests.get(
"https://api.spicyapi.ai/api/v1/chat/credit",
headers={"Authorization": f"Bearer {os.environ['SPICY_API_KEY']}"},
)
body = res.json()
if body["code"] != 200:
raise RuntimeError(f'{body["code"]} {body["msg"]}')
balance = body["data"]
print(balance.get("funding", balance)){
"code": 200,
"msg": "success",
"data": {
"available": "128.42",
"held": "0.36",
"total": "128.78"
}
}| Campo | Significado |
|---|---|
available | Importe neto de la cuenta; puede ser negativo tras utilizar crédito aprobado y no basta por sí solo para comprobar si una tarea será aceptada |
held | Importe reservado para tareas en ejecución |
total | Suma de los dos anteriores |
Si los fondos disponibles para el modelo y el momento seleccionados no cubren la estimación, createTask devuelve 40201. El vencimiento del crédito, los límites agotados y un déficit por recuperación de pagos también pueden afectar la aceptación. No sustituyas las comprobaciones del servidor por una prueba en el cliente que solo compruebe el signo de available.
No necesitas consultar el saldo antes de cada generación: la aceptación de la tarea ya comprueba el saldo disponible y los límites de gasto.
En la API, los importes son cadenas sin el símbolo del dólar
«$0.008» es la forma en que esta página muestra los precios a los lectores. La API devuelve una cadena decimal sin símbolo de moneda: estimatedCost, cost y los tres campos del saldo tienen el formato "0.008": sin $, sin separadores y siempre en USD.
// Keep the exact decimal string for display
const usd = task.cost;Se utilizan cadenas en lugar de números JSON de forma deliberada: en la mayoría de los lenguajes, un número JSON se convierte en un float64, y 0.008 no tiene una representación binaria exacta. Si vas a registrar el importe en tu contabilidad, interprétalo como un decimal:
from decimal import Decimal
usd = Decimal(task["cost"]) # not float()Límites de gasto
Un límite de gasto establece cuánto dinero se puede gastar. Una tarea puede estar sujeta a hasta seis límites; el primero que se alcance rechaza la tarea con 40202, antes de crearla o retener fondos:
| Límite | Quién lo define | msg al alcanzarlo |
|---|---|---|
| Límite total de la clave | Tú, en la página de claves de API. Es el máximo para toda la vida de esa clave | This key has reached its total spend cap |
| Límite mensual de la clave | Tú, en la página de claves de API. Es el presupuesto de este mes calendario | This key has reached its monthly budget |
| Límite diario de la clave | Tú, en la página de claves de API. Las claves nuevas no tienen límite salvo que lo establezcas | This key has reached its daily spend cap |
| Límite diario del equipo | Propietarios, administradores y responsables de presupuesto, en la página del equipo. Solo se aplica a claves que pertenecen a un equipo | Workspace daily budget has been reached |
| Límite mensual del equipo | Igual que el anterior | Workspace monthly budget has been reached |
| Límite diario de la plataforma | Nosotros. Es nuestra protección general; tú no puedes aumentarlo | Platform quota for today is exhausted, please try again later |
Los límites diarios se reinician a las 00:00 UTC; los mensuales siguen el mes calendario en UTC y se reinician el día 1. El límite total nunca se reinicia. Si se alcanza el límite de la plataforma, reintenta después de las 00:00 UTC o contacta con soporte si sigue ocurriendo.
Una retención pendiente cuenta para todos los límites, totales, mensuales y diarios, hasta que se liquide la tarea, sin importar el día o el mes: el dinero todavía no se ha gastado, pero tampoco puede gastarse dos veces. Los límites de equipo se describen en Consola y equipos.
Un campo de límite vacío no significa lo mismo en todos los casos
- Al crear o editar una clave: dejar el límite vacío significa sin límite, igual que
0. Las claves nuevas no tienen límite salvo que lo establezcas. Vaciar un límite de una clave existente lo elimina; para conservarlo, deja un número en el campo. - Límites de gasto del equipo: un campo vacío conserva el valor actual;
0significa sin límite.
Los límites existen para protegerte. Un bucle fuera de control que consume un importe elevado en unas horas es un incidente habitual en este sector y casi siempre ocurre en una cuenta sin límite configurado.
Registro de movimientos
La página Facturación de la consola muestra todos los movimientos del saldo con etiquetas claras, como Recarga, Retenido, Cobrado y Devuelto. Al descargar la lista mediante Exportar CSV, la columna kind contiene uno de estos códigos estables:
| Tipo | Significado |
|---|---|
topup | Dinero que pagaste, añadido a tu saldo |
bonus | Importe adicional de una oferta de recarga, contabilizado por separado de lo que pagaste |
trial | Crédito de una campaña de prueba, separado de recargas y bonos |
hold | Importe estimado reservado al aceptar una tarea; no es un cargo |
settle | Cargo final de la tarea, incluido un rechazo de contenido cobrado según las condiciones del modelo; la parte no utilizada de la retención se devuelve |
refund | Devolución de toda la retención porque la tarea falló o agotó el tiempo de espera |
adjust | Corrección manual de nuestro equipo; siempre incluye la identidad del operador y un motivo |
chargeback | Saldo retirado tras una disputa de pago |
forfeit | Saldo restante al que renunciaste al cerrar tu cuenta |
grant_expire | Fondos promocionales no utilizados retirados después de vencer |
grant_revoke | Fondos promocionales no utilizados revocados |
El registro solo permite añadir entradas. Una entrada existente nunca se reescribe: la devolución de una retención crea una entrada nueva, no borra la original. Así se puede recalcular cualquier saldo desde el principio y demostrar por qué los números coinciden o no.
El crédito de bono se contabiliza por separado de lo que pagaste porque un reembolso del pago, es decir, dinero devuelto a tu tarjeta, solo cubre el importe pagado; un bono no tiene valor en efectivo. Esto no está relacionado con las entradas refund anteriores, que devuelven a tu saldo la retención de una tarea fallida.
Estos movimientos se conservan durante 10 años, separados del contenido de las tareas, para que sigan disponibles para conciliaciones y disputas mucho después de que se eliminen los prompts y resultados. Consulta Retención de datos.
Facturas e informes de uso
Puedes emitir dos documentos desde Facturación → Facturas en la consola, ambos descargables en PDF:
| Documento | Qué cubre | ¿Es un documento de pago? |
|---|---|---|
| Factura de pago | Una recarga que ya pagaste, por el importe cobrado | Sí. Es la que debes presentar para solicitar un reembolso de gastos |
| Informe de uso | Lo que realmente gastaste en un mes ya cerrado | No. Ese dinero se pagó al recargar; presentar ambos equivaldría a reclamar el mismo dinero dos veces |
Introduce tus datos una vez en la parte superior de Facturación → Facturas. Son obligatorios el nombre de tu empresa o el tuyo, la primera línea de la dirección, la ciudad y el país; el número fiscal, como VAT o GST, es opcional. Los datos se imprimen tal como los introduces: tú los proporcionas y nosotros no verificamos ninguno, incluido el número fiscal. Solo se pueden imprimir caracteres latinos, griegos y cirílicos, por lo que debes escribir el nombre de una empresa japonesa o coreana en su forma romanizada registrada. Un documento ya emitido conserva los datos del momento de emisión; las modificaciones posteriores solo afectan a documentos nuevos.
- Cada recarga pagada y cada mes cerrado se puede documentar una vez. Si el documento ya existe, descárgalo en lugar de emitir otro.
- Para corregir datos incorrectos, selecciona Volver a emitir: el documento anterior se marca como anulado y se genera otro con un número nuevo para el mismo concepto. Usa Anular sin sustituir únicamente cuando el documento corresponda a una recarga o mes incorrectos.
- Los estados de cuenta, más abajo en la misma página, son distintos: una instantánea mensual fija de todos los movimientos del saldo para tu contabilidad. No son recibos ni documentos fiscales.
El impuesto figura como cero: somos un proveedor estadounidense y no recaudamos ni remitimos VAT, GST o impuestos sobre ventas en tu nombre. Todos los documentos incluyen un aviso de inversión del sujeto pasivo, de modo que debes gestionar cualquier impuesto que corresponda donde estés. Una factura emitida nunca se edita: se anula y se vuelve a emitir, dejando registrados el motivo y el documento sustituto.
Unidades de facturación
Cada modelo tiene exactamente una unidad de facturación.
| Unidad | Significado | Qué campo de input aporta la cantidad |
|---|---|---|
per_image | Por imagen generada | El campo que declare el modelo; el valor predeterminado es 1 |
per_second | Por segundo de salida. Algunos endpoints redondean la duración hacia arriba a un bloque fijo; consulta Duración facturada en bloques completos | Consulta el quantityField y el esquema actuales; el campo estándar de duración es duration_seconds. No supongas que omitir la duración selecciona el nivel más corto. |
per_request | Por llamada, sin importar los parámetros | — |
per_1k_tokens | Por token. La unidad de la API es per_1k_tokens; el sitio web y price.perMillionTokens del catálogo muestran los mismos precios por millón de tokens. La entrada, la entrada en caché, las escrituras en caché y la salida pueden tener precios distintos | — |
No tienes que adivinar el nombre: quantityField del endpoint del catálogo lo indica para cada modelo; una cadena vacía significa una unidad por llamada.
Un modelo puede tener precios diferentes según el nivel. La resolución, la duración, las opciones de audio y los medios de referencia pueden afectar la cotización, según su esquema. pricing[].variant identifica un nivel de la tabla de precios; no hay un campo variant en el cuerpo de la solicitud. No supongas que esa etiqueta siempre se puede enviar como resolution, ni calcules todos los modelos como precio inicial × duración. Envía la entrada completa a jobs/quote para obtener la estimación exacta y el límite del cargo.
Consulta siempre la cantidad y el precio en el catálogo actualizado
No fijes en el código un campo de cantidad para toda una categoría de modelos. Un quantityField vacío significa una unidad de facturación por llamada; si no está vacío, consulta la estimación a partir del campo de entrada indicado. Los niveles, valores predeterminados y reglas de facturación pueden cambiar con el catálogo. El cargo tiene como límite el importe retenido al aceptar la tarea: los fondos no utilizados se liberan y no se cobra después nada por encima de esa retención.
Duración facturada en bloques completos
La mayoría de los modelos per_second factura la duración exacta que produce. Algunos facturan en bloques fijos: la duración medida se redondea hacia arriba al siguiente bloque completo antes de calcular el precio. Si el bloque es de 8 segundos, un clip de 6 y uno de 8 segundos cuestan lo mismo, mientras que uno de 9 segundos cuesta dos bloques. No todos los modelos por segundo funcionan así: solo se aplica a los endpoints que lo declaran y cada uno lo indica en su página.
También tienen algo en común que explica el redondeo de la cotización: obtienen la duración de un video que tú proporcionas, en lugar de un valor duration_seconds elegido por ti. Por eso no se conoce la duración del resultado hasta leer el clip. Su quantityField está vacío y el importe cotizado antes del envío corresponde al peor caso: el clip más largo que acepta el endpoint:
{
"estimatedCost": "0.96",
"maxCharge": "0.96",
"quantity": "32",
"unit": "per_second"
}Los importes son ilustrativos; aquí quantity es un máximo en segundos, no una medición. El importe cotizado es el importe retenido; el cargo final se calcula según la duración redondeada y nunca supera la retención. El resto se libera al liquidar la tarea, igual que en las tres fases anteriores.
La retención será mayor que el cargo final
Es el comportamiento esperado de estos endpoints, no un cobro excesivo. Entre la aceptación y la liquidación, tu saldo muestra el máximo retenido porque, hasta leer el clip, no se conoce la duración del resultado. Cuando se liquida la tarea se cobra la duración real redondeada al bloque y la diferencia vuelve automáticamente a tu saldo. El registro conserva ambos movimientos, por lo que siempre se pueden comparar hold y settle.
De aquí se derivan dos cosas que conviene prever:
- Calcula tu presupuesto con la cotización, no con tu clip. Hasta liquidar la tarea, el importe reservado es el máximo y cuenta para tus límites de gasto como cualquier otra retención.
- Un clip corto también cuesta un bloque completo. Recortar de 9 a 8 segundos puede reducir a la mitad el precio de un endpoint con bloques de 8 segundos; recortar de 8 a 5 no cambia nada.
Las unidades y los precios exactos aparecen en la página de precios y en la página de cada modelo.
Descuentos y promociones para clientes
Las ofertas pueden aplicarse a todos o a una cuenta concreta, en todos los modelos o solo en algunos. Las ofertas continuas permanecen activas hasta deshabilitarse; las temporales solo se aplican entre su inicio y fin reales. Los precios particulares se aplican cuando esa cuenta inicia sesión o solicita una cotización con su clave de API, y nunca se publican como precios de otro cliente.
Las ofertas no se acumulan. Se aplica automáticamente el menor precio al que tengas derecho. Para un cargo estándar de $10, una oferta pública del 10% y un descuento de cuenta del 20% dan un precio de $8, no un descuento compuesto de $7.20. Cuando una oferta termina o se deshabilita, las nuevas cotizaciones utilizan la mejor oferta restante que te corresponda, o el precio estándar si no queda ninguna.
Las ofertas de la página de inicio, el catálogo y las páginas de modelos te ayudan a comparar opciones. Obtén la estimación real de jobs/quote con tu identidad, modelo y entradas completas. Una cuenta regresiva no reserva un precio: actualiza la cotización cuando cambie una oferta, una entrada o un precio. Las tareas aceptadas conservan su precio fijado aunque la oferta termine durante la ejecución, y el cargo final no puede superar lo retenido al aceptarlas.
Las ofertas se aplican automáticamente a los cargos de uso de la API, no al importe que recargas, y no ofrecen devolución de dinero por recarga. Los ejemplos de presupuesto diario o mensual extrapolan el precio actual; una oferta temporal puede terminar antes que ese periodo de presupuesto, por lo que también debes comprobar su fecha de fin.
Fondos promocionales y líneas de crédito
GET /api/v1/chat/credit conserva available, held y total, y puede incluir un desglose funding. Las respuestas antiguas pueden omitir funding; que falte un dato no significa cero. Usa client.getBalance() en el SDK o spicyapi balance --json en la CLI.
funding.prepaidAvailableUsdcontiene los fondos disponibles prepagados o heredados sin restricciones;grantAvailableUsdsuma las aportaciones activas. Cada entrada degrantsindica importes otorgados, disponibles, retenidos y gastados, estado, inicio, vencimiento ymodelSlugs. Una lista de modelos vacía significa todos los modelos; de lo contrario, la aportación solo paga los modelos enumerados. La lista contiene hasta 100 aportaciones, prioriza las que tienen saldo restante o retenido y después las ordena de más reciente a más antigua.grantsHasMoreindica que hay más registros. No sustituyas el total de la cuenta por el subtotal de la lista visible.funding.creditdescribe una línea aprobada de pago diferido.limitUsdes su máximo,availableUsdes el crédito disponible que cumple las condiciones,usedUsdes el principal ya contabilizado y pendiente de pago,heldUsdes lo reservado para tareas aceptadas yexpiresAtes su vencimiento. El límite de crédito no es una recarga, una aportación ni un saldo en efectivo. Vencer, deshabilitarse o superar el límite restringe las nuevas solicitudes; la deuda existente sigue siendo pagadera.- Los fondos promocionales no se pueden retirar. Los descuentos fijan el precio de la solicitud; las aportaciones y el crédito determinan cómo se financia ese precio. Una aportación no reduce el precio de la tabla del modelo. Se aplican su alcance de modelos y su vigencia, y los importes no utilizados pueden vencer o revocarse. Las tareas fallidas y las reservas no utilizadas liberan los fondos a su fuente original; eso no reactiva una aportación vencida o revocada.
- Un
funding.cashShortfallUsdpositivo indica un déficit por recuperación externa de pagos. Las aportaciones y el crédito no pueden cubrirlo; las llamadas nuevas permanecen bloqueadas hasta cubrirlo. En cambio, unavailablenegativo puede reflejar el uso de crédito aprobado. No deduzcas un rechazo a partir de su signo ni lo sumes directamente al límite de crédito. El servidor comprueba las fuentes de fondos, la disponibilidad para el modelo, la vigencia y los límites de gasto.
Los importes siguen siendo cadenas decimales exactas en USD y las fechas usan RFC3339. Indica la zona horaria al mostrar fechas. La página de facturación de la consola muestra detalles de fondos y aportaciones; los cambios solo entran en vigor tras la aprobación manual de un administrador. Para preguntar por aportaciones o líneas de crédito, abre una conversación en Soporte dentro de la consola o escribe a support@spicyapi.ai. La API pública no ofrece operaciones de escritura para aumentar tu propia capacidad ni emitir aportaciones.
Uso de la clave de API actual
Para ver un gráfico del gasto por día y por modelo de toda tu cuenta o de un equipo, usa Facturación → Uso en la consola. El siguiente endpoint de la API informa únicamente sobre la clave que lo llama:
curl 'https://api.spicyapi.ai/api/v1/usage?from=2026-09-01&to=2026-09-06' \
-H "Authorization: Bearer $SPICY_API_KEY"Las fechas usan UTC [from,to), por lo que este ejemplo incluye del 1 al 5 de septiembre. Omite las fechas para consultar los últimos siete días, incluido hoy; el intervalo máximo es de 92 días. Los resultados pertenecen únicamente a la clave de API actual. No hay un parámetro para consultar otra clave ni un informe de toda la cuenta; usa chat/credit para el saldo de la cuenta.
data.totalCalls cuenta todas las tareas; data.totalSpend solo incluye cargos liquidados. days y models agrupan las mismas tareas por fecha de creación y modelo, con cadenas decimales exactas en USD. Se excluyen las retenciones pendientes y una liquidación tardía puede actualizar fechas anteriores. El historial de tareas oculto sigue incluido; se omiten los días sin llamadas. No sumes las dos agrupaciones.
Usa client.getUsage({ from, to }) en el SDK o spicyapi usage --from 2026-09-01 --to 2026-09-06 en la CLI. Este endpoint tiene su propio límite de solicitudes, más estricto; consulta Límites de solicitudes.
n8n
Usa los modelos de imagen, video, audio y chat de SpicyAPI en flujos de trabajo de n8n. Instala el nodo de la comunidad, importa las plantillas de HTTP Request o apunta la credencial de OpenAI de n8n a SpicyAPI para los nodos AI Agent.
Consola y espacios de trabajo
Qué hace cada página de la consola de SpicyAPI y cuándo usarla, y cómo los equipos comparten claves de API y límites de gasto mientras paga el propietario del equipo.

