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

# Discovering Capabilities

> Ask what your environment and credential can currently do before attempting a settlement.

`GET /v1/platforms/me/capabilities` returns an advisory snapshot of what the authenticated environment and credential can do right now: which settlement operations your credential's routes would admit, which active templates a settlement can be created from, and which chains and mechanism this deployment settles on.

Every answer is read from the same checks the mutations enforce. The snapshot never grants anything: `POST /v1/settlements` and `POST /v1/instructions` revalidate the credential, the template and the chain configuration as they are when the request arrives.

## Calling it

```bash theme={null}
curl https://api.keystoneos.xyz/v1/platforms/me/capabilities \
  -H "Authorization: Bearer {access_token}"
```

The route requires `platform:read`, a platform and an environment:

| Credential               | Environment                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------------------ |
| Client credentials (M2M) | The environment the credential is issued for                                                     |
| User token               | The `X-Keystone-Environment` header; without it the request answers `403 NO_ENVIRONMENT_CONTEXT` |

Nothing in the request selects an environment beyond that. A query parameter naming another environment is ignored, and one platform can never discover another's environment.

Session tokens cannot call this route: they are minted with settlement and template scopes only, never `platform:read`. Discover from your backend and hand the widget what it needs.

The response is served with `Cache-Control: private, no-store`.

## Reading the answer

```json theme={null}
{
  "platform_id": "0d8e8a5c-3d8b-4f6e-9b6a-1a2b3c4d5e6f",
  "environment_id": "7f1c2b3a-4d5e-6f70-8192-a3b4c5d6e7f8",
  "generated_at": "2026-09-16T12:00:00Z",
  "advisory": true,
  "freshness": "Valid only at generated_at. ...",
  "operations": {
    "settlement_read": { "enabled": true, "required_permission": "settlements:read", "unavailable_reason": null, "settlement_restricted": false },
    "settlement_create": { "enabled": true, "required_permission": "settlements:write", "unavailable_reason": null },
    "instruction_submit": { "enabled": true, "required_permission": "settlements:write", "unavailable_reason": null }
  },
  "templates": {
    "readable": true,
    "required_permission": "templates:read",
    "unavailable_reason": null,
    "page": {
      "items": [
        { "id": "9c0b1a2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d", "slug": "cross_platform_dvp", "name": "Cross-platform DvP", "version": 3, "available": true, "mechanism": "escrow", "unavailable_reason": null }
      ],
      "active_total": 2,
      "limit": 50,
      "offset": 0
    }
  },
  "chains": {
    "mechanisms": ["escrow"],
    "multi_chain_supported": false,
    "settlement_chains": [
      { "chain_id": 84532, "name": "base-sepolia", "settlement_address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" }
    ],
    "chain_locality_enforced": true,
    "execution": { "mode": "on_chain", "settlement_contract_declared": true, "writes_configured": true, "escrow_chain_id": 84532 }
  }
}
```

### Operations

Each operation reports whether its route would admit this credential, the permission the route requires, and the first refusal the route would answer:

| `unavailable_reason`            | Meaning                                                                  |
| ------------------------------- | ------------------------------------------------------------------------ |
| `insufficient_permission`       | The credential lacks `required_permission`.                              |
| `session_settlement_restricted` | A session token minted for specific settlements cannot reach this route. |
| `session_write_denied`          | A session token cannot perform this write; call it from your backend.    |

`settlement_read.settlement_restricted` is `true` for a session token minted with `settlement_ids`. The response does not list them, and it never says that any particular settlement is readable.

Funding and recovery actions on an existing settlement depend on that settlement's state and are not described here.

### Templates

`templates.page` is one page of active templates, paginated with `limit` (1 to 100, default 50) and `offset`. Each item says whether a settlement can currently be created from it:

| `unavailable_reason`  | Meaning                                                                  |
| --------------------- | ------------------------------------------------------------------------ |
| `config_invalid`      | The live configuration does not parse under the current template schema. |
| `machine_unsupported` | The template selects a machine this API has no public mechanism for.     |

`active_total` counts active templates across every page, not available ones. Inactive templates are not listed, exactly as in `GET /v1/settlement-templates`. Without `templates:read` the page is `null` and no identifier is returned.

A template can be deactivated or edited after you read the page. Creation judges the template as it is at that moment and refuses a template that is no longer usable.

### Chains

| Field                         | Meaning                                                                                                                                                                                                                                                 |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mechanisms`                  | The mechanisms this API creates and describes. Only `escrow` today; nothing else is available.                                                                                                                                                          |
| `multi_chain_supported`       | Whether the legs of one settlement may name more than one chain. `false`: a mixed-chain instruction is refused with `UNSUPPORTED_CHAIN_COMBINATION`.                                                                                                    |
| `settlement_chains`           | Registry chains carrying a settlement contract, the only chains an explicit leg `chain_id` may name. A registry entry without a contract appears in `GET /v1/chains` but not here.                                                                      |
| `chain_locality_enforced`     | `true` while `settlement_chains` is non-empty: any other explicit `chain_id` is refused with `UNSUPPORTED_SETTLEMENT_CHAIN`. `false` when no chain carries a contract, in which case any `chain_id` is admitted because nothing is registered on-chain. |
| `execution.mode`              | `on_chain` when a settlement contract is declared, so every settlement with legs is attested and registered before its deposit window. `off_chain` when none is: settlements advance with no escrow and no on-chain execution.                          |
| `execution.writes_configured` | With a declared contract, whether its write path is configured. `false` is a broken deployment whose on-chain setup halts, not an off-chain one.                                                                                                        |
| `execution.escrow_chain_id`   | The chain registrations are sent to; `null` when `off_chain`.                                                                                                                                                                                           |

Configuration is not a health probe. An advertised chain says the deployment is configured to register there; it does not say the chain is reachable, that a token qualifies, or that a settlement will execute.

## Related

* [Templates](/concepts/templates)
* [Submitting Instructions](/guides/submitting-instructions)
* [Error Codes](/guides/error-codes)
