# Task APIs

> Every Refabric task is called the same way: send its input, get a job, read the job's files.

A **task** is one piece of fashion work with a name — `image.generate`, `image.change_background`,
`photoshoot.create`. Its input and output are published as JSON Schema in the catalogue
(`GET /v1/tasks/{name}`) and on its page in the [Task API Reference](https://docs.refabric.com/task-api-reference).

A task call does not answer with the result. It starts a **job**, and the job delivers **files**:
images, videos, SVGs, PDFs or a record. You choose how to learn that the job has ended.

## Quick example

::::code-group
```python
import os, time, requests

API = "https://api.refabric.com/v1"
s = requests.Session()
s.headers["Authorization"] = f"Key {os.environ['REFABRIC_API_KEY']}"

job = s.post(f"{API}/tasks/image.generate", json={"prompt": "a navy linen shirt dress, studio photo"}).json()
while (status := s.get(job["status_url"]).json())["lifecycle"] != "terminal":
    time.sleep(5)
print(s.get(job["result_url"]).json()["files"])
```

```javascript
const API = "https://api.refabric.com/v1";
const headers = { Authorization: `Key ${process.env.REFABRIC_API_KEY}`, "Content-Type": "application/json" };

const job = await (await fetch(`${API}/tasks/image.generate`, {
  method: "POST", headers, body: JSON.stringify({ prompt: "a navy linen shirt dress, studio photo" }),
})).json();
let status;
do {
  await new Promise((r) => setTimeout(r, 5000));
  status = await (await fetch(job.status_url, { headers })).json();
} while (status.lifecycle !== "terminal");
console.log((await (await fetch(job.result_url, { headers })).json()).files);
```

```bash
curl -s -X POST "https://api.refabric.com/v1/tasks/image.generate" \
  -H "Authorization: Key $REFABRIC_API_KEY" -H "Content-Type: application/json" \
  -d '{"prompt": "a navy linen shirt dress, studio photo"}'
# then: curl -s "<status_url>" … until "lifecycle": "terminal", then curl -s "<result_url>" …
```
::::

Every task follows the same pattern: `POST /v1/tasks/{name}` answers `202` with a `job_id` and its
`status_url`, `result_url` and `cancel_url`; the job's result lists its files in one shape
([Files and media](https://docs.refabric.com/task-apis/files-and-media)). Only the input differs from task to task.

## How it works

| Way | How | When |
|---|---|---|
| **Submit and poll** | read `status_url` until `lifecycle` is `terminal`, then `result_url` | the default; works everywhere ([Asynchronous jobs](https://docs.refabric.com/task-apis/calling-tasks/asynchronous-jobs)) |
| **Wait** | send `Prefer: wait=N`; a job that ends in time answers `200` with its result | short jobs ([Synchronous](https://docs.refabric.com/task-apis/calling-tasks/synchronous)) |
| **Webhook per job** | add `?webhook_url=` to the submit; we call you when the job ends | one-off jobs whose caller can receive a `POST` ([Webhooks](https://docs.refabric.com/task-apis/calling-tasks/webhooks#asking-for-a-callback)) |
| **Registered webhook endpoints** | register an endpoint once in **Panel › Developers › Webhooks** | every job started with your keys; progress events too ([Webhooks](https://docs.refabric.com/task-apis/calling-tasks/webhooks)) |

Before you submit, `POST /v1/tasks/{name}/estimate` with the same body tells you the most the job can
cost ([Pricing](https://docs.refabric.com/task-apis/pricing)).

## What you can make

The catalogue groups its tasks by category (`category` on every task). The categories, what each
one makes and its tasks are listed live on [All tasks](https://docs.refabric.com/task-api-reference); the category values
are the [`task_category`](https://docs.refabric.com/task-apis/vocabularies-and-concepts#task_category) vocabulary.

## Next steps

::::cards
:::card{title="Common task arguments" href="/task-apis/common-task-arguments"}
The inputs many tasks share, and how they behave.
:::
:::card{title="Calling tasks" href="/task-apis/calling-tasks/overview"}
Choose between polling, waiting and webhooks.
:::
:::card{title="Headers" href="/task-apis/headers"}
The request options that are not task inputs.
:::
::::
