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

# Authentication

> Use your API key to mint short‑lived session tokens. Keep it simple and secure.

## Two credentials

* API key: send with <code>X-Partner-Key</code> for server‑to‑server calls (mint sessions). Never expose it to clients.
* Session token: short‑lived JWT for protected endpoints. Send with <code>Authorization: Bearer \<token></code>.

## Flow

```mermaid theme={null}
sequenceDiagram
  participant Backend as Your Backend
  participant MachinesAPI as Machines API
  participant Agent as Agent/Service

  Backend->>MachinesAPI: POST /users/resolve (X-Partner-Key)
  Backend->>MachinesAPI: POST /sessions (X-Partner-Key + scopes)
  MachinesAPI-->>Backend: { sessionToken, scopes, expiresAt }
  Backend->>Agent: Deliver sessionToken (scoped JWT)
  Agent->>MachinesAPI: call protected endpoints (Bearer sessionToken)
  MachinesAPI-->>Agent: structured JSON responses
```

## API flows (step‑by‑step)

<Steps>
  <Step title="Create a session token (server-to-server)">
    <b>Endpoint</b>: <a href="/api/sessions" target="_blank" rel="noreferrer"><code>POST /sessions</code></a><br />
    <b>Body</b>:

    <ul>
      <li><code>userId</code> (string, your user id)</li>
      <li><code>walletAddress</code> (0x… address, optional)</li>
      <li><code>scopes</code> (array of strings)</li>
      <li><code>ttlSeconds</code> (integer, optional)</li>
    </ul>

    <b>Response</b>:

    <ul>
      <li><code>sessionToken</code> (use as <code>Authorization: Bearer \<token></code>)</li>
      <li><code>sessionId</code>, <code>userId</code>, <code>expiresAt</code>, <code>scopes</code></li>
    </ul>

    ```bash theme={null}
    curl -s \
      -d '{"userId":"demo-123","walletAddress":"0xabc...","scopes":["cards.read","cards.write"]}' \
      https://dev-api.machines.cash/partner/v1/sessions
    ```

    ```json theme={null}
    {
      "ok": true,
      "data": {
        "sessionToken": "<jwt>",
        "sessionId": "...",
        "userId": "...",
        "expiresAt": "2026-01-01T00:00:00.000Z",
        "scopes": ["cards.read","cards.write"]
      },
      "summary": "session created",
      "errors": []
    }
    ```
  </Step>

  <Step title="Use the session token">
    Send <code>Authorization: Bearer \<token></code> on protected endpoints.

    ```bash theme={null}
    curl -s \
      -H 'Authorization: Bearer <SESSION_TOKEN>' \
      https://dev-api.machines.cash/partner/v1/cards
    ```

    Missing/expired tokens return <code>401</code>; missing permissions return <code>403</code>.
  </Step>

  <Step title="Renew when expired">
    Tokens are short‑lived. Mint a new session when you get <code>401 Unauthorized</code>.
  </Step>

  <Step title="Scope presets by task">
    Keep scopes minimal. Common sets:

    <ul>
      <li><b>KYC</b>: <code>kyc.read</code>, <code>kyc.write</code></li>
      <li><b>Cards</b>: <code>cards.read</code>, <code>cards.write</code></li>
      <li><b>Card secrets</b>: <code>cards.secrets.read</code></li>
      <li><b>Card labels</b>: <code>encryption.write</code> (encrypt), <code>encryption.read</code> (decrypt)</li>
      <li><b>Balances</b>: no extra scopes</li>
      <li><b>Transactions</b>: <code>transactions.read</code></li>
      <li><b>Withdrawals</b>: <code>withdrawals.write</code></li>
    </ul>
  </Step>
</Steps>

<Tip>Missing a scope returns <code>403 Forbidden</code>.</Tip>

## All available scopes

Deposits and balances do not require extra scopes.

```text theme={null}
users.read
users.write
kyc.read
kyc.write
cards.read
cards.write
cards.secrets.read
encryption.read
encryption.write
deposits.read
deposits.write
transactions.read
withdrawals.write
```

## Headers quick reference

```text theme={null}
# Mint sessions (server-to-server)
X-Partner-Key: <YOUR_API_KEY>

# Call protected endpoints
Authorization: Bearer <SESSION_TOKEN>
Content-Type: application/json

# Optional Open Responses output
X-Open-Responses: 1
X-Open-Responses-Call-Id: <TOOL_CALL_ID>
```

## Token basics

* Short‑lived by default (e.g., \~15 minutes). Rotate by minting a new session.
* Session payload includes account id, user id, wallet address, scopes, expiry.
* Never log tokens or card data; always use HTTPS.

<Note>Use <code>[https://dev-api.machines.cash](https://dev-api.machines.cash)</code> in sandbox. Switch to production only after key validation.</Note>
