SDK oficiales
SDK oficiales para cinco lenguajes
Instala un paquete y llama a modelos de imagen, video y audio desde tu propio servidor. El SDK se encarga de la autenticación y de esperar los resultados: tú solo escribes la solicitud y lees la respuesta.
Lo que el SDK hace por ti
Tú escribes una sola llamada. El SDK autentica la solicitud, sube tus archivos, espera el resultado y te lo devuelve como datos tipados.
- Tu códigoUna sola llamada
- SDK oficialAutentica solicitudes, sube archivos y espera resultados
- Modelos de imagen, video y audioLos mismos modelos y precios que la web
Ideal para
- Servicios de backendGenera contenido desde tu propia API o cola de trabajos.
- Scripts y procesos por lotesCrea muchas tareas desde una hoja de cálculo o un trabajo programado.
- Apps con servidorGuarda la clave en el servidor y envía los archivos terminados a tus usuarios.
Empieza en tres pasos
- Paso 1
Crea una clave de API
Genera una en la consola y guárdala como SPICY_API_KEY en tu servidor.
- Paso 2
Instala el paquete
Elige tu lenguaje más abajo y ejecuta la línea de instalación.
- Paso 3
Crea una tarea y lee el resultado
Envía un prompt, espera la tarea y guarda el archivo que devuelve.
Elige tu lenguaje
Cada SDK se publica en el registro principal de su lenguaje y usa la misma API. Cambia de pestaña para ver la línea de instalación y una solicitud completa.
TypeScript
@spicyapi/sdkRequiere Node.js 22.13+
Tu servidor crea tareas y guarda resultados. Instalar, exportar la clave, ejecutar.
npm install @spicyapi/sdk
export SPICY_API_KEY="injected from your secret manager"import { randomUUID } from "node:crypto";
import { SpicyClient } from "@spicyapi/sdk";
const client = new SpicyClient();
const model = await client.getModel("MODEL_ID_FROM_CATALOG");
const task = await client.run(
{ model: model.model, input: { prompt: "A cinematic night portrait" } },
{ idempotencyKey: randomUUID() },
);
console.log(task.state, task.output?.assets?.[0]?.url);Python
spicyapiRequiere Python 3.11+
La misma secuencia en Python: consultar la cotización, crear la tarea y esperar a que llegue a un estado final.
pip install spicyapi
export SPICY_API_KEY="injected from your secret manager"import uuid
from spicyapi import SpicyClient, output_assets
client = SpicyClient() # reads SPICY_API_KEY from the environment
model = client.get_model("MODEL_ID_FROM_CATALOG")
quote = client.quote_task(
model=model["model"],
input_data={"prompt": "A cinematic night portrait"},
)
print(quote["estimatedCost"], quote["maxCharge"]) # decide before you spend
task = client.create_task(
model=model["model"],
input_data={"prompt": "A cinematic night portrait"},
idempotency_key=str(uuid.uuid4()),
quote_id=quote["quoteId"],
expected_cost=quote["estimatedCost"],
)
final = client.wait_for_terminal(task["taskId"])
for asset in output_assets(final):
print(asset["url"])Go
github.com/spicyapi-ai/spicy-goRequiere Go 1.23+
Solo biblioteca estándar, así que tu grafo de módulos no crece. Disponible ya con go get.
go get github.com/spicyapi-ai/spicy-go
export SPICY_API_KEY="injected from your secret manager"client, err := spicy.New(spicy.Options{}) // reads SPICY_API_KEY from the environment
if err != nil {
return err
}
request := spicy.CreateTaskInput{
Model: "MODEL_ID_FROM_CATALOG",
Input: map[string]any{"prompt": "A cinematic night portrait"},
}
quote, err := client.Quote(ctx, request)
if err != nil {
return err
}
request.QuoteID = quote.QuoteID
request.ExpectedCost = quote.EstimatedCost
// Store this next to your own record of the job before sending it: its whole
// purpose is to still be there after the crash that lost the response.
key, err := spicy.NewIdempotencyKey()
if err != nil {
return err
}
task, err := client.CreateTask(ctx, request, key, spicy.CreateTaskOptions{})
if err != nil {
return err
}
final, err := client.WaitForTerminal(ctx, task.TaskID, spicy.WaitOptions{})
if err != nil {
return err
}
for _, asset := range final.ReadyAssets() {
log.Println(asset.URL)
}PHP
spicyapi/spicyapiRequiere PHP 8.1+, ext-json, ext-hash
Arrays asociativos y argumentos con nombre, sin ninguna dependencia.
composer require spicyapi/spicyapiuse SpicyApi\SpicyClient;
$client = new SpicyClient(); // reads SPICY_API_KEY from the environment
$quote = $client->quote('MODEL_ID_FROM_CATALOG', ['prompt' => 'A cinematic night portrait']);
printf("at most %s\n", $quote['maxCharge']); // decide before you spend
$task = $client->createTask(
model: $quote['model'],
input: ['prompt' => 'A cinematic night portrait'],
idempotencyKey: SpicyClient::idempotencyKey(),
quoteId: $quote['quoteId'],
expectedCost: $quote['estimatedCost'],
);
$final = $client->waitForTerminal($task['taskId']);
foreach (SpicyClient::readyAssets($final) as $asset) {
echo $asset['url'], "\n";
}Java
ai.spicyapi:spicyapi-java:0.1.0Requiere Java 17+, Jackson
Records y Jackson; run() hace la creación y la espera de una vez.
<dependency>
<groupId>ai.spicyapi</groupId>
<artifactId>spicyapi-java</artifactId>
<version>0.1.0</version>
</dependency>SpicyClient client = SpicyClient.builder().apiKeyFromEnvironment().build();
CreateTaskRequest request = CreateTaskRequest.of(
"MODEL_ID_FROM_CATALOG",
Map.of("prompt", "A cinematic night portrait"));
TaskQuote quote = client.quote(request); // free; reserves nothing
System.out.println("this will cost at most " + quote.maxCharge());
TaskRecord task = client.run( // createTask + waitForTerminal
request.withQuote(quote), UUID.randomUUID().toString());
// Transcription and similar endpoints answer in text and return no files at all.
task.outputText().ifPresent(System.out::println);
for (TaskAsset asset : task.assets()) {
asset.url().ifPresent(System.out::println);
}Qué pasa después de enviar
La generación de imagen y video sigue en marcha cuando la llamada de creación ya ha respondido. Guarda el ID de la tarea y deja que un webhook, o una consulta de estado con límite de tiempo, te avise cuando termine.
- createTaskEnvía con una clave de idempotencia: la misma generación solo se acepta una vez.
- taskIdLa respuesta vuelve al instante mientras la tarea sigue en marcha.
- Webhook / recordInfoRecibe primero un webhook firmado; usa consultas de estado acotadas solo para recuperar el resultado.
- output.assetsURLs listas para usar. Copia lo que quieras conservar.
Llamadas desde un navegador o una app móvil
Una clave incluida en una app cliente queda expuesta a sus usuarios. Mantenla en tu servidor: @spicyapi/proxy añade la credencial a las solicitudes de tu frontend, de modo que la app nunca la ve.
- Clave dentro de la appCualquiera puede leerla y gastar tu saldo.
- App con la clave dentro
- SpicyAPI
- Clave en tu servidorLa app habla con tu servidor y el proxy añade la clave.
- Navegador o móvil
- Tu servidor + proxy
- SpicyAPI
npm install @spicyapi/proxy// app/api/spicy/proxy/route.ts
export { GET, POST } from "@spicyapi/proxy/nextjs";
export const runtime = "nodejs";Antes de salir a producción
- 01Confirmar la disponibilidad actual.
- 02Validar los campos exactos de la página.
- 03Mantener la clave API en el servidor.
- 04Mostrar la estimación antes de enviar.
- 05Guardar taskId fuera de la sesión del navegador.
- 06Verificar la firma webhook o el límite de comprobaciones.
- 07Tratar una tarea aceptada como no cancelable.
Soluciona errores comunes
Casi todos los problemas del principio son uno de estos tres. Cada tarjeta muestra lo que ves y lo único que debes cambiar.
- 401
Clave de API no válida
A la API no llegó ninguna clave, o llegó una incorrecta. Define SPICY_API_KEY en el mismo entorno donde se ejecuta tu código.
- espera
La tarea sigue en curso
Un video puede tardar unos minutos. Espera con un límite de tiempo o usa un webhook. Si reenvías sin la misma Idempotency-Key, se crea una segunda tarea de pago.
- enlace
El enlace del resultado caducó
Los enlaces de descarga duran poco. Pide un enlace nuevo para la tarea en lugar de guardar el anterior.
