# Quickstart

# Quickstart

Get from nothing to your first live data query in under five minutes. This page assumes you have a running Amdahl instance and can reach it over HTTPS.

## What you'll build

In this walkthrough you will authenticate to the Amdahl Platform API with an API key, confirm your business context, and run a read-only SQL query against your `interactions` data to prove the full request / response loop. Everything is plain HTTPS with JSON bodies, so the same flow works from a browser extension, a mobile client, a CLI, or a long-running agent.

## Prerequisites

- An Amdahl instance base URL. The examples below use `https://app.amdahl.co` as a placeholder. Substitute your own host (for example `https://api.amdahl.com`).
- An API key with at least `context:read` and `data:read` scopes. See [authentication.md](./authentication.md) for how to mint one.
- `curl` and `jq` installed locally. `jq` is optional but makes the examples readable.

All endpoints live under a single prefix:

```
https://app.amdahl.co/api/platform/v1
```

All requests must include your API key in the `Authorization` header:

```
Authorization: Bearer ak_live_...
```

## Step 1: Get an API key

Go to [console.amdahl.co](https://console.amdahl.co), open the workspace you want to operate against, and head to **Settings -> Developer -> Create key**. Scope the key to at least `context:read` and `data:read`, then copy the plaintext value the instant it is shown. The server stores only a SHA-256 hash and will never display the plaintext again; a lost key must be rotated, not recovered. Full details (OAuth, JWT, scope matrix, rotation) are in [authentication.md](./authentication.md).

Export it so the rest of the examples stay short:

```bash
export AMDAHL_KEY="ak_live_paste_your_key_here"
export AMDAHL_BASE="https://app.amdahl.co/api/platform/v1"
```

## Step 2: Make your first call

The fastest way to prove auth is working is to fetch your business context summary. This endpoint returns the company profile, author profiles, and a channel breakdown of your writing samples. It requires only `context:read`.

```bash
curl -s "$AMDAHL_BASE/context/summary" \
  -H "Authorization: Bearer $AMDAHL_KEY" \
  | jq
```

Expected response shape:

```json
{
  "business": {
    "id": "8b2f...",
    "name": "Acme Corp",
    "website": "https://acme.example"
  },
  "authors": [{ "id": "...", "name": "Jane Founder", "role": "CEO" }],
  "writing_samples": {
    "total": 47,
    "by_channel": { "blog": 12, "linkedin": 30, "newsletter": 5 }
  }
}
```

A 401 here means your key is missing or wrong. A 403 means your key lacks `context:read`. See [pagination-errors.md](./pagination-errors.md) for the canonical error envelope.

## Step 3: Run your first data query

`data.query` runs a read-only SQL `SELECT` against your `interactions` table, scoped to your business automatically (never put `business_id` in the `WHERE` clause). It is a `POST /data/query` call and requires `data:read`. Ask for a simple count first to prove the loop.

```bash
curl -s -X POST "$AMDAHL_BASE/data/query" \
  -H "Authorization: Bearer $AMDAHL_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "sql": "SELECT COUNT(*) AS total FROM interactions" }' \
  | jq
```

Expected response shape:

```json
{
  "columns": ["total"],
  "rows": [{ "total": 142318 }],
  "row_count": 1,
  "duration_ms": 142
}
```

A 403 here means your key lacks `data:read`. A `400` with `invalid_sql` means the query referenced a table outside your business scope or used a write statement; the surface is read-only and tenant-scoped.

## Step 4: Group the data to confirm the read loop

Now run a grouped query to see real rows come back. List-style results return `columns`, `rows`, and `row_count` so you can drive a table or a chart off them.

```bash
curl -s -X POST "$AMDAHL_BASE/data/query" \
  -H "Authorization: Bearer $AMDAHL_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "sql": "SELECT channel, COUNT(*) AS events FROM interactions GROUP BY channel ORDER BY events DESC LIMIT 5" }' \
  | jq
```

Expected response:

```json
{
  "columns": ["channel", "events"],
  "rows": [
    { "channel": "email", "events": 8421 },
    { "channel": "slack", "events": 3109 },
    { "channel": "phone", "events": 1204 }
  ],
  "row_count": 3,
  "duration_ms": 156
}
```

If `row_count` is zero, your tenant has no interactions ingested yet, or a filter was too tight. Drop the `WHERE` clause and try the bare `COUNT(*)` from Step 3 to confirm data exists.

## What's next

You now have working auth and a live read against your own data. Common next stops:

- [Sessions](./sessions.md) for agent-style flows that accumulate data across multiple tool calls.
- [Agents guide](./agents.md) for spinning up a content writer, researcher, or copilot against a task.
- [Recipes](./recipes/) for end-to-end walkthroughs: [draft a blog post](./recipes/draft-blog-post.md), [run research](./recipes/run-research.md), [react to a webhook](./recipes/react-to-webhook.md).
- [API reference](./api-reference/README.md) for the full tool catalogue, scope matrix, data models, and webhook events.
- [SDK notes](./sdk/) for curl, TypeScript, and Python idioms.

If something breaks, start with [pagination-errors.md](./pagination-errors.md) to decode the error envelope, then check [rate-limits.md](./rate-limits.md) if you are seeing `rate_limited`.
