> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.rightbrain.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.rightbrain.ai/_mcp/server.

# Create a task

> Create a Rightbrain task with a single API call — pick a model, define a prompt with a typed input and a structured output, and get back a versioned task.

A **task** is a structured AI function: a prompt with typed inputs, a chosen model, and a typed output. Agents call tasks as tools, and you can run them standalone from your own code. This quickstart creates one with a single API call.

> **Info**
>
> **What you'll build**: a task that reads a customer review and classifies its sentiment, with output fields ready to verify an attached product image once you enable file input. The [next page](/docs/quickstart/run-and-observe) runs it.

## Before you start

Every request is authenticated with a bearer token. Create an API key under **Settings → API Clients** in your dashboard, then export it and the [organization and project IDs](/docs/concepts/projects-and-orgs) that scope your resources.

```bash
export RB_TOKEN="your-api-key"
export RB_ORG="{org_id}"
export RB_PROJECT="{project_id}"
```

For the full set of auth methods — OAuth 2.0, PKCE, task access tokens — see [Authentication](/docs/api/authentication).

#### Pick a model

Tasks run on a model you choose. List the models available to your project and copy an `id`. So the same task can later verify an attached image, filter to vision-capable models with `?vision=image`.

**`List vision-capable models`**

```bash title="List vision-capable models"
curl "https://app.rightbrain.ai/api/v1/org/$RB_ORG/project/$RB_PROJECT/model?vision=image" \
  -H "Authorization: Bearer $RB_TOKEN"
```

The endpoint returns a plain array. Each entry carries an `id`, a human-readable `alias`, `supports_vision`, and coarse `price` and `speed` tiers.

```json
[
  {
    "id": "ec217e75-72ea-4281-a1b8-cb7bd0ef9f41",
    "name": "claude-sonnet-4-5",
    "alias": "Claude Sonnet 4.5",
    "provider": "anthropic",
    "supports_vision": true,
    "price": "average",
    "speed": "fast"
  }
]
```

Save the `id` you want as `RB_MODEL` — the next step reads it. (`llm_model_id` requires the model's `id`, not its name.)

```bash
export RB_MODEL="{model_id}"
```

#### Create the task

Send a `POST` to the `task` endpoint. The `user_prompt` holds a `{customer_review}` placeholder — that becomes the task's typed input. The `output_format` defines the structured response you get on every run.

**`cURL`**

```bash title="cURL"
curl -X POST https://app.rightbrain.ai/api/v1/org/$RB_ORG/project/$RB_PROJECT/task \
  -H "Authorization: Bearer $RB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sentiment Analyzer",
    "enabled": true,
    "llm_model_id": "'"$RB_MODEL"'",
    "system_prompt": "You are an expert product-review analyst specializing in e-commerce sentiment analysis and visual verification.",
    "user_prompt": "Analyze the sentiment of this customer review, and describe the product image if one is attached, noting whether it matches the product in the review: {customer_review}",
    "output_format": {
      "sentiment": { "type": "string", "options": ["positive", "neutral", "negative"] },
      "image_description": { "type": "string", "description": "A description of the product image, or \"N/A\" if none was provided" },
      "image_match": { "type": "boolean", "description": "Whether the image matches the product described in the review" }
    }
  }'
```

**`Python`**

```python title="Python"
import os, requests

base = f"https://app.rightbrain.ai/api/v1/org/{os.environ['RB_ORG']}/project/{os.environ['RB_PROJECT']}"
headers = {"Authorization": f"Bearer {os.environ['RB_TOKEN']}"}

payload = {
    "name": "Sentiment Analyzer",
    "enabled": True,
    "llm_model_id": os.environ["RB_MODEL"],
    "system_prompt": "You are an expert product-review analyst specializing in e-commerce sentiment analysis and visual verification.",
    "user_prompt": "Analyze the sentiment of this customer review, and describe the product image if one is attached, noting whether it matches the product in the review: {customer_review}",
    "output_format": {
        "sentiment": {"type": "string", "options": ["positive", "neutral", "negative"]},
        "image_description": {"type": "string", "description": 'A description of the product image, or "N/A" if none was provided'},
        "image_match": {"type": "boolean", "description": "Whether the image matches the product described in the review"},
    },
}

task = requests.post(f"{base}/task", headers=headers, json=payload).json()
print(task["id"])
```

**`TypeScript`**

```typescript title="TypeScript"
const base = `https://app.rightbrain.ai/api/v1/org/${process.env.RB_ORG}/project/${process.env.RB_PROJECT}`;
const headers = {
  Authorization: `Bearer ${process.env.RB_TOKEN}`,
  "Content-Type": "application/json",
};

const response = await fetch(`${base}/task`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    name: "Sentiment Analyzer",
    enabled: true,
    llm_model_id: process.env.RB_MODEL,
    system_prompt:
      "You are an expert product-review analyst specializing in e-commerce sentiment analysis and visual verification.",
    user_prompt:
      "Analyze the sentiment of this customer review, and describe the product image if one is attached, noting whether it matches the product in the review: {customer_review}",
    output_format: {
      sentiment: { type: "string", options: ["positive", "neutral", "negative"] },
      image_description: {
        type: "string",
        description: 'A description of the product image, or "N/A" if none was provided',
      },
      image_match: {
        type: "boolean",
        description: "Whether the image matches the product described in the review",
      },
    },
  }),
});

const task = await response.json();
console.log(task.id);
```

#### Read the created task

The response is the task, created with an initial revision that is automatically active (`active_revisions` carries one revision at weight `1.0`). Save the `id` — you'll run this task on the next page.

```json
{
  "id": "0195d1ff-1f05-437a-95ac-6de8969cb47b",
  "name": "Sentiment Analyzer",
  "enabled": true,
  "output_modality": "json",
  "active_revisions": [
    {
      "task_revision_id": "0195d1ff-1f42-f14e-8b65-641baf9dc32e",
      "weight": 1.0
    }
  ]
}
```

> **Tip**
>
> Give every output field a clear description and, where the answer is a fixed set, an `options` list. Constrained fields keep values inside a known set, which is what lets downstream code trust the output. See [Tasks](/docs/concepts/tasks) for nested and constrained output.

## What's next

#### [Run and observe](/docs/quickstart/run-and-observe)

Run your task over the API and read the response.

#### [Build your first agent](/docs/quickstart/first-agent)

Attach this task to an agent and run it with streaming.