Skip to main content

Prerequisites

To use Para, you need an API key. This key authenticates your requests to Para services and is essential for integration.
Don’t have an API key yet? Request access to the to create API keys, manage billing, teams, and more.

Environments

EnvironmentBase URL
Betahttps://api.beta.getpara.com
Productionhttps://api.getpara.com
All endpoints are versioned under /v1.

Authentication

Include your API key in every request:
curl https://api.beta.getpara.com/v1/wallets/WALLET_ID \
  -H "X-API-Key: sk_..."
HeaderRequiredDescription
X-API-KeyYesYour partner secret key (server-side only)
X-Request-IdNoUUID for request tracing. Para returns one if omitted.
Never expose your API key in client-side code. Use it only from your backend.
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.

IP Allowlisting

Restrict API access to specific IPs via the Developer Portal (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):
{ "code": "WALLET_ALREADY_EXISTS", "message": "a wallet for this identifier and type already exists", "walletId": "0a1b..." }
StatusMeaningAction
400Invalid request bodyCheck required fields and types
401API key not providedInclude X-API-Key header
403Invalid API keyVerify your secret key is correct
404Wallet not foundConfirm wallet ID exists
409Duplicate walletSame type + scheme + userIdentifier already exists (see below)
429Rate limit exceededWait for Retry-After seconds then retry
500Server errorRetry 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:
{ "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:
1

Look up by identifier

Query wallets by the original identifier:
curl "https://api.beta.getpara.com/v1/wallets?userIdentifier=user@example.com&userIdentifierType=EMAIL" \
  -H "X-API-Key: sk_..."
2

List all wallets

As a final fallback, list all wallets and filter client-side:
curl "https://api.beta.getpara.com/v1/wallets" \
  -H "X-API-Key: sk_..."

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:
PlanREST API Limit
Free30 req/min
Growth1,000 req/min
ScaleCustom
Need higher limits? Scale plan customers can request custom rate limits — contact the Para team to discuss your use case.

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 structured data. EVM wallets only. Para computes the EIP-712 hash server-side — just pass the structured data directly.
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.
Don’t include EIP712Domain in the types object. Para handles it automatically from the domain fields.

Other Signing Methods

EndpointUse Case
POST /v1/wallets/{id}/sign-rawSign arbitrary hex bytes (chain-agnostic)
POST /v1/wallets/{id}/sign-messageSign a human-readable message (EIP-191 for EVM)
POST /v1/wallets/{id}/sign-transactionSign an EVM or Solana transaction
POST /v1/wallets/{id}/transferBuild, sign, and broadcast a transfer in one call
See the API reference for full request/response schemas.

Timeouts

Recommended client timeouts:
OperationTimeout
Create wallet30s
Get wallet10s
Sign30s