> ## Documentation Index
> Fetch the complete documentation index at: https://docs.infery.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SDKs

> Official clients for the Infery API — what exists today, and what each one is for.

The API is HTTP and needs no client: every example in these docs has a `curl`
form, and the [API reference](/api-reference/introduction) is complete on its
own. An SDK buys you three things that are tedious to get right by hand.

**Types that match the wire.** Every model, every parameter, every response
shape, checked by your editor before you run anything.

**Deferred results, collected.** A slow media generation answers `504` with a
`job_id` and keeps working — and keeps billing. Every official client collects
the finished result for you instead of failing.

**Retries that cannot double-charge.** A `500` on a billed `POST` is not
retried, because it may arrive after your balance was already debited. Rate
limiting answers `403` here rather than `429`, so a generic HTTP client's
backoff never fires anyway.

## Available now

<CardGroup cols={2}>
  <Card title="TypeScript" href="/sdks/typescript" icon="js">
    `@infery/sdk` — every endpoint, Node 20+, ESM and CJS, zero dependencies.
  </Card>

  <Card title="Python" href="/sdks/python" icon="python">
    `infery` — every endpoint, Python 3.10+, sync and async, one dependency.
  </Card>
</CardGroup>

**TypeScript**

* [Getting started](/sdks/typescript) — install, the first call, streaming,
  media, workflows, errors
* [Method reference](/sdks/typescript-reference) — every call and the route it
  makes

**Python**

* [Getting started](/sdks/python) — install, both clients, streaming, media,
  workflows, errors, and reusing an `httpx` pool
* [Method reference](/sdks/python-reference) — every signature on both clients,
  and every type they name

And for either one:

* [OpenAI SDK compatibility](/sdks/openai-compatibility) — endpoint by endpoint,
  whether your existing OpenAI client reaches it

### "The same namespaces" is a test, not a promise

The TypeScript client covers 42 calls and the Python client 43 calls, under the
same 14 namespaces — the same published operations, plus the compositions each
one needs. The single difference is `videos.wait`, which Python added so that its
`media.wait` composes a resource for video like it does for the other five
modalities; the TypeScript client still polls that endpoint from inside
`media.ts`. In the Python package the surface is checkable rather than
aspirational:
`sdks/python/tests/test_surface_parity.py` walks each client's resource tree and
asserts the set of dotted paths equals an explicit enumeration — on `Infery` and
on `AsyncInfery` both, so a method added to one and forgotten on the other is a
red test rather than a bug report. The enumeration's keys are in turn tied to the
operations in the OpenAPI document, so an endpoint the gateway publishes cannot
reach one SDK and miss the other unnoticed.

Twin parity alone would be blind to a method missing from *both* sides, which is
why the enumeration exists as well: `music.stream` was dropped once and came back
only because the list said it should be there.

## Planned

Java and C#, in that order. They share the shape of the two clients above — the
same namespaces, the same deferred-job handling, the same retry rule — and the
same generated sources: the error-code catalogue in
`sdks/spec/error-codes.json` is language-neutral and already generated for all
of them.

Until they land, those languages talk to the API directly. The
[API reference](/api-reference/introduction) and the OpenAPI document are the
contract, and nothing in the SDKs is privileged access.

## Parameters belong to the model, not to the SDK

Worth knowing before you look for a parameter list in an SDK page: beyond the
handful of fields every request shares, **what a call accepts depends on the
model you name**. An image model declares its own sizes, a TTS model its voices,
a video model its durations and resolutions.

The authoritative list is per model, in `_infery.allowed_params` on
[`GET /v1/models`](/api-reference/models). The SDKs pass unknown keys through
rather than filtering them, so a parameter a model gained yesterday works today
without an SDK release — see the [model catalog](/models/catalog).

The same reasoning is why both SDKs have a single `media.generate` —
[TypeScript](/sdks/typescript#one-call-for-every-media-modality),
[Python](/sdks/python#one-call-for-every-media-modality) — alongside the
per-modality methods: when the modality is a runtime value, it belongs in the
request rather than in the choice of method.
