# Quickstart

> Connect a provider account you already hold, create an INFRO API key, and make your first text, image, video, or audio request through the gateway.

Source: https://infro.io/docs/quickstart

> **Note:** INFRO is in private early access. Running these examples requires an early-access account, an active trial or subscription entitlement, and your own provider connection. Self-serve purchasing is not generally open. See [Early access](https://infro.io/early-access).

You need three things to start: an organization with an active trial or plan, a provider account connected to it, and an INFRO key. Everything else — routing, retries, failover, metering — happens behind the endpoint.

## 1. Subscribe, connect a provider, create a key

In the [console](https://dash.infro.io), name your organization, choose a plan and start its 14-day trial — a card is required at checkout, and nothing is charged until the trial ends ([billing](https://infro.io/docs/org/billing)). Guided setup then opens over the console's Overview: on a plan with more than one seat it first offers to invite your team, then asks you to connect a provider account you already hold, create an INFRO key (shown once) and send a first request. The provider credential is sealed on arrival and never shown again; the INFRO key is what your application sends. Set a spend limit on the key if you want a ceiling on estimated provider cost — see [Rate & spend limits](https://infro.io/docs/api/limits).

```bash
# keep the key in your environment, never in code
export INFRO_API_KEY="sk_infro_..."
```

## 2. Install the SDK

> **Note:** The first-party Python, TypeScript and Dart SDKs are published (version 0.1.x). The Python and Dart clients return plain dictionaries and maps rather than typed objects. If you already use an OpenAI-compatible client, you can also point it at `https://api.infro.io/v1` and authenticate with your `INFRO_API_KEY`.

**Python**

```bash
pip install infro
```

**TypeScript**

```bash
npm install @infro.io/sdk
```

**Dart**

```bash
dart pub add infro
```

Any OpenAI-compatible client also works for text: point its base URL at `https://api.infro.io/v1` and swap the key. See [SDKs & frameworks](https://infro.io/docs/sdks) for LangChain, the Vercel AI SDK, and others.

## 3. Make your first request

Model ids follow `vendor/model-name`. `GET /v1/models` lists the ids your key can call — only models one of your connections serves — with the vendor's published rates behind each estimate. Switching models is a one-string change.

**Python**

```python
import os
from infro import Infro

client = Infro(api_key=os.environ["INFRO_API_KEY"])

image = client.images.generate(
    model="bfl/flux-2-pro",
    prompt="a lighthouse in fog, 35mm",
)

print(image["data"][0]["url"])
print("estimated cost:", image["usage"].get("cost"))  # None when unpriced
```

**TypeScript**

```typescript
import Infro from "@infro.io/sdk";

const infro = new Infro({ apiKey: process.env.INFRO_API_KEY });

const image = await infro.images.generate({
  model: "bfl/flux-2-pro",
  prompt: "a lighthouse in fog, 35mm",
});

console.log(image.data[0].url);
console.log("estimated cost:", image.usage?.cost ?? "unpriced");
```

**Dart**

```dart
import 'dart:io';
import 'package:infro/infro.dart';

final infro = Infro(apiKey: Platform.environment['INFRO_API_KEY']!);

final image = await infro.images.generate(
  model: 'bfl/flux-2-pro',
  prompt: 'a lighthouse in fog, 35mm',
);

print(image['data'][0]['url']);
```

**curl**

```bash
curl https://api.infro.io/v1/images/generations \
  -H "Authorization: Bearer $INFRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bfl/flux-2-pro",
    "prompt": "a lighthouse in fog, 35mm"
  }'
```

## 4. Try another modality

The same client covers text and audio, and video as an [async job](https://infro.io/docs/api/jobs) with a signed [webhook](https://infro.io/docs/api/webhooks). Each modality needs a connection that serves it: none of the built-in provider kinds serves video yet, so a video request answers `503` until one does.

```python
# Text — OpenAI-compatible
chat = client.chat.completions.create(
    model="anthropic/claude-sonnet-5",
    messages=[{"role": "user", "content": "Write an alt text for a foggy lighthouse."}],
)

# Video — async, delivered by webhook (needs a connection that serves video)
job = client.videos.create(
    model="kuaishou/kling-o3",
    prompt="slow push-in on a lighthouse in fog",
    duration_seconds=6,
    webhook={"url": "https://api.example.com/hooks/infro"},
)
print(job["id"], job["status"])
```

## 5. Optional: control routing and cost

By default a model id is served by the provider connections you have added for its vendor, in the order you added them. To choose that order or split traffic between connections, create a [route](https://infro.io/docs/routes) and send its slug as the model. To fall back to a different model when every connection fails, list `fallbacks` on the request (ignored when `model` is a route slug). These fields sit at the top level of the body and are ignored by other OpenAI-compatible backends, so your code stays portable.

```python
image = client.images.generate(
    model="bfl/flux-2-pro",
    prompt="a lighthouse in fog, 35mm",
    fallbacks=["bytedance/seedream-5-pro"],
)
```

> **Note:** Every response carries `usage.cost` — an estimate of what your provider will bill for that request, `null` when the model is unpriced — alongside `provider` and `connection`. Log those next to your own request ids and you have per-feature cost attribution across every provider you use, without any extra instrumentation.

## Next steps

- [Authentication](https://infro.io/docs/authentication) — key format, headers, rotation, and spend limits.
- [Image generation](https://infro.io/docs/modalities/images) · [Video generation](https://infro.io/docs/modalities/video) · [Audio & speech](https://infro.io/docs/modalities/audio).
- [Errors](https://infro.io/docs/api/errors) — every status code and which to retry.
- [Failover & fallbacks](https://infro.io/docs/features/fallbacks) — what happens when a route goes down.
