# Quickstart

## Create an API key

Sign in and create a key in [API keys](https://seedrouter.ai/apikeys). Save it when it is first shown. Add credits in [Billing](https://seedrouter.ai/billing).

Set `SEEDROUTER_API_KEY` in your server environment. Python examples require the `requests` package.

## Submit a task

```bash
curl https://api.seedrouter.ai/v1/images/generations \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "An amber glass bottle on a cream background, studio lighting",
    "size": "1024x1024",
    "quality": "low"
  }'
```

```python
import os
import requests

response = requests.post(
    "https://api.seedrouter.ai/v1/images/generations",
    headers={"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}"},
    json={
        "model": "gpt-image-2",
        "prompt": "An amber glass bottle on a cream background, studio lighting",
        "size": "1024x1024",
        "quality": "low",
    },
    timeout=60,
)
response.raise_for_status()
task_id = response.json()["id"]
```

```javascript
const response = await fetch('https://api.seedrouter.ai/v1/images/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SEEDROUTER_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'gpt-image-2',
    prompt: 'An amber glass bottle on a cream background, studio lighting',
    size: '1024x1024',
    quality: 'low',
  }),
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const { id: taskId } = await response.json();
```

```go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "os"
    "strings"
    "time"
)

func main() {
    body := strings.NewReader(`{
      "model": "gpt-image-2",
      "prompt": "An amber glass bottle on a cream background, studio lighting",
      "size": "1024x1024",
      "quality": "low"
    }`)
    req, err := http.NewRequest("POST", "https://api.seedrouter.ai/v1/images/generations", body)
    if err != nil { panic(err) }
    req.Header.Set("Authorization", "Bearer " + os.Getenv("SEEDROUTER_API_KEY"))
    req.Header.Set("Content-Type", "application/json")
    client := &http.Client{Timeout: 60 * time.Second}
    res, err := client.Do(req)
    if err != nil { panic(err) }
    defer res.Body.Close()
    if res.StatusCode != http.StatusOK { panic(res.Status) }
    var task struct { ID string `json:"id"` }
    if err := json.NewDecoder(res.Body).Decode(&task); err != nil { panic(err) }
    fmt.Println(task.ID)
}
```

## Read the result

Store the returned `id`, then query it with the same account's API key:

```bash
curl https://api.seedrouter.ai/v1/tasks/YOUR_TASK_ID \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY"
```

Repeat every three seconds while the status is `processing`. When it is `completed`, read `output.data[].url`. If it is `failed`, inspect `error`.

A polling timeout does not cancel generation. Save the task ID and resume querying it instead of submitting another generation request.

See [Tasks](https://seedrouter.ai/docs/api/tasks) for a complete polling example and [GPT Image 2](https://seedrouter.ai/docs/gpt-image-2) for editing, quality, and size options.
