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

# Quickstart

> Crée une API key et génère ta première image avec un modèle de style entraîné en cinq étapes.

Ce guide t'emmène de zéro à une image terminée en cinq étapes : crée une clé,
vérifie-la, envoie une génération, interroge le résultat et télécharge-le. Chaque
appel vise la base URL :

```
https://api.samsa.ai/public/v1
```

<Note>
  Les exemples utilisent une fausse clé (`samsa_sk_example…`) et des ids
  d'exemple. Remplace-les par les tiens. Stocke ta clé dans une variable
  d'environnement pour qu'elle n'atterrisse jamais dans ton gestionnaire de
  versions :

  ```bash theme={null}
  export SAMSA_API_KEY="samsa_sk_exampleXf9Lp2QyaBcDeFgHiJkLmNoPqRsTuVwx"
  ```
</Note>

## Créer une API key

Les API keys appartiennent à l'**organisation** et ne peuvent être créées que par
un **admin** de l'organisation (`OWNER` ou `ADMIN`).

<Steps>
  <Step title="Ouvre les paramètres de ton organisation">
    Dans l'[app Samsa](https://app.samsa.ai), va dans les paramètres de ton
    organisation et ouvre l'onglet **API Keys**.
  </Step>

  <Step title="Crée une clé">
    Donne un nom à la clé. Par défaut, elle reçoit **tous les scopes**
    (`images.generate`, `images.edit`, `videos.generate`, `models.read`,
    `models.write`, `usage.read`) ; restreins-les si l'intégration a besoin de
    moins. Tu peux aussi définir une expiration optionnelle.
  </Step>

  <Step title="Copie la clé maintenant">
    <Warning>
      La clé complète (`samsa_sk_…`) est affichée **exactement une fois**, à la
      création. Samsa n'en stocke qu'un hash et ne pourra jamais l'afficher de
      nouveau. Copie-la immédiatement et garde-la en lieu sûr — si tu la perds,
      révoque la clé et crées-en une nouvelle.
    </Warning>
  </Step>
</Steps>

Les clés agissent **pour leur organisation** : les credits sont prélevés sur le
pool de l'organisation, et toutes les images ou vidéos que tu génères apparaissent
dans l'app sous le compte de l'admin qui a créé la clé.

## Vérifier la clé avec `GET /me`

`GET /me` est le moyen le plus rapide de confirmer qu'une clé fonctionne. Il
renvoie l'organisation de la clé, ses métadonnées sûres (préfixe, scopes,
expiration — jamais le secret) et le solde de credits disponible de
l'organisation.

<CodeGroup>
  ```bash curl theme={null}
  curl https://api.samsa.ai/public/v1/me \
    -H "Authorization: Bearer $SAMSA_API_KEY"
  ```

  ```python Python theme={null}
  import os
  import requests

  BASE_URL = "https://api.samsa.ai/public/v1"
  API_KEY = os.environ["SAMSA_API_KEY"]
  HEADERS = {"Authorization": f"Bearer {API_KEY}"}

  resp = requests.get(f"{BASE_URL}/me", headers=HEADERS)
  resp.raise_for_status()
  print(resp.json())
  ```

  ```typescript TypeScript theme={null}
  const BASE_URL = "https://api.samsa.ai/public/v1";
  const API_KEY = process.env.SAMSA_API_KEY!;
  const headers = { Authorization: `Bearer ${API_KEY}` };

  const resp = await fetch(`${BASE_URL}/me`, { headers });
  if (!resp.ok) throw new Error(`GET /me failed: ${resp.status}`);
  console.log(await resp.json());
  ```
</CodeGroup>

```json Response theme={null}
{
  "organization": {
    "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
    "name": "Acme Inc"
  },
  "api_key": {
    "id": "9c8d7e6f-5a4b-4c3d-2e1f-0a9b8c7d6e5f",
    "name": "Production key",
    "prefix": "samsa_sk_exam",
    "scopes": [
      "images.edit",
      "images.generate",
      "models.read",
      "models.write",
      "usage.read",
      "videos.generate"
    ],
    "expires_at": null
  },
  "credits": {
    "available": 1450
  }
}
```

## Générer une image

Envoie un prompt à `POST /images/generations`. Ici, nous composons aussi l'un des
modèles **style** entraînés de l'organisation en passant son id ou son nom comme
`style_id` — un nom est résolu vers un modèle visible pour toi. Tu peux combiner
`object_ids`, `person_ids`, `setting_ids` et un `color_palette_id` de la même façon
— chacun par nom ou id. La requête renvoie `202`
immédiatement avec un
`id` de job ; l'image est produite de façon asynchrone.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.samsa.ai/public/v1/images/generations \
    -H "Authorization: Bearer $SAMSA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "prompt": "A minimalist product shot of a ceramic mug on linen, soft daylight",
      "style_id": "2b9d1f7a-3c4e-4a5b-9c8d-0e1f2a3b4c5d",
      "aspect_ratio": "1:1",
      "resolution": "1K",
      "num_outputs": 1
    }'
  ```

  ```python Python theme={null}
  payload = {
      "prompt": "A minimalist product shot of a ceramic mug on linen, soft daylight",
      "style_id": "2b9d1f7a-3c4e-4a5b-9c8d-0e1f2a3b4c5d",
      "aspect_ratio": "1:1",
      "resolution": "1K",
      "num_outputs": 1,
  }

  resp = requests.post(
      f"{BASE_URL}/images/generations",
      headers={**HEADERS, "Content-Type": "application/json"},
      json=payload,
  )
  resp.raise_for_status()
  job = resp.json()
  generation_id = job["id"]
  print(job)
  ```

  ```typescript TypeScript theme={null}
  const payload = {
    prompt: "A minimalist product shot of a ceramic mug on linen, soft daylight",
    style_id: "2b9d1f7a-3c4e-4a5b-9c8d-0e1f2a3b4c5d",
    aspect_ratio: "1:1",
    resolution: "1K",
    num_outputs: 1,
  };

  const submit = await fetch(`${BASE_URL}/images/generations`, {
    method: "POST",
    headers: { ...headers, "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
  if (!submit.ok) throw new Error(`generation failed: ${submit.status}`);
  const job = await submit.json();
  const generationId = job.id;
  console.log(job);
  ```
</CodeGroup>

```json Response — 202 Accepted theme={null}
{
  "id": "7f9c0e2a-1b3d-4c5e-8f6a-9b0c1d2e3f40",
  "status": "pending",
  "estimated_credits": 5
}
```

<Note>
  Le moteur par défaut est `nano_banana_pro` (passe `engine` pour choisir
  `nano_banana_2`). `num_outputs` vaut **1** par défaut ; chaque output coûte `5`
  credits en `1K`, mis à l'échelle selon la résolution (`1K` ×1, `2K` ×2, `4K`
  ×4). Le `style_id` — un id ou un nom — doit référencer un modèle `completed`
  visible pour toi.
</Note>

## Interroger le résultat

Interroge `GET /images/generations/{id}` jusqu'à ce que `status` soit `completed`
(ou `failed`). Les statuts sont `pending`, `processing`, `completed`, `failed` et
`cancelled`.

<CodeGroup>
  ```bash curl theme={null}
  curl https://api.samsa.ai/public/v1/images/generations/7f9c0e2a-1b3d-4c5e-8f6a-9b0c1d2e3f40 \
    -H "Authorization: Bearer $SAMSA_API_KEY"
  ```

  ```python Python theme={null}
  import time

  while True:
      resp = requests.get(
          f"{BASE_URL}/images/generations/{generation_id}",
          headers=HEADERS,
      )
      resp.raise_for_status()
      result = resp.json()
      if result["status"] in ("completed", "failed", "cancelled"):
          break
      time.sleep(2)

  print(result)
  ```

  ```typescript TypeScript theme={null}
  async function poll(id: string) {
    while (true) {
      const resp = await fetch(`${BASE_URL}/images/generations/${id}`, { headers });
      if (!resp.ok) throw new Error(`poll failed: ${resp.status}`);
      const result = await resp.json();
      if (["completed", "failed", "cancelled"].includes(result.status)) {
        return result;
      }
      await new Promise((r) => setTimeout(r, 2000));
    }
  }

  const result = await poll(generationId);
  console.log(result);
  ```
</CodeGroup>

```json Response — completed theme={null}
{
  "id": "7f9c0e2a-1b3d-4c5e-8f6a-9b0c1d2e3f40",
  "status": "completed",
  "created_at": "2026-07-02T12:00:00Z",
  "credits_used": 5,
  "images": [
    {
      "id": "d4c3b2a1-6f5e-4b3a-9d8c-1e0f2a3b4c5d",
      "url": "https://cdn.samsa.ai/user-.../7f9c0e2a.png?X-Amz-Signature=...",
      "thumbnail_url": "https://cdn.samsa.ai/user-.../7f9c0e2a-thumb.png?X-Amz-Signature=...",
      "width": 1024,
      "height": 1024,
      "seed": 128390
    }
  ],
  "error": null
}
```

## Télécharger le résultat

Chaque entrée dans `images` porte une presigned URL HTTPS `url` valable **24
heures** — télécharge et stocke l'asset avant son expiration.

<CodeGroup>
  ```bash curl theme={null}
  curl -o mug.png \
    "https://cdn.samsa.ai/user-.../7f9c0e2a.png?X-Amz-Signature=..."
  ```

  ```python Python theme={null}
  image_url = result["images"][0]["url"]
  img = requests.get(image_url)
  img.raise_for_status()
  with open("mug.png", "wb") as f:
      f.write(img.content)
  ```

  ```typescript TypeScript theme={null}
  const imageUrl = result.images[0].url;
  const img = await fetch(imageUrl);
  const buffer = Buffer.from(await img.arrayBuffer());
  await import("node:fs/promises").then((fs) => fs.writeFile("mug.png", buffer));
  ```
</CodeGroup>

## Étapes suivantes

<CardGroup cols={2}>
  <Card title="Référence API" icon="terminal" href="/fr/api-reference/introduction">
    La base URL, l'authentification et les conventions communes à chaque endpoint.
  </Card>

  <Card title="MCP server" icon="plug" href="/fr/mcp-server">
    Connecte Samsa à Claude, ChatGPT ou n'importe quel client MCP et génère des
    médias sous forme d'outils — via OAuth ou une API key.
  </Card>
</CardGroup>

<Tip>
  Tu préfères le push plutôt que le polling ? Passe un `webhook_url` sur n'importe
  quelle requête de génération pour recevoir un callback signé dès l'instant où le
  job atteint un statut terminal.
</Tip>
