Официальные SDK
Официальные SDK для пяти языков
Установите один пакет и вызывайте модели изображений, видео и аудио со своего сервера. Аутентификацию и ожидание результата берёт на себя SDK — вам остаётся написать запрос и прочитать ответ.
Что SDK делает за вас
Вы пишете один вызов функции. SDK подписывает запрос, загружает файлы, дожидается результата и возвращает его в виде типизированных данных.
- Ваш кодОдин вызов функции
- Официальный SDKПодписывает запросы, грузит файлы, ждёт результат
- Модели для изображений, видео и аудиоТе же модели и цены, что на сайте
Подходит для
- Бэкенд-сервисыГенерируйте медиа прямо в своём API или очереди задач.
- Скрипты и пакетная обработкаСоздавайте много задач из таблицы или по расписанию.
- Приложения с серверомХраните ключ на сервере, а готовые файлы отдавайте пользователям.
Начните за три шага
- Шаг 1
Создайте API-ключ
Создайте его в консоли и сохраните на сервере как SPICY_API_KEY.
- Шаг 2
Установите пакет
Выберите свой язык ниже и выполните команду установки.
- Шаг 3
Создайте задачу и получите результат
Отправьте промпт, дождитесь завершения задачи и сохраните возвращённый файл.
Выберите язык
Каждый SDK опубликован в основном реестре своего языка и работает с тем же API. Переключайте вкладки, чтобы увидеть команду установки и полный пример запроса.
TypeScript
@spicyapi/sdkТребуется Node.js 22.13+
Ваш сервер создаёт задачи и хранит результаты. Установить, экспортировать ключ, запустить.
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
spicyapiТребуется Python 3.11+
Тот же порядок действий, но по-питоновски: оценка, создание, ожидание конечного состояния.
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-goТребуется Go 1.23+
Только стандартная библиотека, так что граф модулей не разрастается. Доступен сразу через 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/spicyapiТребуется PHP 8.1+, ext-json, ext-hash
Ассоциативные массивы и именованные аргументы, без единой зависимости.
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.0Требуется Java 17+, Jackson
Записи и Jackson; run() делает создание и ожидание за один вызов.
<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);
}Что происходит после отправки
Генерация изображений и видео продолжается и после того, как вызов создания вернул ответ. Сохраните ID задачи, а о завершении узнайте через вебхук или ограниченную по времени проверку статуса.
- createTaskОтправляйте с ключом идемпотентности: одна генерация принимается ровно один раз.
- taskIdОтвет приходит сразу, а задача продолжает выполняться.
- Webhook / recordInfoПредпочитайте подписанный вебхук; ограниченный опрос используйте только для восстановления.
- output.assetsГотовые ссылки. То, что нужно сохранить, копируйте к себе.
Вызовы из браузера или мобильного приложения
Ключ, встроенный в клиентское приложение, доступен его пользователям. Храните его на сервере: @spicyapi/proxy добавляет учётные данные к запросам вашего фронтенда, поэтому приложение их не видит.
- Ключ внутри приложенияЛюбой может его прочитать и потратить ваш баланс.
- Приложение с ключом внутри
- SpicyAPI
- Ключ на вашем сервереПриложение обращается к вашему серверу, а прокси подставляет ключ.
- Браузер или телефон
- Ваш сервер + прокси
- SpicyAPI
npm install @spicyapi/proxy// app/api/spicy/proxy/route.ts
export { GET, POST } from "@spicyapi/proxy/nextjs";
export const runtime = "nodejs";Перед запуском
- 01Проверить текущую доступность модели.
- 02Проверить точные поля со страницы модели.
- 03Хранить API-ключ только на сервере.
- 04Показать оценку до отправки.
- 05Сохранить taskId вне браузерной сессии.
- 06Проверить подпись webhook или ограничение запросов статуса.
- 07Считать принятую задачу неотменяемой.
Частые ошибки и как их исправить
Почти все проблемы на старте — одна из этих трёх. На каждой карточке: что вы видите и что нужно изменить.
- 401
Недействительный API-ключ
В API пришёл неверный ключ или никакой. Задайте SPICY_API_KEY в том же окружении, где запускается ваш код.
- wait
Задача ещё выполняется
Видео может генерироваться несколько минут. Ждите с ограничением по времени или используйте вебхук. Повторная отправка без того же Idempotency-Key создаст вторую платную задачу.
- ссылка
Ссылка на результат устарела
Ссылки для скачивания живут недолго. Запросите у задачи свежую ссылку, а не храните старую.
