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.
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
| 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:
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. |
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..." }
| 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:
{ "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:
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_..."
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:
| Plan | REST API Limit |
|---|
| Free | 30 req/min |
| Growth | 1,000 req/min |
| Scale | Custom |
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.
Sign Authorization (EIP-7702)
Signs an 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.
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:
{
"address": "0x1234567890abcdef1234567890abcdef12345678",
"chainId": 1,
"nonce": 0,
"r": "0xa1b2c3...",
"s": "0xd4e5f6...",
"yParity": 0,
"signature": "a1b2c3d4e5f6..."
}
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.
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 |
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.
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.
See the API reference for full request/response schemas.
Timeouts
Recommended client timeouts:
| Operation | Timeout |
|---|
| Create wallet | 30s |
| Get wallet | 10s |
| Sign | 30s |