# Who Am I

- **Method:** `GET`
- **Path:** `/api/v1/me`
- **Operation ID:** `who_am_i`
- **Tags:** identity

Who this credential is, which tenant it spends and reads on, and what it may do.

The dashboard's first call, and deliberately the one route with no scope of its own: every credential
may ask what it is, including one whose role reads nothing else, and including an ungated request -
which answers as the `fleet` tenant, because that is whose runs an open dev API serves.

`scopes` is the *effective* answer, not the stored one: a person's role expanded through
`tenancy.ROLE_SCOPES`, a minted key's own list, and the full set for a credential that carries none.
A caller deciding which buttons to draw should never have to know that an empty list meant everything.

## Effective servers

- `https://api.saram.sh`

  Saram

## Authentication

- **HTTPBearer**: HTTP bearer

  a Saram API key (`sk_saram_<env>_...`) or a person's AuthKit access token, as `Authorization: Bearer <credential>`. Both are told apart by shape and produce the same principal.

## Responses

### 200 Successful Response

**Content type:** `application/json`

schema: `Me`, no additional properties

Who this credential is, which tenant it spends and reads on, and what it may do.

The first call a dashboard shell makes: it decides which tenant's name is in the header, whether the
members and keys screens are offered, and whether the "start a run" button is there at all. It is
deliberately answerable by *every* credential - a person's token, a minted key, a break-glass entry, an
ungated request - so that one screen works against every way of reaching this API.

- **`scopes` (required)**: `array of string`

  What this credential may actually do, already resolved: a person's role expanded to the scopes it allows, a minted key's own scopes, and the full set for a credential that carries none (a break-glass entry or an ungated request). Never an empty list - read it as the answer, not as what was stored. An operator key minted for Saram's own operations carries operator scopes instead, ops:read and on the operator page's key ops:list, which no tenant can hold, and nothing beside them.
- **`subject` (required)**: `string`

  What runs.created\_by will record for this credential: usr\_... for a person, key\_... for a minted key, operator for a break-glass entry or an ungated request.
- **`tenant` (required)**: `object`, schema: `MeTenant`, no additional properties

  The tenant the request's credential belongs to, as `GET /api/v1/me` reports it.

  Everything but `id` and `slug` is optional because the gate can answer without the row: a break-glass
  entry and an ungated request are the `fleet` tenant by construction, and on a machine with no database
  there is nothing to read the name and the plan out of.
  - **`id` (required)**: `string`
  - **`slug` (required)**: `string`
  - **`house_models`**: `boolean | null`

    True when Saram has agreed to carry this tenant's model spend: your runs may name a Saram-held credential for the actor, the judge and the reproduction check even though your plan is a bring-your-own-keys one, and your steps still bill at your plan's price. It is set by Saram per tenant and by no request; absent means the tenant row was not read.
  - **`name`**: `string | null`
  - **`plan`**: `string | null`
  - **`status`**: `string | null`
- **`caller`**: `string | null`

  The human-readable label this credential is logged and attributed under: an email or the provider subject for a person, cookai/ci for a minted key, the bare name for a break-glass entry. Absent only when no gate is configured at all.
- **`expires_at`**: `string | null`, format: `date-time`

  When this minted key stops getting through the gate, the expires\_at it was minted with. Absent for a key minted without one, for a person, whose sign-in the identity provider ends, and for a break-glass entry or an ungated request. Read here because a key that may not list keys, an operator key among them, can still ask when its own lapses.
- **`role`**: `string | null`

  owner, admin, member or viewer for a person; absent for a machine credential, which carries scopes instead.
- **`user`**: `object | null`, schema: `MeUser`, no additional properties

  The person behind an access token. Absent from `GET /api/v1/me` when the credential is a machine's.
  - **`id` (required)**: `string`
  - **`display_name`**: `string | null`
  - **`email`**: `string | null`

    Absent until the identity provider tells us one: an AuthKit access token carries no email claim unless the deployment adds one through a JWT template, and the address otherwise arrives with the user webhook.

**Example:**

```json
{
  "subject": "",
  "caller": "",
  "tenant": {
    "id": "",
    "slug": "",
    "name": "",
    "plan": "",
    "status": "",
    "house_models": true
  },
  "role": "",
  "scopes": [
    ""
  ],
  "expires_at": "",
  "user": {
    "id": "",
    "email": "",
    "display_name": ""
  }
}
```

## Schemas

- `Me` — shown above.
- `MeTenant` — shown above.
- `MeUser` — shown above.
