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

# API quickstart

> Make a key, list your projects, read your headline figures and pull a day of report rows.

**1. Make a key**

Open **Workspace settings → API keys** and choose **Create key**. Give it a name that says where it will live, so you know which one to revoke later. Every read scope is ticked for you; leave the two write scopes off for now.

The whole key is shown once, in its own box. Copy it then: after you leave the screen only its short prefix is shown. Only a workspace owner or admin can make keys.

**2. Keep it out of your code**

Put the key in an environment variable rather than in a file you commit. In a terminal, `read -rs CITINO_API_KEY && export CITINO_API_KEY` asks for the key without showing it, so it stays out of your shell history too. Every sample on this site reads the key from `CITINO_API_KEY`.

**3. List your projects**

```bash curl theme={null}
curl https://api.citino.ai/v1/projects -H "Authorization: Bearer $CITINO_API_KEY"
```

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

BASE = "https://api.citino.ai/v1"
key = os.environ["CITINO_API_KEY"]
headers = {"Authorization": f"Bearer {key}"}

projects = requests.get(f"{BASE}/projects", headers=headers)
projects.raise_for_status()
for project in projects.json()["items"]:
    print(project["id"], project["name"])
```

```javascript JavaScript theme={null}
const BASE = "https://api.citino.ai/v1";
const headers = { Authorization: `Bearer ${process.env.CITINO_API_KEY}` };

const projects = await fetch(`${BASE}/projects`, { headers });
if (!projects.ok) throw new Error(`Citino answered ${projects.status}`);
for (const project of (await projects.json()).items) {
  console.log(project.id, project.name);
}
```

Copy the `id` of the project you want. The samples below read it from `PROJECT_ID`.

**4. Read your headline figures**

The same four numbers as the top of Overview, for the last 30 days by default.

```bash curl theme={null}
curl "https://api.citino.ai/v1/projects/$PROJECT_ID/metrics" -H "Authorization: Bearer $CITINO_API_KEY"
```

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

BASE = "https://api.citino.ai/v1"
key = os.environ["CITINO_API_KEY"]
project_id = os.environ["PROJECT_ID"]

response = requests.get(
    f"{BASE}/projects/{project_id}/metrics",
    headers={"Authorization": f"Bearer {key}"},
)
response.raise_for_status()
metrics = response.json()["metrics"]
if metrics:
    visibility = metrics["visibility"]
    print(visibility["value"], "±", visibility["band"], "n =", visibility["n"])
```

```javascript JavaScript theme={null}
const BASE = "https://api.citino.ai/v1";
const headers = { Authorization: `Bearer ${process.env.CITINO_API_KEY}` };

const response = await fetch(
  `${BASE}/projects/${process.env.PROJECT_ID}/metrics`,
  { headers },
);
if (!response.ok) throw new Error(`Citino answered ${response.status}`);
const { metrics } = await response.json();
if (metrics) {
  const { value, band, n } = metrics.visibility;
  console.log(value, "±", band, "n =", n);
}
```

Each figure carries its `band` (the ± range), `n` (how many answers it rests on) and `within_noise`. Keep them with the value wherever it goes. See [Metric objects](https://docs.citino.ai/api/metric-objects.md).

**5. Pull yesterday's report rows**

One row per brand per engine for yesterday. Days are your project's market days, so yesterday is yesterday in the market's time zone (`America/New_York` for a US market): the Python and JavaScript samples read it from `MARKET_TZ`. For curl, `FROM` and `TO` are dates as `YYYY-MM-DD`; set both to that day.

```bash curl theme={null}
curl "https://api.citino.ai/v1/projects/$PROJECT_ID/reports/brands?from=$FROM&to=$TO&dimensions=date,engine" -H "Authorization: Bearer $CITINO_API_KEY"
```

```python Python theme={null}
import os
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
import requests

BASE = "https://api.citino.ai/v1"
key = os.environ["CITINO_API_KEY"]
project_id = os.environ["PROJECT_ID"]
market = ZoneInfo(os.environ["MARKET_TZ"])  # e.g. America/New_York
yesterday = (datetime.now(market).date() - timedelta(days=1)).isoformat()

response = requests.get(
    f"{BASE}/projects/{project_id}/reports/brands",
    headers={"Authorization": f"Bearer {key}"},
    params={"from": yesterday, "to": yesterday, "dimensions": "date,engine"},
)
response.raise_for_status()
for row in response.json()["items"]:
    print(row["date"], row["engine"], row["brand"]["name"], row["visibility"]["value"])
```

```javascript JavaScript theme={null}
const BASE = "https://api.citino.ai/v1";
const headers = { Authorization: `Bearer ${process.env.CITINO_API_KEY}` };
// Yesterday in the market's time zone (MARKET_TZ, e.g. America/New_York).
const today = new Intl.DateTimeFormat("en-CA", { timeZone: process.env.MARKET_TZ }).format(new Date());
const day = new Date(`${today}T00:00:00Z`);
day.setUTCDate(day.getUTCDate() - 1);
const yesterday = day.toISOString().slice(0, 10);

const query = new URLSearchParams({
  from: yesterday,
  to: yesterday,
  dimensions: "date,engine",
});
const response = await fetch(
  `${BASE}/projects/${process.env.PROJECT_ID}/reports/brands?${query}`,
  { headers },
);
if (!response.ok) throw new Error(`Citino answered ${response.status}`);
for (const row of (await response.json()).items) {
  console.log(row.date, row.engine, row.brand.name, row.visibility.value);
}
```

A report can take more than one page. Follow `next_cursor` until `has_more` is false; [Pulling data nightly](https://docs.citino.ai/api/nightly-pull.md) has the whole loop.

## Related

> [card] [Authentication](https://docs.citino.ai/api/authentication.md)
>
> Scopes, project limits, expiry and revoking a key.

> [card] [Reports](https://docs.citino.ai/api/reports.md)
>
> Dimensions, filters, budgets and paging.

> [card] [Errors](https://docs.citino.ai/api/errors.md)
>
> Every error code and what to do about it.

> [card] [API reference](https://docs.citino.ai/api-reference)
>
> Every route and its response.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.