Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 0.1.1 instead.
Reason given by maintainers: Superseded by 0.1.1

spicyapi

Official Python SDK for SpicyAPI — image, video and text models behind one API.

Get a key · Models · Docs · Status


One endpoint in front of 83 model families across 121 callable endpoints, billed in USD per request rather than in credits. Media generation is asynchronous and quotable before you spend; text models speak the OpenAI, Anthropic and Gemini wire formats.

pip install spicyapi

Requires Python 3.11+. No runtime dependencies: this package goes into your dependency tree, and every constraint it adds is one more chance of a conflict.

Generate something

import os, uuid
from spicyapi import SpicyClient, output_assets

client = SpicyClient()  # reads SPICY_API_KEY from the environment

model = client.get_model("MODEL_ID_FROM_CATALOG")     # copy a real id from list_models()
quote = client.quote_task(model=model["model"], input_data={"prompt": "a lantern in fog"})
print(quote["estimatedCost"], quote["maxCharge"])      # decide before you spend

task = client.create_task(
    model=model["model"],
    input_data={"prompt": "a lantern in fog"},
    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):                     # module-level helper, not a method
    print(asset["url"])

Build the input from that model's own inputSchema — every model has different fields, and list_models(include_schema=True) returns them.

Start from a local file

Image-to-video, face swap and image editing all need your material on our side first. Upload returns a spicy:// URI; that is what goes into input.

uploaded = client.upload_file("/path/to/reference.png")
task = client.create_task(
    model="MODEL_ID_FROM_CATALOG",
    input_data={"image": uploaded["uri"], "prompt": "slow dolly in"},
    idempotency_key=str(uuid.uuid4()),
)

Webhooks

verify_webhook is a module-level function, so a request handler can use it without building a client. It compares in constant time and checks the timestamp only after the signature is valid.

from spicyapi import verify_webhook

delivery = verify_webhook(
    raw_body=request.body,                      # the exact bytes, before any parsing
    signature=request.headers["X-Webhook-Signature"],
    timestamp=request.headers["X-Webhook-Timestamp"],
    payload_version=request.headers["X-Webhook-Payload-Version"],
    secret=os.environ["SPICY_WEBHOOK_SECRET"],
)

Verify the raw bytes. Re-serialising the parsed JSON changes them, and the signature will never match.

Two things that will save you money

Keep one idempotency key per submission. Reuse it for every resend of that submission, including after a timeout or a dropped connection. A lost response does not prove the task was not created — a fresh key turns an unknown outcome into a second paid task.

A task that succeeds is charged, even if the result disappoints. Quote first when the price matters; quote_task reserves nothing.

What this package does not do

Text models. They speak the OpenAI, Anthropic and Google Gemini wire formats, so the official libraries for those already work — point them at https://api.spicyapi.ai/v1 with the same key. Wrapping them here would add nothing.

Browser, mobile and desktop apps. Never ship this key inside an application: a key compiled into a client is a public key. Call from your server, or put @spicyapi/proxy in front.

Errors

Every failure raises SpicyApiError with status, code, request_id and retry_after_seconds. Branch on code, never on the message text — messages are translated, codes are not.

503 is shared by three different business codes, so reading the HTTP status alone is not enough:

code meaning what to do
40003 uploaded bytes do not match their ticket upload again
40004 no deployment serves that parameter combination change the parameter named in the message
40901 the price moved before the task was created quote again, keep the same idempotency key
503 a dependency is briefly unavailable back off by Retry-After
50301 the model has no usable deployment or price right now do not hammer; refresh the catalogue
50302 a synchronous generation failed upstream and was refunded retry with a new idempotency key

err.recovery carries the same guidance at runtime.


Also available in TypeScript · Python · Go · PHP · Java

Release files for spicyapi 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spicyapi 0.1.0
File Size Uploaded
spicyapi-0.1.0.tar.gz 33.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for spicyapi 0.1.0
File Interpreter ABI Platform
spicyapi-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 54.0 kB

Release files / spicyapi-0.1.0.tar.gz

Download URL spicyapi-0.1.0.tar.gz
Size 33.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b6b9f3439c22b4c1afa3ce70fcce7b3e5b86130adc1d7d17cc77a62e8937b5ba
BLAKE2b-256 checksum
How to use checksums
bc5d9594f3096d4cf9544cce6c052e9f79d5565656245eba7df284b50ca4aee6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.

Transparency log

Release files / spicyapi-0.1.0-py3-none-any.whl

Download URL spicyapi-0.1.0-py3-none-any.whl
Size 20.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
73f9cbbf9f11a5faa60b3c1aa5de3c59d5a5f77d27f9b5cb5131243440cb6fd1
BLAKE2b-256 checksum
How to use checksums
321ec92581d1909f14f5bdf65769b5330291f53501b7bb12731d92172cba3490
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page