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

# Your first API call

> Read the signed-in user through the API, and understand what each failure means.

<Warning>
  **TODO: replace before launch.** This guide is real and it works — but it walks the template's own
  `/me` endpoint, which is plumbing rather than product. Keep it as the model for how a guide is
  written, and replace the subject with a task a customer actually performs.
</Warning>

This is the worked example the rest of the guides should look like: one task,
end to end, including the ways it fails.

## What you need

* An account that is signed in, with an active organisation ([Quickstart](/quickstart)).
* The API host, `api.scaling.cloud`. It is separate from the web application and
  carries no `/api` prefix.

## Check the API is alive

`/health` is public and takes no authentication. Start here, because it
separates "the service is down" from "my credential is wrong".

```bash theme={null}
curl -s https://api.scaling.cloud/health
```

```json Response theme={null}
{
  "status": "ok",
  "commit": "9f2c1ab"
}
```

`commit` is the revision currently serving. Quote it in bug reports — it is the
difference between a fixed bug and a stale deployment.

## Read the signed-in user

`/me` requires an authenticated caller and an active organisation. Authenticating
means signing in with OAuth, which is described in the
[API reference](/api-reference/introduction).

```bash theme={null}
curl -s https://api.scaling.cloud/me \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

TODO: replace before launch — the OAuth flow that produces `$ACCESS_TOKEN` is
not settled, and neither is the shape of the token it returns. This example
assumes a bearer token because that is the OAuth default, not because it is
decided.

```json Response theme={null}
{
  "userId": "user_2abc...",
  "organisationId": "org_2xyz...",
  "email": "ada@example.com",
  "name": "Ada Lovelace",
  "role": "admin"
}
```

`name` is nullable — an account that has never set one returns `null`. Render
around that rather than asserting it.

<Note>
  `organisationId` is taken from the verified credential and never from anything the caller sends.
  Passing an organisation in a body, query string or header does nothing, by design.
</Note>

## When it fails

Every endpoint returns the same error shape, so one handler covers all of them:

```json 401 theme={null}
{
  "code": "unauthenticated",
  "message": "...",
  "requestId": "..."
}
```

| Code              | Status | What to do                                                    |
| ----------------- | ------ | ------------------------------------------------------------- |
| `unauthenticated` | 401    | Send the user back to sign-in                                 |
| `forbidden`       | 403    | Signed in, not allowed. Do not retry                          |
| `not_found`       | 404    | The thing you asked for does not exist in this organisation   |
| `invalid_request` | 400    | The request failed validation. Fix it; retrying will not help |
| `conflict`        | 409    | Something changed underneath you. Re-read, then retry         |
| `internal`        | 500    | Our side. Report it with the `requestId`                      |

Branch on `code`, never on `message`. Messages are written for humans and get
rewritten; codes are part of the contract and changing one is a breaking change.

## Next

TODO: replace before launch — link the guide a reader would genuinely want next.
