# Organization

These routes publish what the console's Organization and API Keys
pages show: who is in your organization, who is invited, which API
tokens exist, and what each token has done.

| Route | What it serves |
|---|---|
| `GET /api/org/members` | the roster, the auto join rules, the outstanding invitations |
| `GET /api/org/tokens` | every API token the organization holds, as metadata |
| `GET /api/org/tokens/{token_id}/activity` | one token's activity trail; `self` is the calling token |
| `DELETE /api/org/tokens/self` | the calling token revokes itself |
| `GET /api/org/activity` | the organization's trail: every member's and every token's recorded write, newest first |

Contract: [`GET /api/org/openapi.json`](https://nationalcompute.com/api/org/openapi.json).

Every route takes an org API token. The organization is the token's
own and nothing identifies it on the wire. Any of your organization's
tokens reads these routes, cluster bound or org wide. The one write is
a token revoking itself. Adding or removing a member, adding a rule,
minting a token, and revoking another token are console actions.
Removing a member revokes every token that member minted, and retiring
the organization revokes every token it holds; those revokes appear in
the [activity trail](#activity) under the actor `system:offboard`.

## Members and invitations

```sh
curl -H "Authorization: Bearer $NC_TOKEN" \
  https://nationalcompute.com/api/org/members
```

`members[]` is the roster: `username`, `email`, `name`, `is_active`
(`false` when the identity provider has suspended the account; `true`
means active, or unknown while the identity provider read is degraded),
`last_login` (RFC 3339, or `null`), and `role`. Every member holds the
one organization role, `admin`. When the identity provider read is
degraded, `email` and `name` read empty and `last_login` reads `null`
rather than stale.

`rules[]` are the auto join rules, each `{id, kind, value}`. A `domain`
rule admits every sign in whose email carries that domain. An `email`
rule invites one address. `invited[]` lists the email rules no member
has consumed yet, the rows the console shows as Invited. An invitation
counts as consumed once a member carries the email, or its username
form when the identity provider read is degraded. An invitation made
from the console also emails that address a one time sign in link. The
link is currently valid for 3 days. A member who signs in with a Google
account under that address can ignore the link.

## Tokens

```sh
curl -H "Authorization: Bearer $NC_TOKEN" \
  https://nationalcompute.com/api/org/tokens
```

`tokens[]` lists every token, live and inactive, newest first:
`token_id` (the middle segment of `national_compute_<id>_<secret>`),
`name`, `scopes` as recorded at mint, `cluster` (the bound cluster, or
`null` for an org wide token), `expires_at`, `created_by`,
`created_at`, `last_used_at`, and `revoked_at` (`null` while live). A
secret is shown once, at mint, on the console. It never appears here,
and neither does its hash. The organization's kind, `standard` or
`public_research`, is on
[`GET /api/whoami`](https://docs.nationalcompute.com/authentication.md#discovering-what-a-token-can-address)
as `org_kind`.

## Activity

```sh
curl -H "Authorization: Bearer $NC_TOKEN" \
  https://nationalcompute.com/api/org/tokens/self/activity
```

The trail of one token, newest first. `self` is the calling token; a
`token_id` from the token list reads any token of your organization.
An id outside your organization reads `404 not-found`, the same as an
unknown id.

`entries[]` are the console audit rows the token wrote as actor. Writes
are always recorded: capacity declares and swaps, limit prices, ssh key adds
and revokes. The token's own mint and revoke rows are included, with
the console user who performed them as `actor`. Two reads are recorded
on every call as well, the VM capacity read and the ssh key list. Those
rows stay out of the trail unless you pass `reads=1`. Other reads are
not recorded. `last_used_at` on the token list says whether a token is
in use.

Each entry carries `id`, `ts` (RFC 3339 UTC), `actor` (`token:<id>`
for the token's own calls), `action` (for example `vm_capacity_put`,
`k8s_bid_put`, `vm_key_add`, `vm_token_mint`, `vm_token_revoke`; with
`reads=1` also `vm_capacity_get` and `vm_keys_get`), `subject` (a
cluster name, or the organization for key and token rows), and
`detail` (the recorded arguments, free text).

Paging is by entry id. `limit` is 100 by default and clamps to 500.
When `more` is `true`, pass the last entry's `id` as `before` for the
next page. A `limit` or `before` that is not an integer, a `before`
that is not positive, or a `reads` other than `1` or `0` reads
`422 bad-request`.

The console shows the same trail: the API Keys page has an Activity
toggle on every token row, with a show reads switch in the panel. On
the MCP server the token list and both trails are
[`grid_api` paths](https://docs.nationalcompute.com/api/mcp.md#grid_api-paths); `self` names no token there.

## The organization's trail

```sh
curl -H "Authorization: Bearer $NC_TOKEN" \
  https://nationalcompute.com/api/org/activity
```

Every recorded write in your organization, newest first, human and
token side by side. Three kinds of rows arrive: every write any of
your tokens made, every row about the organization itself (token mint
and revoke, the spend limit, the billing pages, member and rule
changes), and your members' console writes on your clusters, tied to
each cluster's own island. A limit price or a capacity declaration a member set
on the console reads here with the member as `actor`, so an agent
learns whose hand moved a ceiling before it acts on the change.
Platform admin actions on your clusters are not included. Platform
system rows about the organization are. A console row whose actor ties
to no member, or whose cluster is not one of yours on its island, reads
absent. Rows of another organization never appear, even from a cluster
elsewhere that carries your organization's name or from a person who
belongs to both organizations.

Entries carry the same fields as the token trail. Read rows hide
unless `reads=1`. Paging is by entry id: `limit` is 100 by default and
clamps to 500, and when `more` is `true`, pass the last entry's `id` as
`before`. The response is `{org_id, entries, more}`.

## Rate limit

Every token carries a budget of requests per minute across all routes
(300 by default; the vm contract states the figure in force). The call
past it reads `429 rate-limited` with `retry_after_s`, and the
`Retry-After` header carries the same figure.

## Revoking your own token

```sh
curl -X DELETE -H "Authorization: Bearer $NC_TOKEN" \
  https://nationalcompute.com/api/org/tokens/self
```

The calling token stops working at once. The next call with it reads
`401 unauthorized`. The response is `{ok, token_id, revoked_at}`. The
audit row carries `actor` `token:<id>`, so the trail shows the token
closing itself. No token can revoke another token. That stays a console
action on the API Keys page.
