# Personal access tokens

Read your own Payer account from your own scripts. No merchant, no server — a bearer token that belongs to you.

A personal access token (PAT) lets you read your **own** Payer data from your own code — no merchant required. It's a bearer token prefixed `pat_`, issued from **Account → Tokens** in your Payer dashboard and shown only once. Unlike a merchant key, a PAT belongs to a *person*, not a business.

## What makes a PAT different

- **Read-only.** PATs carry read scopes only. Money-moving scopes are refused at issuance until per-transaction device confirmation is enforced.
- **Personal, never a merchant's.** A PAT reads your own activity. Sending an `X-Active-Merchant` header with a PAT is rejected with a `403` — for merchant API access, issue a secret key from that merchant instead.
- **Always expires.** You set an expiry when you create one; there is no non-expiring option, and the maximum lifetime is **365 days**.

```bash title="Authorization header"
-H "Authorization: Bearer pat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
```

## Scopes

A PAT can hold any of these read scopes. It reaches only the fields its scopes admit — everything else is denied, even other reads. Grant a token the least it needs.

| Scope | Grants |
| --- | --- |
| `balances:read` | Your wallet's available balance. |
| `transactions:read` | Your transaction history and spending insights. |
| `wallets:read` | Your wallet details. |
| `kyc:read` | Your KYC status. |

## Reading over GraphQL

Send your PAT as a bearer token to `POST /graphql`. Each query below is gated on one scope; a token without it gets an authorization error, and a field your token has no scope for is refused outright.

```bash title="Request"
curl https://api.payer.app/graphql \
  -H "Authorization: Bearer pat_..." \
  -H "Content-Type: application/json" \
  -d '{"query":"query { balance { available accountIdentifier } }"}'
```

| Query | Required scope | Returns |
| --- | --- | --- |
| `balance` | `balances:read` | Your wallet's available balance. |
| `history` | `transactions:read` | Your own transactions, most recent first. |
| `insights` | `transactions:read` | Aggregated balance and spending for a period. |

### balance

```graphql title="balance — needs balances:read"
query {
  balance {
    available
    accountIdentifier
  }
}
```

### history

```graphql title="history — needs transactions:read"
query {
  history(first: 20) {
    data {
      id
      transactionType
      partyName
      amount
      status
      createdAt
    }
    paginatorInfo {
      total
      currentPage
      hasMorePages
    }
  }
}
```

### insights

```graphql title="insights — needs transactions:read"
query {
  insights(period: "this_month") {
    balance {
      summary {
        totalMoneyIn
        totalMoneyOut
        leftToSpend
      }
    }
    spending {
      totalSpent
    }
  }
}
```

> [!NOTE]
> A revoked, expired or unknown token gets a `401`. A valid token missing the field's scope gets an authorization error in the GraphQL `errors` array while `data` stays `null` for that field.

## Managing tokens

Issue, rotate and revoke PATs from **Account → Tokens**. Rotating replaces the token immediately; the old value stops working at once. Every issue, rotation and revocation is recorded, and you can see each token's last-used time so a stale one is easy to spot.
