# Quickstart

> Get an API key, send your SuperCool agent a message, wait for the work to finish and download the files, with curl, Python or JavaScript.

Source: https://supercool.com/docs/api/quickstart

This takes about five minutes, plus however long the agent takes to make what you asked for. You need a SuperCool account. Any plan works.

## 1. Get an API key

Open the [API dashboard](https://supercool.com/dashboard#api) (**Dashboard → API**) and create a key. Give it a nickname, like "prod server" or "my laptop". The full key (`sc_key_…`) is shown once, so copy it now.

Put it in an environment variable. Never commit it or ship it to a browser.

```bash
export SUPERCOOL_API_KEY="sc_key_..."
```

Check that it works:

```bash
curl https://api.supercool.com/v1/me -H "Authorization: Bearer $SUPERCOOL_API_KEY"
```

You should see your account, your plan, your available `credits` and your agent's name.

## 2. Send a message

Tell the agent what you want in plain language. The `Idempotency-Key` header makes the request safe to retry: if the connection drops and you send it again with the same key, you get the same message back instead of starting the work twice.

```bash tab="curl"
curl https://api.supercool.com/v1/messages \
  -H "Authorization: Bearer $SUPERCOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"message": "A 15 second vertical ad for my candle shop, warm and cozy"}'
```

```python tab="Python"
import os
import uuid

import requests

API = "https://api.supercool.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['SUPERCOOL_API_KEY']}"}

resp = requests.post(
    f"{API}/messages",
    headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
    json={"message": "A 15 second vertical ad for my candle shop, warm and cozy"},
    timeout=60,
)
resp.raise_for_status()
msg = resp.json()
print(msg["id"], msg["status"], msg["reply"])
```

```js tab="JavaScript"
// Node 18+ (save as quickstart.mjs)
import { randomUUID } from "node:crypto";

const API = "https://api.supercool.com/v1";
const headers = { Authorization: `Bearer ${process.env.SUPERCOOL_API_KEY}` };

const res = await fetch(`${API}/messages`, {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json", "Idempotency-Key": randomUUID() },
  body: JSON.stringify({ message: "A 15 second vertical ad for my candle shop, warm and cozy" }),
});
const msg = await res.json();
console.log(msg.id, msg.status, msg.reply);
```

The call returns within about 30 seconds. For a video, the agent replies and starts the work, so the message comes back as `processing` with one running job:

```json
{
  "id": "msg_3f9a1c2e7b8d4e5f6a7b8c9d",
  "object": "message",
  "status": "processing",
  "final": false,
  "reply": "On it. I'm making a 15 second vertical ad with warm candlelight shots.",
  "jobs": [
    {
      "job_id": "exe_9b2c4d6e8f0a1b3c5d7e9f1a2b4c6d8e",
      "work_id": "5d0c3e2a-8f1b-4c6d-9e7f-1a2b3c4d5e6f",
      "title": "Candle shop vertical ad",
      "status": "running",
      "link": "https://supercool.com/chat/5d0c3e2a-8f1b-4c6d-9e7f-1a2b3c4d5e6f",
      "files": []
    }
  ],
  "files": [],
  "credits_used": 0
}
```

A simple question ("what's a good tagline for a candle shop?") comes back `completed` right away, with the answer in `reply`.

## 3. Wait for the result

Call `GET /v1/messages/{id}` with `?wait=30`. The call holds for up to 30 seconds and returns as soon as something changes. Repeat until `final` is `true`.

```bash tab="curl"
curl "https://api.supercool.com/v1/messages/msg_3f9a1c2e7b8d4e5f6a7b8c9d?wait=30" \
  -H "Authorization: Bearer $SUPERCOOL_API_KEY"
```

```python tab="Python"
while not msg["final"]:
    if msg.get("resume") == "add_credits":
        print("Out of credits: add some before", msg["resume_by"], "and the work resumes by itself.")
        break
    resp = requests.get(f"{API}/messages/{msg['id']}", headers=HEADERS, params={"wait": 30}, timeout=60)
    resp.raise_for_status()
    msg = resp.json()
    for job in msg["jobs"]:
        print(f"  {job['title']}: {job['status']}")

print("Finished:", msg["status"], msg["reason"] or "")
```

```js tab="JavaScript"
let current = msg;
while (!current.final && current.resume !== "add_credits") {
  const r = await fetch(`${API}/messages/${current.id}?wait=30`, { headers });
  current = await r.json();
  for (const job of current.jobs) console.log(`  ${job.title}: ${job.status}`);
}
console.log("Finished:", current.status, current.reason ?? "");
```

When the video is done, the message is `completed`, `final` is `true`, and `files` lists what the agent made:

```json
{
  "id": "msg_3f9a1c2e7b8d4e5f6a7b8c9d",
  "status": "completed",
  "final": true,
  "files": [
    {
      "file_id": "5d0c3e2a-8f1b-4c6d-9e7f-1a2b3c4d5e6f/candle_ad.mp4",
      "name": "candle_ad.mp4",
      "content_type": "video/mp4",
      "kind": "video",
      "size": 4812345,
      "url": "https://api.supercool.sh/api/v1/files/s/eyJmIjoiNWQwYzNl..."
    }
  ],
  "credits_used": 42.5
}
```

Other outcomes, like `needs_input` (the agent has a question), `blocked` (out of credits) or `partial`, are explained in [Getting results](https://supercool.com/docs/api/results#statuses).

## 4. Download the files

Each file's `url` is a signed link, so you don't need to send your API key with it. Download it like any URL:

```bash tab="curl"
curl -L -o candle_ad.mp4 "https://api.supercool.sh/api/v1/files/s/eyJmIjoiNWQwYzNl..."
```

```python tab="Python"
for f in msg["files"]:
    with requests.get(f["url"], stream=True, timeout=300) as r:
        r.raise_for_status()
        with open(f["name"], "wb") as out:
            for chunk in r.iter_content(chunk_size=1 << 20):
                out.write(chunk)
    print("Saved", f["name"])
```

```js tab="JavaScript"
import { writeFile } from "node:fs/promises";

for (const f of current.files) {
  const r = await fetch(f.url);
  if (!r.ok) throw new Error(`download failed: ${r.status}`);
  await writeFile(f.name, Buffer.from(await r.arrayBuffer()));
  console.log("Saved", f.name);
}
```

Links expire. If one has, or if the download answers `412` because the file changed since the link was made, get a fresh one from [`GET /v1/files/{file_id}`](https://supercool.com/docs/api/files#fresh-links).

## Next steps

- **Skip polling:** register a [webhook](https://supercool.com/docs/api/webhooks) and get a signed POST when the message is done.
- **Send files:** attach images, PDFs or footage to a message. See [Files & uploads](https://supercool.com/docs/api/files).
- **Follow up:** send another message like "make it 9:16 and add captions" and the agent continues the same work. See [Sending messages](https://supercool.com/docs/api/messages#follow-ups).
- **Handle every outcome:** read [Getting results](https://supercool.com/docs/api/results) and [Rate limits & errors](https://supercool.com/docs/api/errors).
- **Watch it in the app:** every job's `link` opens its chat in SuperCool.
