---
title: API overview
sidebar_title: Overview
description: Base URL, authentication, the capability matrix and the conventions every Ysra API client should follow — decimal money, idempotency keys and optimistic versions.
---

Everything the portal and mobile apps do goes through the Ysra HTTP API. These
pages cover the endpoints that are supported for your own clients and the
conventions every client should follow.

## Base URL

| Environment | Base URL |
|---|---|
| Sandbox | `https://api-sandbox.ysra.ai` |

Endpoints not documented here are internal to Ysra's own apps and may change
without notice. If you need something that isn't covered, ask us before building
on it.

## Authentication

Send a bearer token with every request:

```http
GET /developer/account/wallet HTTP/1.1
Host: api-sandbox.ysra.ai
Authorization: Bearer eyJhbGciOi…
```

Get a token from [`POST /auth/login`](authentication.md).

## Rule zero: read capabilities first

```http
GET /developer/account/capabilities
```

Fetch capabilities **before rendering or wiring any control**. Some policy
values are accepted and stored but do nothing yet, and a client that presents
them as working misleads its users. Drive enabled and disabled states from the
response; do not hard-code a capability matrix.

## Conventions

### Money is a decimal string

Every USD amount is a decimal **string**, such as `"171.750000"`. Parse it with
a decimal type; never use a binary float for arithmetic you show back to a
person.

=== "Python"

    ```python
    from decimal import Decimal

    available = Decimal(wallet["available_usd"])
    ```

=== "TypeScript"

    ```typescript
    import Big from "big.js";

    const available = new Big(wallet.available_usd);
    ```

### Mutations take an idempotency key

Wallet mutations require an `idempotency_key` (up to 255 characters). Generate
a fresh key for each logical action and **reuse the same key when retrying it**,
so a retry after a timeout cannot apply twice.

### Writes are version-checked

Resources that can be edited concurrently carry a `version`. Send the last
version you read as `expected_version`; if someone else wrote first, you get
`409 Conflict`.

!!! warning "Never retry a 409 blindly"
    Refetch, show the current state, and let the person decide again. A silent
    retry overwrites a decision someone else just made.

## Reference

<div class="cards" markdown>

- [**Authentication**](authentication.md)

    Exchange credentials for a bearer token.

- [**Wallet**](account/wallet.md)

    Budget, credits and the spending ledger.

- [**Autonomy policy**](account/policy.md)

    Account policy and per-repository overrides.

- [**Errors**](errors.md)

    Status codes and what a client should do about each.

</div>
