# Agent authentication on shiken.ai

Not an agent? You are probably looking for the [developer documentation](https://shiken.ai/developers) or the [MCP setup guide](https://shiken.ai/mcp).

You are an agent. Shiken has two credentialed surfaces, and they are for different jobs. Read the first section, pick the one that matches, then follow it.

## Discover

- **Protected-resource metadata (RFC 9728):** `GET https://shiken.ai/.well-known/oauth-protected-resource` — names the organisation API resource, its authorization server and every scope it enforces.
- **Authorization-server metadata (RFC 8414):** `GET https://shiken.ai/.well-known/oauth-authorization-server` — the client-credentials token endpoint, the supported grant, and an `agent_auth` block pointing back here.
- **OpenAPI 3.1:** `GET https://shiken.ai/openapi.json` — every organisation API operation with its required scope.
- **API catalog (RFC 9727):** `GET https://shiken.ai/.well-known/api-catalog`.
- **MCP server card:** `GET https://shiken.ai/.well-known/mcp/server-card.json` — the personal MCP server, its tools and which JSON-RPC methods are public.
- **Front desk:** [https://shiken.ai/agents.md](https://shiken.ai/agents.md) and [llms.txt](https://shiken.ai/llms.txt).

## Pick a method

| You want to | Surface | Credential |
| --- | --- | --- |
| Read one person's own meetings, transcripts, notes and knowledge base | Personal MCP server at `https://app.shiken.ai/api/mcp` | That person's Shiken access token |
| Read or write an organisation's members, groups, content and analytics | Organisation API at `https://shiken.ai/api/v1` | An organisation API key, `sk_live_…` |
| Send xAPI statements from an external LMS or reporter | Learning Record Store at `https://shiken.ai/api/xapi/statements` | A bearer token from the client-credentials endpoint below |

There is no anonymous tier. Every surface is scoped to a person or an organisation.

## Register

Shiken does not implement agentic self-registration: there is no `identity_endpoint`, no dynamic client registration and no consent screen a third-party agent can drive. A human creates the credential once.

- **Personal access token:** the person signs in at https://shiken.ai and follows [the MCP guide](https://shiken.ai/mcp) to copy their access token.
- **Organisation API key:** an organisation admin opens **Settings → API** in the Shiken app and creates a key. Keys start `sk_live_` (or `sk_test_` for a test key) and are shown once. Enterprise access: [contact sales](https://shiken.ai/contact-sales).

## Claim

Not applicable — there is no device-code or claim ceremony. A credential is valid the moment it is created.

## Exchange

Only the xAPI path exchanges anything. An external reporter posts the organisation API key as the client secret and receives a bearer token:

```http
POST https://shiken.ai/api/xapi/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=<your org slug>&client_secret=<sk_live_…>
```

Client authentication may also be sent as HTTP Basic. The token is accepted by the LRS at `https://shiken.ai/api/xapi/statements`.

For the organisation API and the MCP server there is nothing to exchange: send the credential directly.

## Use

Organisation API:

```http
GET https://shiken.ai/api/v1/organizations/{orgId}/members?limit=50
Authorization: Bearer sk_live_…
Accept: application/json
```

Personal MCP server (Streamable HTTP):

```http
POST https://app.shiken.ai/api/mcp
Authorization: Bearer <Shiken access token>
Content-Type: application/json

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_recent_meetings","arguments":{"limit":5}}}
```

`initialize`, `ping` and `tools/list` need no credential, so an agent can read the tool contract before a token exists. `tools/call` needs one.

**Scopes.** An organisation key carries a list; a new key defaults to `users:read`, `content:read`, `groups:read` and `analytics:read`. A `resource:*` wildcard grants every action on that resource, and `admin` grants everything.

- `users:read` — List organisation members and their status, role and group membership.
- `users:write` — Invite or add members to the organisation.
- `content:read` — List published organisation content: quizzes, lessons, roleplays and learning paths.
- `groups:read` — List groups and their membership counts.
- `groups:write` — Create groups.
- `analytics:read` — Read organisation analytics and roleplay session records.
- `admin` — Grants every scope above.

A missing scope returns `403` with `required_scope` and `your_scopes` in the body. A key may only address its own organisation; any other `orgId` is also a `403`.

**Rate limits.** Counted per key per minute. Every response carries `X-RateLimit-Remaining`; exhausting the budget returns `429` with the limit in the message. Back off until the next minute.

**Errors.** Always JSON, never an HTML page: `{ "error": { "message": string, "status": number, "code": string, … } }`. That holds at the entry points too: an unauthenticated `GET https://shiken.ai/api/v1` (or `/api`, or `/v1`) answers `401` with the challenge above rather than a 404 page, so one probe is enough to confirm the surface exists and learn how to authenticate against it.

**Retrying safely.** Every `POST` accepts an `Idempotency-Key` header (max 255 characters; use a UUID). Send the same key on the retry:

```http
POST https://shiken.ai/api/v1/organizations/{orgId}/members
Authorization: Bearer sk_live_…
Idempotency-Key: 7c3f1e60-1d2a-4f88-9f2f-9a2f5d1e8c41
Content-Type: application/json

{"members":[{"email":"ada@example.com","role":0}]}
```

- Replayed → the original status and body, plus `Idempotency-Replayed: true`.
- Same key, different body → `422` `idempotency_key_reuse`.
- Same key while the first call is still running → `409` `idempotency_in_flight` with `Retry-After`.

Keys are scoped to (organisation, endpoint) and expire after 24 hours. Use this rather than retrying a timed-out write blind.

**Skills.** Loadable instruction documents for these surfaces are indexed at `https://shiken.ai/.well-known/agent-skills/index.json` — start with `shiken-api-integration`.

## Handle revoke

- An admin deletes an organisation key under Settings → API. A revoked key returns `401`; treat that as "obtain a new credential", not as a transient error, and surface the sign-in link to the user rather than retrying.
- A personal access token dies with the user's session. Re-authenticate the person.
- There is no revocation webhook. Do not poll for revocation; react to the `401`.

## Contact

Questions about access or volume: info@shiken.ai. Enterprise: https://shiken.ai/contact-sales.
