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

# Scopes

> Three presets, the capabilities underneath them, and which of the four calls each one reaches.

A scope is a named preset chosen when a key is minted. It expands into a list
of capabilities, and that list is what the key carries; the preset name is not
stored. Renaming or redefining a preset later cannot change an existing key.

## The three presets

| Preset | Expands to |
| - | - |
| **Locality** | `frame.read`, `locality.query`, `layer.read`, `project.read` |
| **Analyst** | Locality, plus `ask.query` and `stats.read` |
| **Full read** | Analyst, plus `feature.read` and `dashboard.read` |

## What each preset reaches

| Call | Needs | Locality | Analyst | Full read |
| - | - | :-: | :-: | :-: |
| `GET /v1/frames/at` | `frame.read` | ● | ● | ● |
| `GET /v1/frames` | `frame.read` | ● | ● | ● |
| `GET /v1/frames/data`, baseline rows | `frame.read` | ● | ● | ● |
| `GET /v1/frames/data`, features of point, line and polygon datasets | `feature.read` | | | ● |
| `POST /v1/frames/insight` | `ask.query` | | ● | ● |

So a **Locality** key resolves locations to frames and reads the baselines
recorded on them: administrative identity, population, buildings, physical
setting, culture, and any baseline the organisation has added or licensed. It
cannot ask a question, and it does not see the individual features of a
dataset of shapes. An **Analyst** key adds the question call. A **Full read**
key also sees the features bound to each frame, at most 200 per dataset per
request.

The capabilities a preset carries beyond these four calls, such as
`locality.query` or `stats.read`, exist for the app and for future calls; they
reach nothing in this reference today.

## Narrowing to datasets

A key may be narrowed to named datasets when it is minted. A narrowed key
answers `GET /v1/frames/data` and `POST /v1/frames/insight` from those datasets
alone, and the others are absent from its answers rather than refused. The
frame index itself, which `GET /v1/frames/at` and `GET /v1/frames` read, is
the platform's and is never narrowed.

## How a denial reads

The capability check happens after the key is accepted and before any data is
read, and it answers `403` naming the capability that is missing:

```json theme={null}
{
  "error": {
    "code": "insufficient_scope",
    "message": "this API key does not carry the ask.query scope"
  }
}
```

That is the only `403` these calls produce. Every preset carries `frame.read`,
so the three frame reads refuse only a key minted with an explicit capability
list that left it out. The question call is the one a Locality key meets this
on.

## Why keys are read-only

There is no write capability a key can hold, under any preset. Writes on LOCI
record who made them, and there is no honest way to record a machine as the
author of a change under the name of whoever minted its key. Until there is,
keys read and do not write. If something must be written, a person does it in
the app.


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