---
title: Your first call
description: From an API key to a successful authenticated request in three curls, before you install anything.
---

import { Callout } from "fumadocs-ui/components/callout";

# Your first call

Three requests, no dependencies. If these work, the API works, and you can decide about SDKs afterwards.

Base URL: `https://api.codespar.dev`

## 1. Prove the key

```bash
curl https://api.codespar.dev/v1/whoami \
  -H "Authorization: Bearer $CODESPAR_API_KEY"
```

```json
{
  "organization": { "id": "org_...", "name": "Your company" },
  "project": { "id": "prj_...", "name": "default" },
  "key": { "id": "key_...", "environment": "test", "scopes": ["*"] }
}
```

This is the request to run when something is not working. It answers four questions at once: whether the key is valid, which org and project it is bound to, which environment it acts in, and what it is allowed to do.

<Callout type="warn">
The `csk_test_` / `csk_live_` prefix picks the environment, **not the host**. The same base URL serves both. A test key against production data is not a thing that can happen; a live key you thought was a test key is.
</Callout>

A key belongs to one project. To act on another, a service credential sends the `x-codespar-project` header.

## 2. Read something

```bash
curl https://api.codespar.dev/v1/wallets \
  -H "Authorization: Bearer $CODESPAR_API_KEY"
```

An empty list on a new project is the correct answer, not an error.

## 3. Write something

```bash
curl -X POST https://api.codespar.dev/v1/wallets \
  -H "Authorization: Bearer $CODESPAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "display_name": "First wallet",
       "currency": "BRL"
     }'
```

`display_name` and `currency` are the only required fields. `currency` is one of `BRL`, `USD`, `MXN`, `COP`, `ARS`, `USDC`, `BRLA`. The response is the created wallet with a zero balance in that currency.

## What you get back when it goes wrong

| Status | Means |
|---|---|
| `401` | The key is missing, malformed, or revoked. Run step 1. |
| `403` | The key is valid and lacks the scope for this route. Step 1 lists the scopes it has. |
| `400` | The body did not match. The response carries `issues` with the field that failed. |
| `404` | The id does not exist **or** belongs to another tenant. The two are deliberately indistinguishable, so an id cannot be probed across tenants. |

## Where to go next

**[The API reference](/docs/api/reference)** — every operation the published OpenAPI document describes, with request and response fields, generated from the spec so it cannot drift from the API.

The machine-readable document itself is at [`codespar.dev/openapi.json`](https://codespar.dev/openapi.json), served without a credential, if you would rather generate a client than read pages.

**[Quickstart](/docs/quickstart)** — the same ground with the SDK, once you have decided the API does what you need.

**[Authentication](/docs/concepts/authentication)** — keys, scopes, OAuth, and the service credential.
