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

# Setup

> Authenticate and make your first REST request

export const DemoCallout = ({variant = "card", title = "Interactive Demo", description = "Try the live demo to explore authentication flows and customize your modal before integrating."}) => {
  if (variant === "subtle") {
    return <div className="not-prose my-4 px-4 py-3 rounded-xl border border-orange-200 bg-orange-50/50">
        <div className="flex items-center justify-between gap-4">
          <p className="text-sm text-gray-700 m-0">
            {description}
          </p>
          <a href="https://demo.getpara.com/" target="_blank" rel="noopener noreferrer" className="not-prose flex-shrink-0 inline-flex items-center gap-2 px-3 py-1.5 text-xs font-semibold text-orange-600 bg-white border border-orange-200 rounded-lg hover:bg-orange-50 transition-colors no-underline">
            Try Demo
            <svg width="12" height="12" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M40 472L472 40M472 40H83.2M472 40V428.8" stroke="currentColor" strokeWidth="66.6667" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </a>
        </div>
      </div>;
  }
  return <a href="https://demo.getpara.com/" target="_blank" rel="noopener noreferrer" className="not-prose block my-4 p-5 rounded-xl bg-gradient-to-r from-orange-600 via-pink-600 to-purple-600 hover:opacity-95 transition-opacity no-underline">
      <div className="flex items-center justify-between gap-4">
        <div>
          <h3 className="text-base font-semibold text-white m-0">{title}</h3>
          <p className="text-xs text-white/80 mt-1 m-0">{description}</p>
        </div>
        <div className="flex-shrink-0 w-8 h-8 rounded-full bg-white/20 flex items-center justify-center">
          <svg width="14" height="14" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M40 472L472 40M472 40H83.2M472 40V428.8" stroke="white" strokeWidth="66.6667" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
        </div>
      </div>
    </a>;
};

export const Link = ({href, label, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  return <a href={href} target={newTab ? '_blank' : '_self'} rel={newTab ? 'noopener noreferrer' : undefined} className="not-prose inline-block relative text-black font-semibold cursor-pointer border-b-0 no-underline" onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      {label}
      <span className={`absolute left-0 bottom-0 w-full rounded-sm bg-gradient-to-r from-orange-600 to-purple-600 transition-all duration-300 ${isHovered ? 'h-0.5' : 'h-px'}`} />
    </a>;
};

## Prerequisites

To use Para, you need an API key. This key authenticates your requests to Para services and is essential for
integration.

<Warning>
  Don't have an API key yet? Request access to the <Link label="Developer Portal" href="https://developer.getpara.com" /> to create API keys, manage billing, teams, and more.
</Warning>

<DemoCallout variant="subtle" />

## Environments

| Environment | Base URL                       |
| ----------- | ------------------------------ |
| Beta        | `https://api.beta.getpara.com` |
| Production  | `https://api.getpara.com`      |

All endpoints are versioned under `/v1`.

## Authentication

Include your API key in every request:

```bash theme={null}
curl https://api.beta.getpara.com/v1/wallets/WALLET_ID \
  -H "X-API-Key: sk_..."
```

| Header         | Required | Description                                            |
| -------------- | -------- | ------------------------------------------------------ |
| `X-API-Key`    | Yes      | Your partner secret key (server-side only)             |
| `X-Request-Id` | No       | UUID for request tracing. Para returns one if omitted. |

<Warning>
  Never expose your API key in client-side code. Use it only from your backend.
</Warning>

<Tip>
  TypeScript backends can use [`@getpara/rest-sdk`](/v3/rest/sdk) instead of hand-written REST calls. It handles
  `X-API-Key`, `X-Request-Id`, optional `Idempotency-Key`, abort signals, validation errors, serialization errors, and
  HTTP error mapping.
</Tip>

<Danger>
  **Your project controls wallet access.** Wallets created via the REST API are permanently scoped to the project that
  created them. Rotating your secret key is safe — the new key still accesses the same wallets. However, if you delete
  your project or create a new one, you lose signing access to those wallets — even though the wallets and funds remain
  on-chain.

  If you need to migrate wallets between projects, contact [Para support](https://join.slack.com/t/para-community/shared_invite/zt-304keeulc-Oqs4eusCUAJEpE9DBwAqrg).
</Danger>

## IP Allowlisting

Restrict API access to specific IPs via the [Developer Portal](https://developer.getpara.com/) (Security → Allowlist). Once configured, requests from other IPs return `401 Unauthorized`.

## Error Handling

All errors return JSON with a `code` field for programmatic handling and a human-readable `message`. Some include extra context (e.g. `walletId` on `409`):

```json theme={null}
{ "code": "WALLET_ALREADY_EXISTS", "message": "a wallet for this identifier and type already exists", "walletId": "0a1b..." }
```

| Status | Meaning              | Action                                                               |
| ------ | -------------------- | -------------------------------------------------------------------- |
| `400`  | Invalid request body | Check required fields and types                                      |
| `401`  | API key not provided | Include `X-API-Key` header                                           |
| `403`  | Invalid API key      | Verify your secret key is correct                                    |
| `404`  | Wallet not found     | Confirm wallet ID exists                                             |
| `409`  | Duplicate wallet     | Same `type` + `scheme` + `userIdentifier` already exists (see below) |
| `429`  | Rate limit exceeded  | Wait for `Retry-After` seconds then retry                            |
| `500`  | Server error         | Retry with backoff                                                   |

### Handling 409 Conflict (Duplicate Wallet)

When creating a wallet that already exists, the API returns `409 Conflict` with the existing `walletId` in the
response body:

```json theme={null}
{ "message": "a wallet for this identifier and type already exists", "walletId": "0a1b...", "code": "WALLET_ALREADY_EXISTS" }
```

If you need to look up wallets by other means, you can also:

<Steps>
  <Step title="Look up by identifier">
    Query wallets by the original identifier:

    ```bash theme={null}
    curl "https://api.beta.getpara.com/v1/wallets?userIdentifier=user@example.com&userIdentifierType=EMAIL" \
      -H "X-API-Key: sk_..."
    ```
  </Step>

  <Step title="List all wallets">
    As a final fallback, list all wallets and filter client-side:

    ```bash theme={null}
    curl "https://api.beta.getpara.com/v1/wallets" \
      -H "X-API-Key: sk_..."
    ```
  </Step>
</Steps>

## Rate Limits

All `/v1` endpoints are rate-limited per API key. When a limit is exceeded the API returns `429 Too Many Requests` with a `Retry-After` header indicating how long to wait.

Rate limits vary by plan:

| Plan   | REST API Limit |
| ------ | -------------- |
| Free   | 30 req/min     |
| Growth | 1,000 req/min  |
| Scale  | Custom         |

<Tip>
  Need higher limits? Scale plan customers can request custom rate limits — contact the Para team to discuss your use case.
</Tip>

## Signing

The REST API supports several signing methods. All signing endpoints require an EVM or Solana wallet (created via `POST /v1/wallets`).

### Sign Typed Data (EIP-712)

Signs [EIP-712](https://eips.ethereum.org/EIPS/eip-712) structured data. EVM wallets only. Para computes the EIP-712 hash server-side — just pass the structured data directly.

```bash theme={null}
curl -X POST "https://api.beta.getpara.com/v1/wallets/WALLET_ID/sign-typed-data" \
  -H "X-API-Key: sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "typedData": {
      "domain": {
        "name": "MyDApp",
        "version": "1",
        "chainId": 11155111,
        "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
      },
      "types": {
        "Mail": [
          { "name": "from", "type": "address" },
          { "name": "to", "type": "address" },
          { "name": "contents", "type": "string" }
        ]
      },
      "primaryType": "Mail",
      "message": {
        "from": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
        "to": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
        "contents": "Hello, world!"
      }
    }
  }'
```

Returns `{ "signature": "a1b2c3..." }` — a hex-encoded signature without `0x` prefix.

<Tip>
  Don't include `EIP712Domain` in the `types` object. Para handles it automatically from the `domain` fields.
</Tip>

### Sign Authorization (EIP-7702)

Signs an [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) authorization for account delegation. EVM wallets only. This enables account abstraction providers (ZeroDev, Alchemy, Pimlico, etc.) to delegate an EOA to a smart contract for gas sponsorship or batched calls — without migrating to a new wallet address.

```bash theme={null}
curl -X POST "https://api.beta.getpara.com/v1/wallets/WALLET_ID/sign-authorization" \
  -H "X-API-Key: sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "authorization": {
      "address": "0x1234567890abcdef1234567890abcdef12345678",
      "chainId": 1,
      "nonce": 0
    }
  }'
```

Returns the signed authorization with decomposed signature fields:

```json theme={null}
{
  "address": "0x1234567890abcdef1234567890abcdef12345678",
  "chainId": 1,
  "nonce": 0,
  "r": "0xa1b2c3...",
  "s": "0xd4e5f6...",
  "yParity": 0,
  "signature": "a1b2c3d4e5f6..."
}
```

<Note>
  Unlike other signing endpoints that return `v` (27/28), this endpoint returns `yParity` (0/1) per the EIP-7702 spec. The `address` field also accepts `contractAddress` as an alias, matching viem's API.
</Note>

### Other Signing Methods

| Endpoint                                 | Use Case                                                                                              |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `POST /v1/wallets/{id}/sign-raw`         | Sign arbitrary hex bytes (chain-agnostic)                                                             |
| `POST /v1/wallets/{id}/sign-message`     | Sign a human-readable message (EIP-191 for EVM)                                                       |
| `POST /v1/wallets/{id}/sign-transaction` | Sign an EVM, Solana, or Stellar transaction; EVM and Solana can also broadcast with `broadcast: true` |
| `POST /v1/wallets/{id}/transfer`         | Build, sign, and broadcast a transfer in one call                                                     |
| `POST /v1/wallets/{id}/estimate-fee`     | Preview transfer fees without signing or broadcasting                                                 |

<Note>
  `sign-transaction` accepts both legacy `Transaction` and v0 `VersionedTransaction` (Address Lookup Tables) Solana formats; the endpoint auto-detects which one was sent. This means output from `VersionedTransaction.serialize()` (what Jupiter's swap API returns) can be passed in directly.
</Note>

<Note>
  `sign-transaction` is sign-only by default. Set top-level `broadcast: true` for EVM or Solana to broadcast the signed bytes and receive `txHash`, `transactionId`, and an `x-transaction-id` response header. Stellar remains sign-only and rejects `broadcast: true`.
</Note>

See the [API reference](/v3/rest/overview) for full request/response schemas.

## Timeouts

Recommended client timeouts:

| Operation     | Timeout |
| ------------- | ------- |
| Create wallet | 30s     |
| Get wallet    | 10s     |
| Sign          | 30s     |
