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

# Quickstart

> Make a first authenticated request and learn the conventions every endpoint shares.

## 1. What you need

* A running Argus deployment, local or hosted.
* **Either** a browser signed in to it with Discord, **or** a service credential an administrator has issued to you.
* The permission the endpoint checks. A new account can use the civilian endpoints and nothing else; see [Permissions](/permissions).

<Note>
  Argus is an internal application API. There is nothing to sign up for, and no key you can generate yourself.
</Note>

## 2. Base URL

Every path is under `/api` on the deployment's own origin.

| Environment | Base URL |
| - | - |
| Local development | `http://localhost:3000/api` |
| A deployment | `<APP_URL>/api`, where `APP_URL` is the origin that deployment is configured with |

There is one API, with no version in the path.

## 3. A first request

<Tabs>
  <Tab title="From the web application">
    Code running on an Argus page is same-origin, so the session cookie is sent for you.

    ```js theme={null}
    const response = await fetch("/api/me", { credentials: "same-origin" });
    const { data } = await response.json();

    console.log(data.displayName, data.permissions);
    ```

    A request that changes something needs a JSON body and nothing else. The browser adds the `Origin` header Argus checks.

    ```js theme={null}
    const response = await fetch("/api/cad/me/unit/book-on", {
      method: "POST",
      credentials: "same-origin",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ callsign: "MO12", agencyCode: "MET", type: "RESPONSE" }),
    });
    ```
  </Tab>

  <Tab title="With a service credential">
    Send the token as a bearer credential. Keep it in an environment variable, never in source.

    ```bash theme={null}
    curl "$ARGUS_URL/api/sessions?status=ACTIVE" \
      -H "Authorization: Bearer $ARGUS_SERVICE_TOKEN"
    ```

    A credential can only call endpoints whose permission is among its scopes, and never the ones that need a signed-in person.
  </Tab>
</Tabs>

## 4. Reading the response

A successful response wraps its result in `data`. The examples on this page are shortened; the reference shows each full shape.

```json theme={null}
{
  "data": {
    "id": "cmg5x1k2a0000l508a1b2c3d4",
    "displayName": "Olivia Officer",
    "developerAccess": false,
    "permissions": ["cad.unit.self", "civilians.create", "civilians.manage_own", "pnc.view"]
  }
}
```

Lists add `meta`. Page with `limit` (1 to 100, default 25) and `offset` (0 to 10,000). `hasMore` tells you whether another page exists.

```json theme={null}
{
  "data": [{ "id": "cmg5z2unt000al508unt00001", "callsign": "MO12" }],
  "meta": { "limit": 25, "offset": 0, "hasMore": false }
}
```

A failure has no `data`. It carries a stable `code`, a readable `message`, and the request's ID.

```json theme={null}
{
  "error": { "code": "FORBIDDEN", "message": "Permission required: cad.view." },
  "requestId": "3f1c9d5e-7a42-4f0b-9c1e-8b6d2a4e5f70"
}
```

Branch on `error.code`, not on the message.

## 5. Permissions

Each endpoint names the permission it checks. `GET /api/me` returns the permissions in effect for you right now, which is the reliable way to decide what to offer.

* Everyone signed in holds `civilians.create` and `civilians.manage_own`.
* Everything else comes from staff roles an administrator assigns.
* Holding one permission never implies another.

## 6. Errors you will meet first

| Status and code | What happened | What to do |
| - | - | - |
| `401 UNAUTHENTICATED` | No session, or a bad credential | Sign in, or check the token |
| `401 SESSION_EXPIRED` | The session ended | Sign in again |
| `403 FORBIDDEN` | You lack the permission named in the message | Ask an administrator for the role |
| `403 INVALID_ORIGIN` | A change was sent from another origin | Call from the application's own origin |
| `400 INVALID_INPUT` | A field failed validation | Read `error.details` for each path and message |
| `409 CAD_CONFLICT` | What you sent is out of date | Re-read the record, then decide whether to retry |
| `429 RATE_LIMITED` | Too many requests this minute | Wait for `Retry-After` seconds |

[Errors](/errors) lists every status and code. [Optimistic concurrency](/concepts/optimistic-concurrency) explains the `version` field behind most 409s.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.