# Get daily costs
Source: https://docs.getimg.ai/api-reference/billing/get-daily-costs
/openapi.yaml get /v2/billing/costs
Retrieve daily API costs and the range total for your developer project.
# Get the current balance
Source: https://docs.getimg.ai/api-reference/billing/get-the-current-balance
/openapi.yaml get /v2/billing/balance
Retrieve the current API balance shared by the API key's workspace.
# Generate an image
Source: https://docs.getimg.ai/api-reference/images/generate-an-image
/openapi.yaml post /v2/images/generations
Generate an image and return the completed result.
# Get a model
Source: https://docs.getimg.ai/api-reference/models/get-a-model
/openapi.yaml get /v2/models/{model}
Retrieve a single model with its supported parameters and pricing.
# List supported models
Source: https://docs.getimg.ai/api-reference/models/list-supported-models
/openapi.yaml get /v2/models
List the models available to your project with their supported parameters and pricing.
# Create a video generation
Source: https://docs.getimg.ai/api-reference/videos/create-a-video-generation
/openapi.yaml post /v2/videos/generations
Submit a video generation request and return a pending result.
# Retrieve video generation status
Source: https://docs.getimg.ai/api-reference/videos/retrieve-video-generation-status
/openapi.yaml get /v2/videos/generations/{id}
Retrieve the current status of a video generation request.
# Authentication
Source: https://docs.getimg.ai/guides/authentication
Authenticate requests with your API key.
Every API request needs an API key in the `Authorization` header.
```text theme={null}
Authorization: Bearer $GETIMG_API_KEY
```
## Get your API key
Create and manage API keys in the [developer settings](https://getimg.ai/app/developer/api-keys).
## Use your key
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI({
apiKey: process.env.GETIMG_API_KEY, // default, can be omitted
});
const result = await client.images.generate({
model: "seedream-5-lite",
prompt: "A sunset over the ocean",
});
```
```python Python theme={null}
import os
from getimg import GetimgAI
client = GetimgAI(
api_key=os.environ.get("GETIMG_API_KEY"), # default, can be omitted
)
result = client.images.generate(
model="seedream-5-lite",
prompt="A sunset over the ocean",
)
```
```bash cURL theme={null}
curl -X POST https://api.getimg.ai/v2/images/generations \
-H "Authorization: Bearer $GETIMG_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "seedream-5-lite", "prompt": "A sunset over the ocean"}'
```
## Security best practices
* Store API keys in environment variables, not source code.
* Add `.env` files to `.gitignore`.
* Revoke compromised API keys in [developer settings](https://getimg.ai/app/developer/api-keys) and create replacements.
* Use separate API keys for development and production.
## Authentication errors
Missing, malformed, or invalid keys return `401` with error code `invalid_api_key`.
```json theme={null}
{
"error": {
"message": "Incorrect API key provided. You can manage your API keys at https://getimg.ai/app/developer/api-keys",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key",
"doc_url": "https://docs.getimg.ai/guides/authentication"
}
}
```
V1 API keys do not work on this API. If you send one, the error message says so and points you to [developer settings](https://getimg.ai/app/developer/api-keys), where you can create a key for this API.
See [Errors](/guides/errors) for error handling and retry guidance.
# Billing
Source: https://docs.getimg.ai/guides/billing
Read your balance, track daily costs, and top up credits.
The API uses a prepaid credit balance. Each generation draws from that balance, and you can read both the balance and your daily spend from the API.
```text theme={null}
GET https://api.getimg.ai/v2/billing/balance
GET https://api.getimg.ai/v2/billing/costs
```
## Check your balance
The balance is shared by every API key in the workspace.
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const { balance, currency } = await client.billing.retrieveBalance();
console.log(`${balance} ${currency}`);
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
result = client.billing.retrieve_balance()
print(f"{result.balance} {result.currency}")
```
```bash cURL theme={null}
curl https://api.getimg.ai/v2/billing/balance \
-H "Authorization: Bearer $GETIMG_API_KEY"
```
```json theme={null}
{
"currency": "USD",
"balance": "12.3456"
}
```
`balance` is a decimal string with four fractional digits, so you can parse it without floating-point rounding. Use your language's decimal type for comparisons and arithmetic.
```javascript Node.js theme={null}
const { balance } = await client.billing.retrieveBalance();
if (Number(balance) < 5) {
console.warn("Balance is low, top up before the next batch");
}
```
```python Python theme={null}
from decimal import Decimal
result = client.billing.retrieve_balance()
if Decimal(result.balance) < Decimal("5"):
print("Balance is low, top up before the next batch")
```
A workspace with no billing set up returns a zero balance.
## Track daily costs
`GET /v2/billing/costs` returns one cost bucket per day, plus a total for the range. Costs cover every API key in the project.
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const costs = await client.billing.listCosts({
start: "2026-09-01T00:00:00Z",
end: "2026-09-05T00:00:00Z",
});
for (const bucket of costs.data) {
console.log(`${bucket.date}: ${bucket.cost}`);
}
console.log(`Total: ${costs.total_cost} ${costs.currency}`);
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
costs = client.billing.list_costs(
start="2026-09-01T00:00:00Z",
end="2026-09-05T00:00:00Z",
)
for bucket in costs.data:
print(f"{bucket.date}: {bucket.cost}")
print(f"Total: {costs.total_cost} {costs.currency}")
```
```bash cURL theme={null}
curl -G https://api.getimg.ai/v2/billing/costs \
-H "Authorization: Bearer $GETIMG_API_KEY" \
--data-urlencode "start=2026-09-01T00:00:00Z" \
--data-urlencode "end=2026-09-05T00:00:00Z"
```
```json theme={null}
{
"currency": "USD",
"data": [
{ "date": "2026-09-01", "cost": 0.84 },
{ "date": "2026-09-02", "cost": 1.26 },
{ "date": "2026-09-03", "cost": 0 },
{ "date": "2026-09-04", "cost": 0.42 },
{ "date": "2026-09-05", "cost": 0.93 }
],
"total_cost": 3.45,
"start": "2026-09-01T00:00:00Z",
"end": "2026-09-05T00:00:00Z"
}
```
### Range parameters
| Parameter | Required | Description |
| --------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `start` | yes | Inclusive ISO 8601 timestamp. Must include a time zone. |
| `end` | yes | Inclusive ISO 8601 timestamp. Must include a time zone, fall after `start`, and sit within 180 days of it. |
Both bounds are inclusive. A range that omits the time zone, ends before it starts, or spans more than 180 days returns `400` with error code `invalid_parameter`.
### How buckets work
* Buckets use UTC calendar dates, in ascending order.
* Days with no spend are included with a cost of `0`.
* The end date gets its own bucket.
* The first and last bucket can each cover a partial day when your range starts or ends mid-day.
Costs are reported as numbers in USD, unlike the balance.
Cost data is usage telemetry and can lag recent charges. Treat it as a spend report, not as the authoritative billing ledger. Reconcile against the [billing page](https://getimg.ai/app/developer/billing).
## Top up credits
Add credits to your account on the [billing page](https://getimg.ai/app/developer/billing). Click **Top up balance** to make a one-time purchase.
## Auto top-up
On the same [billing page](https://getimg.ai/app/developer/billing), you can enable auto top-up. When your balance drops below a threshold, credits are added automatically.
## Cost per generation
Every completed generation returns a `usage` object with the cost of that generation. Use it to attribute spend as you go instead of reconciling daily totals. See [Media responses](/guides/media-responses).
For the rates behind those costs, see the `pricing` field on each model in [Models](/guides/models).
## API billing vs consumer plans
API credits are separate from the consumer plans listed at [getimg.ai/pricing](https://getimg.ai/pricing).
* Credits purchased for the API do not transfer to consumer plans, and vice versa.
* A consumer subscription is not required to use the API.
* The two systems use independent balances.
## Need help with an older setup
If you still have questions about an older (v1) setup, contact [api@getimg.ai](mailto:api@getimg.ai).
## Related pages
* [Models](/guides/models)
* [Media responses](/guides/media-responses)
* [Errors](/guides/errors)
# Errors
Source: https://docs.getimg.ai/guides/errors
Error codes and handling.
The API uses standard HTTP status codes and a consistent error object, so you can route failures quickly and recover with less guesswork.
## Error response format
```json theme={null}
{
"error": {
"message": "Unsupported resolution '4K' for model 'seedream-5-lite'.",
"type": "invalid_request_error",
"param": "resolution",
"code": "invalid_parameter"
}
}
```
| Field | Type | Description |
| --------- | -------------- | ---------------------------------------------------------- |
| `message` | string | Human-readable description of the error |
| `type` | string | Always `invalid_request_error` |
| `param` | string or null | The request parameter that caused the error, if applicable |
| `code` | string | Machine-readable error code |
| `doc_url` | string | Link to relevant documentation, when available |
## Error codes
| Code | HTTP status | Description | Retryable |
| -------------------------- | ----------- | --------------------------------------------------------- | --------- |
| `invalid_api_key` | 401 | Missing, malformed, revoked, or invalid API key | No |
| `parameter_missing` | 400 | A required parameter was not provided | No |
| `invalid_parameter` | 400 | A parameter value is not supported for the selected model | No |
| `quota_exceeded` | 402 | Insufficient account balance or quota | No |
| `content_policy_violation` | 422 | Prompt or reference image input failed safety checks | No |
| `rate_limit` | 429 | Too many requests | Yes |
| `not_found` | 404 | The requested resource does not exist | No |
| `server_error` | 500 | Unexpected server-side error | Yes |
## Handling errors
Use the HTTP status code and `error.code` together. The status code tells you whether the failure is temporary. The error code tells you what to fix next.
### Retryable failures
Retry `429` and `500` responses with exponential backoff.
* For `429`, wait for the `Retry-After` header.
* For `500`, use backoff with a timeout or retry limit.
* Log the generation ID when you have one so you can trace the failed generation.
See [Rate limits](/guides/rate-limits) for details.
### Terminal failures
Do not retry `400`, `401`, `402`, `404`, or `422` until you change the request or account state.
* `400`: fix missing or invalid parameters
* `401`: fix your API key
* `402`: add credits or resolve quota limits
* `404`: verify the resource ID or path
* `422`: revise the prompt or reference image input
## Async video failures
Video generations can fail after submission. When you poll `GET /v2/videos/generations/{id}`, the response can return `status: "failed"` with an error object.
```json theme={null}
{
"id": "req-01HXYZVIDEO1234",
"status": "failed",
"error": {
"message": "Upstream provider request timed out.",
"code": "server_error"
}
}
```
Treat `failed` as a terminal state for that generation. Read `error.message`, fix the input or retry policy, and submit a new generation when you're ready.
See [Generate videos](/guides/generate-videos) for a polling example.
# Generate images
Source: https://docs.getimg.ai/guides/generate-images
Create images from text and reference images.
Use `POST /v2/images/generations` to create images synchronously. The API waits for completion and returns the finished files in the same response.
```text theme={null}
POST https://api.getimg.ai/v2/images/generations
```
## What to send
At minimum, send a `model` and `prompt`.
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const result = await client.images.generate({
model: "seedream-5-lite",
prompt: "A cinematic portrait of a cat astronaut",
});
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
result = client.images.generate(
model="seedream-5-lite",
prompt="A cinematic portrait of a cat astronaut",
)
```
```bash cURL theme={null}
curl -X POST https://api.getimg.ai/v2/images/generations \
-H "Authorization: Bearer $GETIMG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedream-5-lite",
"prompt": "A cinematic portrait of a cat astronaut"
}'
```
## Key parameters
| Parameter | Type | Default | Description |
| --------------- | ------ | ------------- | ------------------------------------------------------------------------------ |
| `model` | string | required | Model identifier. See [Models](https://getimg.ai/app/developer/models). |
| `prompt` | string | required | Text description of the image to generate. |
| `aspect_ratio` | string | model default | Aspect ratio. Common values: `1:1`, `16:9`, `9:16`, `2:3`, `3:2`. |
| `resolution` | string | model default | Resolution label. Common values: `1K`, `2K`, `4K`. |
| `output_format` | string | `jpeg` | Output format: `png`, `jpeg`, `webp`. |
| `images` | array | -- | Up to 20 reference images for guided generation. HTTPS URL or base64 data URL. |
## Using reference images
Pass up to 20 reference images in the `images` array. Each item needs a `url`.
```json theme={null}
{
"model": "seedream-5-lite",
"prompt": "Product photo in warm studio lighting",
"images": [
{
"url": "https://your-bucket.s3.amazonaws.com/reference.png"
}
],
"aspect_ratio": "1:1",
"resolution": "2K",
"output_format": "webp"
}
```
Use reference images when you need tighter control over style, composition, or subject.
How many reference images a model accepts is in its `supported_references` field. See [Models](/guides/models).
### Reference image sources
`url` accepts either form:
* a publicly accessible HTTPS URL
* a base64 data URL, such as `data:image/png;base64,...`
Use a data URL when the image only exists on your side and you don't want to host it first.
```javascript Node.js theme={null}
import { readFile } from "node:fs/promises";
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const bytes = await readFile("reference.png");
const dataUrl = `data:image/png;base64,${bytes.toString("base64")}`;
const result = await client.images.generate({
model: "seedream-5-lite",
prompt: "Product photo in warm studio lighting",
images: [{ url: dataUrl }],
});
```
```python Python theme={null}
import base64
from getimg import GetimgAI
client = GetimgAI()
with open("reference.png", "rb") as f:
encoded = base64.b64encode(f.read()).decode()
result = client.images.generate(
model="seedream-5-lite",
prompt="Product photo in warm studio lighting",
images=[{"url": f"data:image/png;base64,{encoded}"}],
)
```
Inline images must be PNG, JPEG, or WebP. Bare base64 without the `data:` prefix is rejected.
A decoded reference image can be up to 10 MiB, and the whole JSON request must fit within 25 MiB. Base64 adds roughly 33% to the original file size, so budget for that before you inline several images. Pass an HTTPS URL instead when you're close to the limit.
## Response handling
A completed image generation returns:
* `id` for the generation
* `status: "completed"`
* `data`, which contains one or more generated files
* `usage`, which contains billing details for the generation
Each item in `data` includes a signed download URL and a `deletes_at` timestamp. Generated media is retained for 24 hours, so download the file within that window if you need to keep it in your own system.
See [Media responses](/guides/media-responses) for the full response shape.
## Common failure cases
* Invalid model, aspect ratio, or resolution returns `400`.
* Missing or invalid API keys return `401`.
* Insufficient balance returns `402`.
* Safety failures for prompts or reference images return `422`.
* Rate or concurrency limits return `429`.
See [Errors](/guides/errors) for error handling details.
## Full example
```javascript Node.js theme={null}
import { writeFile } from "node:fs/promises";
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const result = await client.images.generate({
model: "seedream-5-lite",
prompt: "A watercolor painting of a mountain village at dawn",
aspect_ratio: "16:9",
resolution: "2K",
output_format: "png",
});
const download = await fetch(result.data[0].url);
const buffer = Buffer.from(await download.arrayBuffer());
await writeFile("output.png", buffer);
console.log(`Saved output.png (${result.data[0].width}x${result.data[0].height})`);
console.log(`Cost: ${result.usage?.total_cost} (${result.usage?.billable_unit})`);
```
```python Python theme={null}
import httpx
from getimg import GetimgAI
client = GetimgAI()
result = client.images.generate(
model="seedream-5-lite",
prompt="A watercolor painting of a mountain village at dawn",
aspect_ratio="16:9",
resolution="2K",
output_format="png",
)
with open("output.png", "wb") as f:
f.write(httpx.get(result.data[0].url).content)
print(f"Saved output.png ({result.data[0].width}x{result.data[0].height})")
print(f"Cost: {result.usage.total_cost} ({result.usage.billable_unit})")
```
```bash cURL theme={null}
curl -X POST https://api.getimg.ai/v2/images/generations \
-H "Authorization: Bearer $GETIMG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedream-5-lite",
"prompt": "A watercolor painting of a mountain village at dawn",
"aspect_ratio": "16:9",
"resolution": "2K",
"output_format": "png"
}'
```
## Related pages
* [Quickstart](/guides/quickstart)
* [Media responses](/guides/media-responses)
* [Errors](/guides/errors)
* [Models](/guides/models)
# Generate videos
Source: https://docs.getimg.ai/guides/generate-videos
Submit, poll, and download video generations.
Use `POST /v2/videos/generations` to start a video generation. Video generation is asynchronous, so you submit once, poll for status, and download the finished asset when it's ready.
```text theme={null}
POST https://api.getimg.ai/v2/videos/generations
GET https://api.getimg.ai/v2/videos/generations/{id}
```
## The generation flow
POST to `/v2/videos/generations` with your model, prompt, and parameters. The API returns `HTTP 202` with a generation ID and `status: "pending"`.
GET `/v2/videos/generations/{id}` periodically. The status will be `pending`, `failed`, or `completed`.
When status is `completed`, download the video from the signed download URL in `data[0].url`.
## Step 1: Submit
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const result = await client.videos.generations.create({
model: "seedance-v1-5-pro",
prompt: "A drone shot over a futuristic city skyline at sunset",
aspect_ratio: "16:9",
resolution: "1080p",
duration: 5,
sound: true,
});
const generationId = result.id; // e.g., "req-01HXYZVIDEO1234"
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
result = client.videos.generations.create(
model="seedance-v1-5-pro",
prompt="A drone shot over a futuristic city skyline at sunset",
aspect_ratio="16:9",
resolution="1080p",
duration=5,
sound=True,
)
generation_id = result.id # e.g., "req-01HXYZVIDEO1234"
```
```bash cURL theme={null}
curl -X POST https://api.getimg.ai/v2/videos/generations \
-H "Authorization: Bearer $GETIMG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-v1-5-pro",
"prompt": "A drone shot over a futuristic city skyline at sunset",
"aspect_ratio": "16:9",
"resolution": "1080p",
"duration": 5,
"sound": true
}'
```
```json theme={null}
{
"id": "req-01HXYZVIDEO1234",
"status": "pending"
}
```
## Step 2: Poll for status
Poll the status endpoint with your generation ID.
| Status | Meaning | Next action |
| ----------- | ----------------- | ------------------------------------------------------------ |
| `pending` | Still processing | Wait and poll again |
| `failed` | Generation failed | Read `error.message`, then submit a new generation if needed |
| `completed` | Video is ready | Download from `data[0].url` |
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const result = await client.videos.generations.retrieve("req-01HXYZVIDEO1234");
console.log(result.status);
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
result = client.videos.generations.retrieve("req-01HXYZVIDEO1234")
print(result.status)
```
```bash cURL theme={null}
curl https://api.getimg.ai/v2/videos/generations/req-01HXYZVIDEO1234 \
-H "Authorization: Bearer $GETIMG_API_KEY"
```
**Completed response:**
```json theme={null}
{
"id": "req-01HXYZVIDEO1234",
"status": "completed",
"model": "seedance-v1-5-pro",
"data": [
{
"url": "https://api.getimg.ai/v2/downloads/req-01HXYZVIDEO1234/0?exp=1760000000&sig=ca4f0f...",
"width": 1920,
"height": 1080,
"duration": 5,
"fps": 24,
"has_sound": true,
"mime_type": "video/mp4",
"deletes_at": "2026-09-09T12:30:00.000Z"
}
],
"usage": {
"total_cost": 0.25,
"billable_unit": "video_second",
"unit_price": 0.05,
"quantity": 5
}
}
```
### Polling strategy
Poll every 5 seconds as a starting point. Set a timeout so your integration stays responsive and does not poll forever.
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
async function pollVideo(generationId, interval = 5000, timeout = 300000) {
const start = Date.now();
while (Date.now() - start < timeout) {
const result = await client.videos.generations.retrieve(generationId);
if (result.status === "completed") return result;
if (result.status === "failed") {
throw new Error(`Generation failed: ${result.error.message}`);
}
await new Promise((r) => setTimeout(r, interval));
}
throw new Error(`Video not ready after ${timeout / 1000}s`);
}
```
```python Python theme={null}
import time
from getimg import GetimgAI
client = GetimgAI()
def poll_video(generation_id, interval=5, timeout=300):
elapsed = 0
while elapsed < timeout:
result = client.videos.generations.retrieve(generation_id)
if result.status == "completed":
return result
if result.status == "failed":
raise Exception(f"Generation failed: {result.error.message}")
time.sleep(interval)
elapsed += interval
raise TimeoutError(f"Video not ready after {timeout}s")
```
```bash cURL theme={null}
while true; do
response=$(curl -s https://api.getimg.ai/v2/videos/generations/req-01HXYZVIDEO1234 \
-H "Authorization: Bearer $GETIMG_API_KEY")
status=$(printf '%s' "$response" | jq -r '.status')
echo "Status: $status"
if [ "$status" = "completed" ] || [ "$status" = "failed" ]; then
printf '%s\n' "$response"
break
fi
sleep 5
done
```
## Step 3: Download
The `url` in each data item is a signed download URL. Generated media is retained for 24 hours, and the URL expires at the `deletes_at` timestamp.
```javascript Node.js theme={null}
import { writeFile } from "node:fs/promises";
const download = await fetch("https://api.getimg.ai/v2/downloads/req-01HXYZVIDEO1234/0?exp=1760000000&sig=ca4f0f...");
const buffer = Buffer.from(await download.arrayBuffer());
await writeFile("video.mp4", buffer);
```
```python Python theme={null}
import httpx
with open("video.mp4", "wb") as f:
f.write(httpx.get("https://api.getimg.ai/v2/downloads/req-01HXYZVIDEO1234/0?exp=1760000000&sig=ca4f0f...").content)
```
```bash cURL theme={null}
curl -o video.mp4 "https://api.getimg.ai/v2/downloads/req-01HXYZVIDEO1234/0?exp=1760000000&sig=ca4f0f..."
```
## Parameters
| Parameter | Type | Default | Description |
| -------------- | ------- | ------------- | ------------------------------------------------------------------------------------------ |
| `model` | string | required | Model identifier. See [Models](https://getimg.ai/app/developer/models). |
| `prompt` | string | required | Text description of the video to generate. |
| `aspect_ratio` | string | model default | e.g., `16:9`, `1:1`, `9:16`. |
| `resolution` | string | model default | e.g., `720p`, `1080p`. |
| `duration` | integer | model default | Duration in seconds. |
| `sound` | boolean | `false` | Generate audio, where supported by the model. |
| `images` | array | -- | Up to 20 first frame, last frame, or reference image inputs. HTTPS URL or base64 data URL. |
## Using frame and reference images
Pass up to 20 images in the `images` array. Each item needs a `url` and a `role`.
Video models support these roles:
* **`first_frame`**: the opening frame of the video
* **`last_frame`**: the closing frame of the video. This always requires a `first_frame`.
* **`reference_image`**: a style or content reference when you need the output to stay closer to an existing visual direction. You cannot combine it with `first_frame` or `last_frame`.
```json theme={null}
{
"model": "seedance-v1-5-pro",
"prompt": "Transition from sunrise to dusk over mountain landscape",
"images": [
{
"url": "https://your-bucket.s3.amazonaws.com/sunrise.png",
"role": "first_frame"
},
{
"url": "https://your-bucket.s3.amazonaws.com/dusk.png",
"role": "last_frame"
}
],
"aspect_ratio": "16:9",
"resolution": "720p",
"duration": 10
}
```
Not all models support all roles. A model's `supported_references` field lists the roles it accepts and the maximum count for each. See [Models](/guides/models). Unsupported roles return `400` with code `invalid_parameter`.
### Image sources
`url` accepts either form:
* a publicly accessible HTTPS URL
* a base64 data URL, such as `data:image/png;base64,...`
Use a data URL when the frame only exists on your side and you don't want to host it first.
```javascript Node.js theme={null}
import { readFile } from "node:fs/promises";
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const bytes = await readFile("sunrise.png");
const dataUrl = `data:image/png;base64,${bytes.toString("base64")}`;
const { id } = await client.videos.generations.create({
model: "seedance-v1-5-pro",
prompt: "Transition from sunrise to dusk over mountain landscape",
images: [{ url: dataUrl, role: "first_frame" }],
duration: 5,
});
```
```python Python theme={null}
import base64
from getimg import GetimgAI
client = GetimgAI()
with open("sunrise.png", "rb") as f:
encoded = base64.b64encode(f.read()).decode()
submission = client.videos.generations.create(
model="seedance-v1-5-pro",
prompt="Transition from sunrise to dusk over mountain landscape",
images=[{"url": f"data:image/png;base64,{encoded}", "role": "first_frame"}],
duration=5,
)
```
Inline images must be PNG, JPEG, or WebP. Bare base64 without the `data:` prefix is rejected.
A decoded image can be up to 10 MiB, and the whole JSON request must fit within 25 MiB. Base64 adds roughly 33% to the original file size, so budget for that before you inline both a first and last frame. Pass an HTTPS URL instead when you're close to the limit.
## Failure states
Video generations can fail after submission.
* If polling returns `status: "failed"`, treat that generation as terminal.
* Read `error.message` for the reason.
* Fix the input, wait if the problem is temporary, or submit a new generation.
## Sound
Set `sound: true` to generate audio. Supported models are listed on the [Models](https://getimg.ai/app/developer/models) page.
```json theme={null}
{
"model": "seedance-v1-5-pro",
"prompt": "Ocean waves crashing on a rocky shore",
"duration": 10,
"sound": true
}
```
## Full example
```javascript Node.js theme={null}
import { writeFile } from "node:fs/promises";
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const { id } = await client.videos.generations.create({
model: "seedance-v1-pro",
prompt: "A timelapse of clouds rolling over a mountain peak",
aspect_ratio: "16:9",
resolution: "1080p",
duration: 10,
sound: true,
});
console.log(`Submitted: ${id}`);
let result = await client.videos.generations.retrieve(id);
while (result.status === "pending") {
await new Promise((r) => setTimeout(r, 5000));
result = await client.videos.generations.retrieve(id);
console.log(`Status: ${result.status}`);
}
if (result.status === "failed") {
throw new Error(`Failed: ${result.error.message}`);
}
const video = result.data[0];
const download = await fetch(video.url);
const buffer = Buffer.from(await download.arrayBuffer());
await writeFile("output.mp4", buffer);
console.log(`Saved output.mp4 (${video.width}x${video.height}, ${video.duration}s, ${video.fps}fps)`);
console.log(`Sound: ${video.has_sound}`);
console.log(`Cost: ${result.usage?.total_cost} (${result.usage?.quantity} ${result.usage?.billable_unit})`);
```
```python Python theme={null}
import time
import httpx
from getimg import GetimgAI
client = GetimgAI()
submission = client.videos.generations.create(
model="seedance-v1-pro",
prompt="A timelapse of clouds rolling over a mountain peak",
aspect_ratio="16:9",
resolution="1080p",
duration=10,
sound=True,
)
print(f"Submitted: {submission.id}")
result = client.videos.generations.retrieve(submission.id)
while result.status == "pending":
time.sleep(5)
result = client.videos.generations.retrieve(submission.id)
print(f"Status: {result.status}")
if result.status == "failed":
raise RuntimeError(f"Failed: {result.error.message}")
video = result.data[0]
with open("output.mp4", "wb") as f:
f.write(httpx.get(video.url).content)
print(f"Saved output.mp4 ({video.width}x{video.height}, {video.duration}s, {video.fps}fps)")
print(f"Sound: {video.has_sound}")
if result.usage:
print(f"Cost: {result.usage.total_cost} ({result.usage.quantity} {result.usage.billable_unit})")
```
```bash cURL theme={null}
submission=$(curl -s -X POST https://api.getimg.ai/v2/videos/generations \
-H "Authorization: Bearer $GETIMG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-v1-pro",
"prompt": "A timelapse of clouds rolling over a mountain peak",
"aspect_ratio": "16:9",
"resolution": "1080p",
"duration": 10,
"sound": true
}')
generation_id=$(printf '%s' "$submission" | jq -r '.id')
echo "Submitted: $generation_id"
while true; do
result=$(curl -s "https://api.getimg.ai/v2/videos/generations/$generation_id" \
-H "Authorization: Bearer $GETIMG_API_KEY")
status=$(printf '%s' "$result" | jq -r '.status')
echo "Status: $status"
if [ "$status" = "failed" ]; then
printf '%s\n' "$result" | jq -r '.error.message'
exit 1
fi
if [ "$status" = "completed" ]; then
download_url=$(printf '%s' "$result" | jq -r '.data[0].url')
curl -L "$download_url" -o output.mp4
break
fi
sleep 5
done
```
## Related pages
* [Media responses](/guides/media-responses)
* [Errors](/guides/errors)
* [Rate limits](/guides/rate-limits)
* [Models](/guides/models)
# Libraries
Source: https://docs.getimg.ai/guides/libraries
Official client libraries for the getimg.ai API.
Use an official client library to call the getimg.ai API from your language of choice.
Official TypeScript and JavaScript client. Install from [npm](https://www.npmjs.com/package/getimg-ai).
```bash theme={null}
npm install getimg-ai
```
Official Python client. Install from [PyPI](https://pypi.org/project/getimg/).
```bash theme={null}
pip install getimg
```
Both clients cover the same resources:
| Resource | Node.js | Python |
| --------------------------- | -------------------------------------- | -------------------------------------- |
| Generate an image | `client.images.generate()` | `client.images.generate()` |
| Create a video generation | `client.videos.generations.create()` | `client.videos.generations.create()` |
| Retrieve a video generation | `client.videos.generations.retrieve()` | `client.videos.generations.retrieve()` |
| List models | `client.models.list()` | `client.models.list()` |
| Get a model | `client.models.retrieve()` | `client.models.retrieve()` |
| Get the balance | `client.billing.retrieveBalance()` | `client.billing.retrieve_balance()` |
| Get daily costs | `client.billing.listCosts()` | `client.billing.list_costs()` |
Both read your API key from the `GETIMG_API_KEY` environment variable by default. See [Authentication](/guides/authentication).
If you prefer raw HTTP, use the examples in [Quickstart](/guides/quickstart) and the generation guides.
# Media responses
Source: https://docs.getimg.ai/guides/media-responses
Response format for generated media.
Generation endpoints return a consistent response structure. Use this page to understand what you get back, what expires, and what to store on your side.
## Response structure
Every completed generation includes these fields:
| Field | Type | Description |
| -------- | ------ | ---------------------------------------------------------------------- |
| `id` | string | Unique generation identifier, for example `req-01HXYZABCD1234` |
| `status` | string | `completed` for images, `pending`, `failed`, or `completed` for videos |
| `model` | string | The model used for the generation |
| `data` | array | Generated media items |
| `usage` | object | Billing information |
## Sync vs async
**Images** return `HTTP 200` with `status: "completed"` and the full response body immediately.
**Videos** return `HTTP 202` with `status: "pending"` and only an `id` when you submit the generation. Poll `GET /v2/videos/generations/{id}` until the status changes to `completed` or `failed`. See [Generate videos](/guides/generate-videos) for the full flow.
## The data array
Each item in `data` represents a generated file.
**Image items:**
| Field | Type | Description |
| ------------ | ------- | ---------------------------------------- |
| `url` | string | Signed download URL |
| `width` | integer | Image width in pixels |
| `height` | integer | Image height in pixels |
| `mime_type` | string | e.g. `image/png`, `image/webp` |
| `deletes_at` | string | ISO 8601 timestamp when the file expires |
**Video items** include additional fields:
| Field | Type | Description |
| ----------- | ------- | ------------------------- |
| `duration` | number | Video length in seconds |
| `fps` | number | Frames per second |
| `has_sound` | boolean | Whether audio is included |
## Download URLs
The `url` in each `data` item is a signed download URL to the generated media.
```bash theme={null}
curl -o output.png "https://api.getimg.ai/v2/downloads/req-01HXYZABCD1234/0?exp=1760000000&sig=1d9c2f..."
```
Generated media is retained for 24 hours. The signed `url` is valid for that same window and expires at `deletes_at`.
Download URLs expire 24 hours after generation. Store the file in your own system if you need it for longer.
Read `deletes_at` rather than computing the deadline yourself, and download as soon as a generation completes. That keeps your delivery flow predictable.
## Usage and billing
The `usage` object contains billing details for the generation.
```json theme={null}
{
"total_cost": 0.5,
"billable_unit": "video_second",
"unit_price": 0.05,
"quantity": 10
}
```
| Field | Description |
| --------------- | --------------------------------------------------------------------------- |
| `total_cost` | Total cost for this generation |
| `billable_unit` | `image` for images, `video_second` for videos |
| `unit_price` | Cost per unit |
| `quantity` | Number of units. This is `1` for images and duration in seconds for videos. |
For spend across generations rather than a single one, use the daily costs endpoint in [Billing](/guides/billing). For the rates behind `unit_price`, see the `pricing` field in [Models](/guides/models).
## Related pages
* [Generate images](/guides/generate-images)
* [Generate videos](/guides/generate-videos)
* [Models](/guides/models)
* [Billing](/guides/billing)
# Models
Source: https://docs.getimg.ai/guides/models
List models, read their supported parameters, and choose the right one for each use case.
Use the models endpoints to discover which models your project can use, which parameters each one accepts, and what each one costs.
```text theme={null}
GET https://api.getimg.ai/v2/models
GET https://api.getimg.ai/v2/models/{model}
```
## What these endpoints return
Every model comes back with its supported parameters and its currently effective pricing. Use them when you need to:
* discover current model IDs
* separate image models from video models
* validate `aspect_ratio`, `resolution`, `duration`, and `sound` before you submit a generation
* read the current price per billable unit
## List models
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const models = await client.models.list();
console.log(models);
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
models = client.models.list()
print(models)
```
```bash cURL theme={null}
curl https://api.getimg.ai/v2/models \
-H "Authorization: Bearer $GETIMG_API_KEY"
```
## Filter by type
Use the optional `type` query parameter when you only want one category.
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const videoModels = await client.models.list({ type: "video" });
console.log(videoModels);
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
video_models = client.models.list(type="video")
print(video_models)
```
```bash cURL theme={null}
curl "https://api.getimg.ai/v2/models?type=video" \
-H "Authorization: Bearer $GETIMG_API_KEY"
```
Use `type=image` for image models and `type=video` for video models.
## Get a single model
Pass a model ID to read one model without fetching the whole list.
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const model = await client.models.retrieve("seedream-5-lite");
console.log(model.supported_resolutions);
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
model = client.models.retrieve("seedream-5-lite")
print(model.supported_resolutions)
```
```bash cURL theme={null}
curl https://api.getimg.ai/v2/models/seedream-5-lite \
-H "Authorization: Bearer $GETIMG_API_KEY"
```
The response is a single model object.
```json theme={null}
{
"id": "seedream-5-lite",
"name": "Seedream 5 Lite",
"type": "image",
"supported_aspect_ratios": ["1:1", "16:9"],
"supported_durations": [],
"supported_resolutions": ["2K", "4K"],
"supports_sound": false,
"supported_references": { "reference_image": 14 },
"pricing": {
"currency": "USD",
"rates": [
{
"resolution": "2K",
"sound": "not_applicable",
"billable_unit": "image",
"unit_price": "0.1400"
}
]
},
"created_at": "2026-04-17T10:20:30.000Z"
}
```
An unknown model ID returns `404` with error code `not_found`.
## Response fields
| Field | Type | Description |
| ------------------------- | ------- | -------------------------------------------------------------- |
| `id` | string | Model identifier to send as `model` |
| `name` | string | Display name |
| `type` | string | `image` or `video` |
| `supported_aspect_ratios` | array | Accepted `aspect_ratio` values |
| `supported_durations` | array | Accepted `duration` values in seconds. Empty for image models. |
| `supported_resolutions` | array | Accepted `resolution` values |
| `supports_sound` | boolean | Whether the model can generate audio |
| `supported_references` | object | Maximum reference image count per role |
| `pricing` | object | Currency and currently effective rates |
| `created_at` | string | When the model was added |
## Supported parameters and defaults
`supported_aspect_ratios`, `supported_durations`, and `supported_resolutions` are ordered. The first value is the default the API applies when you omit the parameter, so you can send a minimal request and still get a sensible result.
Sending a value that isn't in the list returns `400` with error code `invalid_parameter`.
## Reference image roles
`supported_references` maps each role the model accepts to the maximum number of reference images for that role.
```json theme={null}
{
"supported_references": { "first_frame": 1, "last_frame": 1 }
}
```
A role that isn't in the object isn't supported by that model. Use this to check a role before you submit rather than discovering it from a `400`. See [Generate images](/guides/generate-images) and [Generate videos](/guides/generate-videos) for how roles work.
## Pricing
Each model carries the rates currently in effect for your project.
| Field | Description |
| ----------------------- | --------------------------------------------------------------------------------- |
| `currency` | Always `USD` |
| `rates` | Effective rates, ordered by unit price |
| `rates[].resolution` | Resolution the rate applies to, or `null` when the rate is resolution-independent |
| `rates[].sound` | `sound_on`, `sound_off`, or `not_applicable` |
| `rates[].billable_unit` | `image` for images, `video_second` for videos |
| `rates[].unit_price` | Price per billable unit, as a decimal string |
To find the rate for a generation, match on the `resolution` and `sound` values you plan to send. For videos, `not_applicable` also acts as a fallback when no exact match exists.
`unit_price` is a string so you can parse it as a decimal without floating-point rounding. Use your language's decimal type rather than a float when you total costs.
An empty `rates` array means no active rates are configured for that model. It does not mean generation is free. Current rates are also listed on the [Models](https://getimg.ai/app/developer/models) page.
For what you have actually spent, see [Billing](/guides/billing).
## Validate before you generate
Fetch the model and check your parameters against it. That turns a failed generation into a local check.
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const model = await client.models.retrieve("seedance-v1-pro");
const resolution = "1080p";
const duration = 10;
if (!model.supported_resolutions.includes(resolution)) {
throw new Error(`${model.id} supports: ${model.supported_resolutions.join(", ")}`);
}
if (!model.supported_durations.includes(duration)) {
throw new Error(`${model.id} supports: ${model.supported_durations.join(", ")}`);
}
if (!model.supports_sound) {
console.log(`${model.id} has no sound, omitting the parameter`);
}
const { id } = await client.videos.generations.create({
model: model.id,
prompt: "A timelapse of clouds rolling over a mountain peak",
resolution,
duration,
sound: model.supports_sound,
});
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
model = client.models.retrieve("seedance-v1-pro")
resolution = "1080p"
duration = 10
if resolution not in model.supported_resolutions:
raise ValueError(f"{model.id} supports: {model.supported_resolutions}")
if duration not in model.supported_durations:
raise ValueError(f"{model.id} supports: {model.supported_durations}")
if not model.supports_sound:
print(f"{model.id} has no sound, omitting the parameter")
submission = client.videos.generations.create(
model=model.id,
prompt="A timelapse of clouds rolling over a mountain peak",
resolution=resolution,
duration=duration,
sound=model.supports_sound,
)
```
To check a reference image role, read `supported_references`.
```javascript Node.js theme={null}
const maxFirstFrames = model.supported_references.first_frame ?? 0;
if (maxFirstFrames === 0) {
throw new Error(`${model.id} does not accept a first frame`);
}
```
```python Python theme={null}
max_first_frames = model.supported_references.get("first_frame", 0)
if max_first_frames == 0:
raise ValueError(f"{model.id} does not accept a first frame")
```
## Image vs video models
Choose the model type based on the generation type:
* Image models are for `POST /v2/images/generations`
* Video models are for `POST /v2/videos/generations`
Sending an image model to the video endpoint, or the reverse, returns `400` with error code `invalid_parameter`.
## How to choose a model
Start with these checks:
* generation type: image or video
* input shape: prompt only, reference image, first frame, or last frame
* output needs: aspect ratio, resolution, duration, and sound
If your integration depends on a specific capability, read the model before you submit a generation and validate against its supported parameters. That keeps your production flow stable as model availability changes.
## Where to check current availability
Use one of these sources:
* `GET /v2/models` and `GET /v2/models/{model}` in your integration
* the [Models](https://getimg.ai/app/developer/models) page in the dashboard
Avoid hardcoding a fixed model list, parameter set, or price in your integration. All of them can change.
## Related pages
* [Quickstart](/guides/quickstart)
* [Generate images](/guides/generate-images)
* [Generate videos](/guides/generate-videos)
* [Billing](/guides/billing)
# Quickstart
Source: https://docs.getimg.ai/guides/quickstart
Generate your first image in under two minutes.
This guide gets you from API key to first image generation with the fewest steps.
## Prerequisites
An API key from the [developer settings](https://getimg.ai/app/developer/api-keys).
## 1. Set your API key
Export your API key as an environment variable.
```bash theme={null}
export GETIMG_API_KEY="sk_your_key_here"
```
## 2. Generate an image
Send a request to the image generation endpoint with a model and prompt.
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const data = await client.images.generate({
model: "seedream-5-lite",
prompt: "A cinematic portrait of a cat astronaut",
aspect_ratio: "1:1",
resolution: "2K",
});
console.log(data);
```
```python Python theme={null}
from getimg import GetimgAI
client = GetimgAI()
data = client.images.generate(
model="seedream-5-lite",
prompt="A cinematic portrait of a cat astronaut",
aspect_ratio="1:1",
resolution="2K",
)
print(data)
```
```bash cURL theme={null}
curl -X POST https://api.getimg.ai/v2/images/generations \
-H "Authorization: Bearer $GETIMG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedream-5-lite",
"prompt": "A cinematic portrait of a cat astronaut",
"aspect_ratio": "1:1",
"resolution": "2K"
}'
```
The response includes a `data` array with the generated image and the download URL you need next.
```json theme={null}
{
"id": "req-01HXYZABCD1234",
"status": "completed",
"model": "seedream-5-lite",
"data": [
{
"url": "https://api.getimg.ai/v2/downloads/req-01HXYZABCD1234/0?exp=1760000000&sig=1d9c2f...",
"width": 2048,
"height": 2048,
"mime_type": "image/jpeg",
"deletes_at": "2026-09-09T12:30:00.000Z"
}
],
"usage": {
"total_cost": 0.04,
"billable_unit": "image",
"unit_price": 0.04,
"quantity": 1
}
}
```
## 3. Download your image
The `url` in each `data` item is a signed download URL. Generated media is retained for 24 hours, so download the file before the `deletes_at` timestamp.
```bash theme={null}
curl -o image.png "https://api.getimg.ai/v2/downloads/req-01HXYZABCD1234/0?exp=1760000000&sig=1d9c2f..."
```
## Next steps
Explore reference images, output formats, and response handling.
Learn the async submit, poll, and download flow.
Check current model availability in the dashboard.
Learn how to list and choose models with `GET /v2/models`.
# Rate limits
Source: https://docs.getimg.ai/guides/rate-limits
Rate limits and retry behavior.
Rate limits are applied per workspace and affect generation endpoints. Plan for them early if you're sending generations at scale.
## Types of rate limits
There are three independent rate limits, all enforced on generation requests only:
| Limit | Applies to | Window | Description |
| ----------------------- | ----------------------------- | ---------- | ------------------------------------------------- |
| **Image RPM** | `POST /v2/images/generations` | 60 seconds | Maximum image generation submissions per minute |
| **Video RPM** | `POST /v2/videos/generations` | 60 seconds | Maximum video generation submissions per minute |
| **Concurrent requests** | Both generation endpoints | Rolling | Maximum in-flight generation requests at any time |
Image and video RPM are tracked separately. The concurrent requests limit is shared across both.
The models and billing endpoints are not metered by these limits, but they can still return `429` under sustained traffic. Handle it with the same backoff you use for generations.
Your current rate limits are shown in the [developer dashboard](https://getimg.ai/app/developer). Limits vary by account setup.
## How this affects image and video generation
* Image generations count when you submit the generation.
* Video generations count when you submit the generation.
* Polling `GET /v2/videos/generations/{id}` is a read operation. It does not create a new generation.
* Pending video generations can still count against your concurrent limit until they finish.
## Rate limit headers
Every generation response includes headers so you can track your usage:
| Header | Description |
| ----------------------- | ------------------------------------------------ |
| `X-RateLimit-Limit` | Maximum requests allowed in the current window |
| `X-RateLimit-Remaining` | Requests remaining in the current window |
| `X-RateLimit-Reset` | Unix timestamp in seconds when the window resets |
When you exceed the RPM limit, the API returns `HTTP 429` with an additional header:
| Header | Description |
| ------------- | ------------------------------- |
| `Retry-After` | Seconds to wait before retrying |
## Concurrent request limit
The concurrent limit caps in-flight generation requests across both endpoints. Pending video generations count against this limit.
When exceeded, the API returns `429`:
```json theme={null}
{
"error": {
"message": "Too many concurrent requests. Please wait for current requests to finish.",
"code": "rate_limit"
}
}
```
## Handling rate limits
Use the `Retry-After` header with exponential backoff.
```javascript Node.js theme={null}
import GetimgAI from "getimg-ai";
const client = new GetimgAI({ maxRetries: 5 });
async function generate(payload) {
try {
return await client.images.generate(payload);
} catch (err) {
if (err instanceof GetimgAI.RateLimitError) {
console.error("Rate limit exceeded after retries");
}
throw err;
}
}
```
```python Python theme={null}
import getimg
from getimg import GetimgAI
client = GetimgAI(max_retries=5)
def generate(**payload):
try:
return client.images.generate(**payload)
except getimg.RateLimitError:
print("Rate limit exceeded after retries")
raise
```
```bash cURL theme={null}
response_headers=$(mktemp)
curl -X POST https://api.getimg.ai/v2/images/generations \
-D "$response_headers" \
-H "Authorization: Bearer $GETIMG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedream-5-lite",
"prompt": "A cinematic portrait of a cat astronaut"
}'
retry_after=$(grep -i '^Retry-After:' "$response_headers" | awk '{print $2}' | tr -d '\r')
if [ -n "$retry_after" ]; then
echo "Retry after ${retry_after}s"
fi
rm "$response_headers"
```
If you run your own queue, back off new generation submissions when remaining capacity is low. Keep polling separate from submission throughput control so retries do not crowd out new work.
# Introduction
Source: https://docs.getimg.ai/index
getimg.ai API for image and video generation.
The getimg.ai API gives you direct access to image and video generation in one production-ready interface. All endpoints use the `v2` prefix and the same base URL.
```text theme={null}
https://api.getimg.ai
```
## Get started
Create an API key in the [developer settings](https://getimg.ai/app/developer/api-keys).
Follow the [quickstart](/guides/quickstart) to generate an image.
Use the [models guide](/guides/models) to understand image and video models.
## What this API covers
Generate images synchronously from a prompt and optional reference images.
Submit a video generation, poll for completion, then download the result.
## Core concepts
Send your API key in the `Authorization` header.
Read supported parameters and pricing per model.
Understand `data`, `usage`, download URLs, and expiry.
Handle validation, balance, rate limit, and server errors.
Understand RPM, concurrency, and retry behavior.
Read your balance and daily costs from the API.
## Next steps
Go from API key to first image generation fast.
Learn the synchronous image flow and parameter basics.
Learn the submit, poll, and download flow for videos.
Use the official Node.js or Python client library.