# Quickstart

> Check the price for free, make the video, and get told when it is ready. Use a test key while you build: results are fake and nothing is charged.

## 1. Get a key

Open **Developers** in the app (https://app.diffusr.ai/developers) and make a test key. It starts with `dfsr_test_`. Keep it in an environment variable. Never put it in code you publish.

```bash
export DIFFUSR_KEY=dfsr_test_...
```

For TypeScript run `npm install diffusr`. For Python run `pip install diffusr`. cURL needs nothing.

## 2. Check the price, free

Add `"dry_run": true` to any call. Nothing is made and nothing is spent. The price holds for an hour.

**cURL**

```bash
curl -X POST https://app.diffusr.ai/api/v2/make_video \
  -H "Authorization: Bearer $DIFFUSR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "prompt": "A woman turns to camera on a sunny street, smiles",
  "model": "seedance-2-0-fast",
  "resolution": "720p",
  "duration_sec": 5,
  "aspect_ratio": "9:16",
  "dry_run": true
}'
```

**TypeScript**

```ts
import { Diffusr } from "diffusr";

const d = new Diffusr(); // reads DIFFUSR_KEY
const job = await d.makeVideo({
  prompt: "A woman turns to camera on a sunny street, smiles",
  model: "seedance-2-0-fast",
  resolution: "720p",
  duration_sec: 5,
  aspect_ratio: "9:16",
  dry_run: true,
});
console.log(job); // the price, nothing was made
```

**Python**

```python
from diffusr import Diffusr

d = Diffusr()  # reads DIFFUSR_KEY
job = d.make_video(
    prompt="A woman turns to camera on a sunny street, smiles",
    model="seedance-2-0-fast",
    resolution="720p",
    duration_sec=5,
    aspect_ratio="9:16",
    dry_run=True,
)
print(job)  # the price, nothing was made
```

The answer has `price.credits` (and `credits_estimated`, the same number), `price.usd`, and `price.expires_at`.

## 3. Make it

Send the same call without `dry_run`. Always send an `Idempotency-Key`: if the connection drops, repeat the same request with the same key and you get the first job back instead of paying twice. Add a `callback_url` if you would rather be told than ask.

**cURL**

```bash
curl -X POST https://app.diffusr.ai/api/v2/make_video \
  -H "Authorization: Bearer $DIFFUSR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "prompt": "A woman turns to camera on a sunny street, smiles",
  "model": "seedance-2-0-fast",
  "resolution": "720p",
  "duration_sec": 5,
  "aspect_ratio": "9:16"
}'
```

**TypeScript**

```ts
import { Diffusr } from "diffusr";

const d = new Diffusr(); // reads DIFFUSR_KEY
const job = await d.makeVideo({
  prompt: "A woman turns to camera on a sunny street, smiles",
  model: "seedance-2-0-fast",
  resolution: "720p",
  duration_sec: 5,
  aspect_ratio: "9:16",
});
const result = await d.waitFor(job.id);
console.log(result.output?.url);
```

**Python**

```python
from diffusr import Diffusr

d = Diffusr()  # reads DIFFUSR_KEY
job = d.make_video(
    prompt="A woman turns to camera on a sunny street, smiles",
    model="seedance-2-0-fast",
    resolution="720p",
    duration_sec=5,
    aspect_ratio="9:16",
)
result = d.wait_for(job["id"])
print(result["output"]["url"])
```

> You are charged when the video is delivered, never more than the price you saw. A failed video costs nothing.

The answer is `202` with an `id`. The work runs in the background.

## 4. Get the video

Ask for the result by its id every 15 to 30 seconds until `status` is `SUCCEEDED`, `FAILED` or `CANCELED`. Or wait for the signed [callback](https://diffusr.ai/docs/callbacks).

**cURL**

```bash
curl "https://app.diffusr.ai/api/v2/results/run_8Hk2xxxxxxxx" \
  -H "Authorization: Bearer $DIFFUSR_KEY"
```

**TypeScript**

```ts
import { Diffusr } from "diffusr";

const d = new Diffusr(); // reads DIFFUSR_KEY
const result = await d.getResult("run_8Hk2xxxxxxxx");
console.log(result.status, result.output?.url);
```

**Python**

```python
from diffusr import Diffusr

d = Diffusr()  # reads DIFFUSR_KEY
result = d.get_result("run_8Hk2xxxxxxxx")
print(result["status"], result.get("output"))
```

When it succeeds, `output.url` is the file and `charge` says what was charged. Videos take 1 to 10 minutes, images 10 to 30 seconds.

## Rules an agent should follow

- Dry run first, show the user the price, and ask before spending.
- One Idempotency-Key per intended job. A new key is a new job and a new charge.
- Read `code` in an error, not the message. See [Errors](https://diffusr.ai/docs/errors).
- Stop when you get `INSUFFICIENT_CREDITS` or `BUDGET_EXCEEDED` and tell the user.

Next: [Test keys](https://diffusr.ai/docs/test-keys), [Prices](https://diffusr.ai/docs/prices), [Callbacks](https://diffusr.ai/docs/callbacks).

Source: https://diffusr.ai/docs/quickstart
