# Introduction

Welcome to Reveel Pay(ID) Documentation

## What is Pay(ID)?

**Pay(ID)** is the first **universal stablecoin payment identifier** — a simple, human-readable ID (e.g. alice(id)) that allows anyone to receive *any* stablecoin, from *any* network, and have it settle in their **preferred token, network, and wallet**.

Instead of sharing complex wallet addresses across multiple blockchains, users share a single Pay(ID). Behind the scenes, Reveel routes incoming stablecoin transfers across networks and assets, abstracting away fragmentation and enabling seamless peer-to-peer and app-driven payments.

Pay(ID) transforms how money moves in Web3 — enabling interoperable, programmable, and chain-agnostic stablecoin transactions in a single click.

## Why Pay(ID)?

Web3 stablecoin payments are powerful, but the user experience is fundamentally broken:

* **Hyper-fragmentation:** 200+ stablecoins across dozens of chains
* **Inconsistent identifiers:** Different addresses per chain, per user, per wallet
* **High failure risk:** Users send to the wrong chain, wrong token, or wrong format
* **Complex UX:** Bridging, swapping, and routing are manual, technical, and error-prone

**Pay(ID) solves this**. It abstracts away the complexity by letting users define how and where they want to receive funds — and letting developers integrate stablecoin payments without worrying about chains, assets, or liquidity.

## How it works

#### &#x20;For Users:

1. **Register a Pay(ID)** via the Pay(ID) Dashboard or integrated apps.
2. **Link your wallets** and configure “Routes” — rules for how to receive funds.
3. **Share your Pay(ID)** with anyone. Incoming funds are automatically resolved, swapped, bridged, and settled to your chosen wallet.

#### &#x20;For Developers:

* Offer Pay(IDs) to your users through your app (including registration, routing, and wallet management).
* Use the Reveel API to resolve any Pay(ID) to a real transaction route.
* Monetize adoption via Pay(ID) referral economics.

## Getting Started

#### End Users:

→ Visit the [Pay(ID) Dashboard](https://reveel.id/claim) to register your Pay(ID) and configure your Routes.

#### Developers:

→ Jump to the [Developer Guide](/getting-started/readme) for API access, integration steps, and example implementations.


# Key Concepts-old

## Pay(ID)

A unique, human-readable identifier that can receive *any stablecoin from any chain*, and automatically route it to the recipient’s desired destination.

## Routes

Rules defined by the user to control how funds are settled. Routes follow an "if this, then that" model. Examples:

* USDC from Optimism → USDC on Base, into Wallet A
* Any funds from alice(id) → USDT on Polygon, into Wallet B

Routes can be based on 3 types of triggers:

* Source Token (e.g. if I receive USDC, then...)
* Source Network (e.g. if I receive funds on BNB Chain, then...)
* Sender (e.g. if I receive funds from Bob, then...)

## Pay(ID) Data Layer

Reveel’s database layer storing:

* Pay(ID) registrations
* Routes
* Linked wallets
* Metadata (linked ENS, MocaID, email, social handles, app namespaces…)

## Liquidity Orchestration Layer

Reveel’s routing engine that determines the optimal transaction path using partner liquidity networks. It finds the best route to deliver funds to the destination wallet, considering:

* Gas fees
* Available bridges
* Partner fees
* Settlement time
* Token liquidity


# Key Concepts

## Overview

Pay(ID) is much more than a name — it's a complete protocol layer for programmable, omnichain stablecoin routing. This section introduces the **core building blocks** that power the Reveel Pay(ID) experience for users, developers, wallets, agents, and dApps.

Understanding these components helps you see how Reveel abstracts away complexity, manages intent-based routing, and enables powerful new UX across the Web3 ecosystem.

## Core Concepts Breakdown

***

### **1. Entry Points**

> **Users, Wallets, Agents, Apps, Custodians**\
> The Reveel journey starts here. Any actor can initiate a payment using a PayID. This entry point could be a user typing a PayID, an AI agent processing a transaction, or a DApp triggering an API call.

***

### **2. PayID**

> **The Universal Identifier**\
> A human-readable ID (e.g. `alice(id)`) that works across chains, tokens, and apps.\
> PayIDs abstract wallet addresses and act as programmable payment endpoints.

* Linked to wallets across multiple chains
* Support ENS, Lens, MocaID and other namespaces
* Can receive *any* supported stablecoin
* Maps to user specific route configurations

***

### **3. Routes Engine**

> **Custom Payment Logic**\
> Routes define **how incoming funds should be handled**, based on:

* Sender (e.g., if Bob pays me…)
* Token (e.g., if USDC…)
* Chain (e.g., if received on BNB…)

This logic defines the final output:

* Which wallet?
* On which chain?
* In which token?

Think of it as "IF THIS, THEN THAT" for payments.

***

### **4. Data Layer**

> **Persistent Identity & Routing Storage**\
> This is the metadata brain of Reveel:

* Stores PayID registrations
* Linked wallet data (onchain + offchain)
* Routes and preferences
* Metadata: ENS, email, app namespace, MocaID

It powers instant resolution, personalization, and cross-app interoperability.

***

### **5. Liquidity Engine / Orchestration Layer**

> **Cross-Chain Optimization**\
> The routing system plugs into bridge & swap partners (e.g., Decent, LayerZero, Stargate etc. ) to:

* Query bridge liquidity
* Evaluate gas costs
* Optimize routes for fees, slippage, and time
* Choose best bridge/swap path

This enables **chain abstraction** behind a single PayID.

***

### **6. Settlement Layer**

> **Final Delivery to Target Wallet**\
> Once a route is selected and liquidity path chosen, the Settlement Layer:

* Executes the crosschain transactions&#x20;
* Transfers funds to the user’s preferred wallet, in the right token & chain
* Emits success/failure receipts to APIs/webhooks


# Technical Architecture

## Overview

Reveel PayID is designed as a **modular protocol layer** that enables cross-chain stablecoin transfers through a unified, human-readable identity: `yourname(id)`.

This page provides a detailed look at how Reveel’s core systems interact to deliver seamless payments — today and in the near future.

## Modular & Composable by Design

At the heart of PayID lies a **modular architecture** designed for flexibility, scalability, and composability. Rather than a linear pipeline, Reveel is built as a **hub-and-spoke system** where each core service operates as an independent, interoperable module — all coordinated through the Reveel protocol core.

### 1. External Integrations Layer

This is the entry point for interactions with Reveel PayID. Apps, wallets, AI agents, or platforms can integrate using REST APIs.

**APIs:**

* `POST /user/create` → Register a platform user
* `GET /user/list`, `GET /user/:id` → Retrieve user data

***

### 2. PayID Resolver

The resolver converts a PayID like `alice(id)` into actionable metadata, such as:

* Registered user
* Linked wallet addresses across chains
* Custom routing rules
* Associated identities (ENS, Lens, MocaID, email)

📌**APIs:**

* `POST /payid/claim` → Claim a new PayID
* `GET /payid/search` → Look up a user by PayID
* `GET /payid/check-price` → Check on-chain PayID price before claiming

***

### 3. Routes Engine

This component parses user-defined logic and determines how incoming funds should be routed. Each route is programmable and can be based on:

* Sender (e.g., route if Bob sends)
* Source Chain
* Source Token

Each route returns:

* Destination wallet address
* Destination chain
* Preferred token

📌**APIs:**

* `POST /routes/create`
* `PUT /routes/edit-route`
* `GET /routes/get-routes`
* `DELETE /routes/delete-route`

***

### 4. Reveel Liquidity Orchestration Layer (RLOL)

**Current Status:**\
RLOL is under active development. It will power routing decisions at a higher precision and future bridge/swap execution strategies.

&#x20;**Responsibilities:**

* Parse target route and prepare transaction context
* Allow routing through supported tokens and chains
* Liquidity Aggregator Engine (LAE) for querying bridges like Connext, Hop, etc.
* Dynamic route optimization (fees, slippage, latency)
* Swap support
* Retry/fallback logic

This layer will supports the full lifecycle of a transaction, even if external liquidity execution is abstracted for now.

***

### 5. Transaction Execution Layer

After a route is resolved, the transaction is initiated and handled through the following APIs:

📌 **Cureent** **APIs:**

* `POST /transact/init-transaction` → Triggers a transaction to the target wallet as defined in the resolved route
* `POST /transact/txn-webhook` → Used by external systems to push transaction status back to Reveel
* `GET /transact/get-activity` → Retrieve transaction metadata and history for a PayID

This system may expand to include bridge routing and swap intelligence, but currently supports clean execution flows based on PayID logic.


# Quickstart

## PayID API Quickstart Guide

This guide shows how to integrate PayID into your app using the live REST API, step by step. We'll register users, claim PayIDs, configure routing, and finally initiate signed on-chain payments — no SDK needed.

### Authentication & Headers

Every request to the API must include:

```
Authorization: Bearer your-api-key
Content-Type: application/json
Accept: application/json
```

📌 **API Base URL**: `https://api.reveel.id/v1`

{% hint style="info" %} <mark style="color:red;">**API keys are provided manually upon approval via email request.**</mark>&#x20;

<mark style="color:red;">**Please send your request from company email to: <devs@r3vl.xyz>**</mark>
{% endhint %}

### Prerequisites

Make sure you have:

* A valid API key
* A tool like curl, Postman, or any HTTP client

### Step 1: Create a User

```bash
curl -X POST https://api.reveel.id/v1/users \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "alice@example.com",
    "twitterUsername": "alice123",
    "walletAddress": "0x123abc456def789ghi"
  }'
```

Response:

```json
{
  "success": true,
  "data": {
    "id": "user-id",
    "email": "alice@example.com",
    "walletAddress": "0x123abc456def789ghi",
    "twitterUsername": "alice123",
    "createdAt": "2023-07-15T12:30:45.000Z"
  },
  "meta": {
    "message": "User created successfully"
  }
}
```

### Step 2: Claim a PayID

```bash
curl -X POST https://api.reveel.id/v1/pay-ids/claim \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user-id",
    "payId": "alice",
    "expiresInYears": 1
  }'
```

Response for free PayID:

```json
{
  "success": true,
  "data": {
    "payId": "alice",
    "price": 0,
    "transactionId": "tx-id"
  },
  "meta": {
    "message": "PayID claimed successfully"
  }
}
```

For premium PayIDs:

```json
{
  "success": true,
  "data": {
    "checkoutUrl": "https://checkout.loop.markets/...",
    "reservationId": "abc123"
  },
  "meta": {
    "message": "Premium PayID reserved for checkout"
  }
}
```

### Step 3: Create a Route

```bash
curl -X POST https://api.reveel.id/v1/routes \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user-id",
    "name": "Default USDC Route",
    "incomingNetworks": ["ETH", "POL"],
    "incomingTokens": ["USDC"],
    "outgoingWallet": "0x789destination..."
  }'
```

Response:

```json
{
  "success": true,
  "data": {
    "id": "route-id",
    "name": "Default USDC Route",
    "incomingNetworks": ["ETH", "POL"],
    "incomingTokens": ["USDC"],
    "outgoingWallet": "0x789destination...",
    "userId": "user-id",
    "createdAt": "2023-07-15T12:35:22.000Z",
    "updatedAt": "2023-07-15T12:35:22.000Z"
  },
  "meta": {
    "message": "Route created successfully"
  }
}
```

### Step 4: Initiate and Sign a Transaction

#### a. Initialize transaction from backend

```bash
curl -X POST https://api.reveel.id/v1/transactions \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "sender-user-id",
    "recipientPayId": "bob",
    "amount": 1.5,
    "token": "ETH",
    "network": "ETH",
    "message": "Payment for services"
  }'
```

Response:

```json
{
  "success": true,
  "data": {
    "amount": 1.5,
    "token": "ETH",
    "network": "ETH",
    "tx": {
      "to": "0xrecipient...",
      "data": "0x6572b...",
      "value": "1500000000000000000",
      "chainId": 1
    },
    "fees": {
      "applicationFee": null,
      "protocolFee": null,
      "bridgeFee": null
    }
  },
  "meta": {
    "message": "Transaction initialized successfully"
  }
}
```

**ERC20 Token Example (with approval)**

When sending ERC20 tokens, you may receive an `approveTx` that needs to be executed first:

```json
{
  "success": true,
  "data": {
    "amount": 10,
    "token": "USDT",
    "network": "POL",
    "tx": {
      "to": "0xcontract...",
      "data": "0xa9059cbb...",
      "value": "0",
      "chainId": 137
    },
    "approveTx": {
      "to": "0xtoken-contract...",
      "data": "0x095ea7b3...",
      "chainId": 137
    },
    "fees": {
      "applicationFee": 0.1,
      "protocolFee": 0.05,
      "bridgeFee": null
    }
  },
  "meta": {
    "message": "Transaction initialized successfully"
  }
}
```

#### b. Frontend Signing & Submission (Wagmi + Viem)

```javascript
import { useAccount, useWalletClient } from 'wagmi'
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'

const { data: walletClient } = useWalletClient()
const { address } = useAccount()

// Handle ERC20 approval if needed
if (response.data.approveTx) {
  const approveTx = {
    to: response.data.approveTx.to,
    data: response.data.approveTx.data,
    value: BigInt(0),
    chainId: response.data.approveTx.chainId
  }
  
  // Send approval transaction first
  const approveHash = await walletClient.sendTransaction({ ...approveTx, account: address })
  await publicClient.waitForTransactionReceipt({ hash: approveHash })
}

// Main transaction from /transactions response
const tx = {
  to: response.data.tx.to,
  data: response.data.tx.data,
  value: BigInt(response.data.tx.value || "0"),
  chainId: response.data.tx.chainId
}

const publicClient = createPublicClient({
  chain: mainnet,
  transport: http()
})

// Send signed transaction
const hash = await walletClient.sendTransaction({ ...tx, account: address })

// Optional: wait for confirmation
await publicClient.waitForTransactionReceipt({ hash })
```

✅ You can also use ethers.js or web3.js — just pass the exact `to`, `data`, `value`, and `chainId` from the response.

### Step 5: Get Transaction Activity

```bash
curl -X GET "https://api.reveel.id/v1/transactions/users/user-id/activities?page=1&pageSize=10" \
  -H "Authorization: Bearer your-api-key" \
  -H "Accept: application/json"
```

Response:

```json
{
  "success": true,
  "data": {
    "activities": [
      {
        "id": "activity-id",
        "txHash": "0xtxhash...",
        "amount": 1.5,
        "type": "SEND",
        "status": "COMPLETED",
        "token": "ETH",
        "network": "ETH",
        "createdAt": "2023-07-15T14:22:45.000Z",
        "updatedAt": "2023-07-15T14:23:12.000Z"
      }
    ],
    "pagination": {
      "totalCount": 1,
      "totalPages": 1,
      "currentPage": 1,
      "pageSize": 10
    }
  }
}
```

✅ Returns transaction history including amounts, routes, tokens, and fees.


# Reveel PayID SDK

Human-readable payments for any wallet

{% embed url="<https://www.npmjs.com/package/@reveelid/sdk>" %}

### 💡 What is Reveel?

> 🔹 **Reveel is a PayID layer for crypto wallets**

Instead of sending funds to a long address like:

```
0x742d35Cc6634C0532...
```

Your users simply send to:

```
@aldo
```

➡️ We handle:

* PayID resolution
* Cross-chain routing
* Swap logic

➡️ Your wallet just **signs the transaction**

***

### 🔄 How It Works

```
User types "@aldo"
        ↓
SDK: initTransaction(...)
        ↓
Reveel backend resolves + routes + builds tx
        ↓
Returns unsigned transaction
        ↓
Wallet signs & submits ✅
```

> 📞 **Think of it like:**
>
> Reveel = phonebook + smart router
>
> Your wallet = the phone

***

### ⚡ Why Integrate?

| Feature         | ❌ Without Reveel   | ✅ With Reveel |
| --------------- | ------------------ | ------------- |
| Send flow       | Paste long address | Type `@aldo`  |
| Cross-chain     | Build yourself     | Automatic     |
| Recipient prefs | Not supported      | Auto-matched  |
| Private keys    | —                  | Never touched |
| Dependencies    | —                  | Zero          |

***

### 🧩 Integration Levels

\<details> \<summary>🟢 Level 1 — Resolve Only (5 min)\</summary>

Quick drop-in to resolve PayIDs:

```
import {createReveel }from"@reveelid/sdk";

constreveel=createReveel({ apiKey:"YOUR_API_KEY" });

const { address }=awaitreveel.resolve("@aldo");
```

➡️ Returns wallet address

\</details>

***

\<details> \<summary>🟡 Level 2 — Full Transaction Flow\</summary>

We build the full transaction for you:

```
constresult=awaitreveel.initTransaction({
  userId:"sender-uuid",
  recipientPayId:"@aldo",
  amount:50,
  token:"USDC",
  network:"BASE",
});

if (result.approveTx) {
awaitwallet.sendTransaction(result.approveTx);
}

consttxHash=awaitwallet.sendTransaction(result.tx);
```

\</details>

***

\<details> \<summary>🔵 Level 3 — User + PayID System\</summary>

Create users & assign PayIDs:

```
constuser=awaitreveel.createUser({
  <email:"user@yourwallet.com>",
  walletAddress:"0x...",
});

constclaim=awaitreveel.claimPayId(user.id,"aldo");
```

\</details>

***

\<details> \<summary>🟣 Level 4 — Smart Routing\</summary>

Define how users receive funds:

```
constroute=awaitreveel.createRoute({
  userId:"recipient-uuid",
  name:"USDC on Base",
  incomingNetworks: ["ETH","OP","BASE"],
  incomingTokens: ["USDC","USDT"],
  outgoingWallet:"0x...",
  swapNetwork:"BASE",
  swapToken:"USDC",
});
```

➡️ Automatically matches on send

\</details>

***

### 🌐 Supported Chains & Tokens

| Chain     | Tokens          |
| --------- | --------------- |
| Ethereum  | USDC, USDT, ETH |
| Base      | USDC, USDT, ETH |
| Polygon   | USDC, USDT, POL |
| Optimism  | USDC, USDT, ETH |
| BNB Chain | USDC, USDT, BNB |

***

### 📦 What `initTransaction` Returns

```
{
amount:50,
token:"USDC",
network:"BASE",
tx: {to,data,value,chainId },
approveTx: {to,data,chainId },
fees: {
applicationFee:null,
protocolFee:null,
bridgeFee:null
  }
}
```

> 🔐 You sign it — Reveel never touches private keys

***

### 🔒 Security & Architecture

* ✅ Zero dependencies
* ✅ Unsigned transactions only
* ✅ TypeScript-first
* ✅ Wallet-agnostic
* ✅ Retry + timeout built-in

***

### 🔍 Autocomplete Search

```
constresults=awaitreveel.searchPayId("ald","ALL");
```

➡️ Returns:

* PayID
* Wallet address
* Twitter handle

***

### ⚠️ Error Handling

```
try {
awaitreveel.resolve("@nonexistent");
}catch (err) {
if (err.code==="PAYID_NOT_FOUND") {
show("This PayID doesn't exist yet");
  }
}
```

***

### 🚀 Get Started

```
npm install @reveelid/sdk
```

📩 Contact: [**partner@reveel.id**](mailto:partner@reveel.id)

***

### 📚 Quick Reference

| Method              | Description     |
| ------------------- | --------------- |
| resolve             | PayID → address |
| searchPayId         | Search users    |
| createUser          | Create user     |
| claimPayId          | Claim PayID     |
| initTransaction     | Build tx        |
| reportTransaction   | Track tx        |
| getActivities       | History         |
| createRoute         | Setup route     |
| getRoutes           | List routes     |
| updateRoute         | Update route    |
| deleteRoute         | Delete route    |
| checkRouteConflicts | Validate routes |


# Overview

Welcome to the Reveel PayID REST API reference. This section contains detailed documentation for every publicly accessible endpoint available to partner applications, wallets, and agents.

### What You Can Do

Reveel PayID APIs allow you to:

* Register and manage users
* Claim and manage PayIDs
* Define and manage custom routing rules
* Initiate cross-chain transactions
* Retrieve transaction history and user activities

### Authentication

All API requests require a valid API key in the Authorization header:

```http
Authorization: Bearer your-api-key
Content-Type: application/json
Accept: application/json
```

💡 API keys are issued after your application is approved. Request access here: **<devs@r3vl.xyz>**

### Base URL

```
https://api.reveel.id/v1
```

### API Categories

The API endpoints are organized into these main categories:

* **Users** - Create, retrieve, and manage user accounts
* **PayIDs** - Claim, search, and manage PayIDs
* **Routes** - Create and manage routing rules for incoming payments
* **Transactions** - Initialize transactions and retrieve activity history

### &#x20;Response Format

All responses follow a consistent structure:

#### Success Response

```json
{
  "success": true,
  "data": {
    // endpoint-specific payload
  },
  "meta": {
    "message": "Action completed successfully"
  }
}
```

#### Error Response

```json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid input data",
    "details": {
      "errors": [
        {
          "path": ["payId"],
          "message": "PayID not found"
        }
      ]
    }
  }
}
```

### Rate Limits & Versioning

* All endpoints are versioned under `/v1`
* Current rate limits: 100 requests/minute (subject to change)
* Abuse or misuse of APIs may result in throttling or key revocation

### &#x20;Error Codes

Common error codes you may encounter:

| Code                 | Description                                       |
| -------------------- | ------------------------------------------------- |
| `UNAUTHORIZED`       | Invalid or missing API key                        |
| `VALIDATION_ERROR`   | Invalid request parameters                        |
| `RESOURCE_NOT_FOUND` | Requested resource does not exist                 |
| `CONFLICT`           | Resource already exists or conflicts with another |
| `INTERNAL_ERROR`     | Server-side error                                 |


# Integration Best Practices

This guide outlines best practices for developers integrating with the Reveel PayID API. Following these principles will help ensure a reliable, secure, and scalable integration.

### 1. Authentication

* Always include your API key in the Authorization header:

  ```
  Authorization: Bearer your-api-key
  ```
* Store API keys securely in environment variables, never in frontend code or public repositories
* Implement key rotation mechanisms if your backend supports it
* Use proper error handling for 401 responses to trigger re-authentication flows

### 2. Token and Network Compatibility

* Only use the supported tokens: `USDT`, `USDC`, `ETH`, `BNB`, `POL` - along with native tokens of respective chains.
* Only use the supported networks: `ETH`, `POL`, `OP`, `BNB`, `BASE`
* Be aware of unsupported combinations:
  * POL token on OP network
  * BNB token on OP network
  * USDT token on BASE network
  * BNB token on BASE network
  * POL token on BASE network

### 3. Transaction Handling

* For ERC20 tokens (USDT, USDC), always check for `approveTx` in the response
* If `approveTx` is present, execute this transaction first before the main transaction
* Implement proper error handling for transaction states (pending, completed, failed)
* Add client-side idempotency keys to prevent accidental duplicate transactions
* When sending to a PayID, be prepared to handle route-based swaps and associated fees

### 4. Error Handling

* All API responses follow a consistent format with `success` flag
* Error responses include detailed information in the `error` object:

  ```json
  {
    "success": false,
    "error": {
      "code": "VALIDATION_ERROR",
      "message": "Invalid input data",
      "details": {
        "errors": [
          {
            "path": ["userId"],
            "message": "userId is required"
          }
        ]
      }
    }
  }
  ```
* Implement specific handling for common errors:
  * 400: Client-side validation errors
  * 401: Authentication failures
  * 404: Resource not found
  * 409: Conflicts (e.g., route conflicts, PayID already taken)
  * 500: Server errors (may be retried with backoff)

### 5. Pagination

* When fetching transaction activities, always use pagination parameters:
  * `page` (default: 1): Page number
  * `pageSize` (default: 10): Number of items per page
* Implement UI for pagination controls or auto-load mechanisms
* Use the pagination metadata returned in the response for accurate UI:

  ```json
  "pagination": {
    "totalCount": 25,
    "totalPages": 3,
    "currentPage": 1,
    "pageSize": 10
  }
  ```

### 6. Network Resilience

* Implement retry logic with exponential backoff for 5xx errors and timeouts
* Do not retry on 4xx errors (except possibly 429 Too Many Requests)
* Recommended backoff strategy:
  * Initial delay: 1 second
  * Maximum retries: 3
  * Exponential factor: 2 (1s, 2s, 4s)
* Add circuit breakers to prevent cascading failures during API outages

### 7. Monitoring and Logging

* Log all API requests with relevant details:
  * Endpoint path
  * HTTP method
  * Response status code
  * Error messages (without sensitive data)
  * Response times
* Track transaction success rates for user analytics
* Implement health checks to detect API availability issues

### 8. Security Considerations

* Validate wallet addresses on the client side before submission
* Never log full transaction data that might contain sensitive information
* Implement rate limiting in your client applications to prevent abuse
* For PayID integrations, validate PayID format before submission to reduce errors

### 9. Performance Optimization

* Cache frequently accessed data (user lists, routes)
* Implement conditional fetching based on UI state
* Use local storage or state management to reduce redundant API calls
* Prefetch anticipated data when appropriate (e.g., user routes before transaction)

### 10. API Evolution

* The Reveel API uses versioned endpoints (`/v1/transactions`)
* Monitor for deprecation notices and new versions
* Design your integration to easily accommodate API changes by using abstraction layers
* Subscribe to developer notifications if available to stay current with changes

### 11. Content Headers

* Always include proper headers for all requests:

  ```
  Accept: application/json
  Content-Type: application/json  // For requests with bodies
  ```
* Validate response content types to ensure you're receiving JSON data
* Handle unexpected content types gracefully (e.g., HTML error pages)


# Users

## Create a new user

> Creates a new user and associates them with the authenticated partner.\
> If a user with the provided email already exists but is not associated with the partner,\
> the existing user will be associated with the partner instead of creating a new user.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the User endpoints:\n\n- **user:create** - Create new users and associate them with your partner account\n- **user:read** - View users associated with your partner account\n- **user:update** - Modify user information for users associated with your partner account\n- **user:delete** - Disassociate users from your partner account\n"}},"schemas":{"CreateUserRequest":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"User's email address (required)"},"twitterUsername":{"type":"string","description":"User's twitter username (optional)"},"walletAddress":{"type":"string","description":"User's blockchain wallet address (optional)"}}},"CreateUserResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the created user"},"email":{"type":"string","format":"email","description":"User's email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's twitter username (if provided)"},"walletAddress":{"type":"string","nullable":true,"description":"User's blockchain wallet address (if provided)"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"}}},"meta":{"type":"object","description":"Additional metadata (empty for user creation)"}}},"ValidationError":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Indicates a validation error"},"message":{"type":"string","description":"Comma-separated list of validation errors"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code identifying the type of error"},"message":{"type":"string","description":"Human-readable error message"},"details":{"type":"object","nullable":true,"description":"Additional details about the error (when available)"}}}}}}},"paths":{"/users":{"post":{"summary":"Create a new user","description":"Creates a new user and associates them with the authenticated partner.\nIf a user with the provided email already exists but is not associated with the partner,\nthe existing user will be associated with the partner instead of creating a new user.\n","tags":["Users"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}}},"responses":{"201":{"description":"User created or associated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserResponse"}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"409":{"description":"User already associated with partner","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"}}}}}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get a user by ID

> Retrieves a specific user by their ID (user must be associated with the authenticated partner)

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the User endpoints:\n\n- **user:create** - Create new users and associate them with your partner account\n- **user:read** - View users associated with your partner account\n- **user:update** - Modify user information for users associated with your partner account\n- **user:delete** - Disassociate users from your partner account\n"}},"schemas":{"GetUserResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"$ref":"#/components/schemas/User"},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Success message"}}}}},"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the user"},"email":{"type":"string","format":"email","description":"User's email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's twitter username (optional)"},"walletAddress":{"type":"string","nullable":true,"description":"User's blockchain wallet address (optional)"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"},"updatedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when the user was last updated"},"payId":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the payId"},"name":{"type":"string","description":"The payId name"}},"description":"User's associated PayID (if any)"}}},"Error":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code identifying the type of error"},"message":{"type":"string","description":"Human-readable error message"},"details":{"type":"object","nullable":true,"description":"Additional details about the error (when available)"}}}}}}},"paths":{"/users/{id}":{"get":{"summary":"Get a user by ID","description":"Retrieves a specific user by their ID (user must be associated with the authenticated partner)","tags":["Users"],"responses":{"200":{"description":"User retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUserResponse"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Update a user

> Updates information for a specific user by their ID.\
> The user must be associated with the authenticated partner.\
> At least one field must be provided for update.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the User endpoints:\n\n- **user:create** - Create new users and associate them with your partner account\n- **user:read** - View users associated with your partner account\n- **user:update** - Modify user information for users associated with your partner account\n- **user:delete** - Disassociate users from your partner account\n"}},"schemas":{"UpdateUserRequest":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"User's updated email address"},"twitterUsername":{"type":"string","description":"User's updated twitter username"},"walletAddress":{"type":"string","description":"User's updated blockchain wallet address"}}},"UpdateUserResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the user"},"email":{"type":"string","format":"email","description":"User's updated email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's updated twitter username"},"walletAddress":{"type":"string","nullable":true,"description":"User's updated blockchain wallet address"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp when the user was updated"}}},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Success message"}}}}},"ValidationError":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Indicates a validation error"},"message":{"type":"string","description":"Comma-separated list of validation errors"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code identifying the type of error"},"message":{"type":"string","description":"Human-readable error message"},"details":{"type":"object","nullable":true,"description":"Additional details about the error (when available)"}}}}}}},"paths":{"/users/{id}":{"put":{"summary":"Update a user","description":"Updates information for a specific user by their ID.\nThe user must be associated with the authenticated partner.\nAt least one field must be provided for update.\n","tags":["Users"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}}},"responses":{"200":{"description":"User updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserResponse"}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"409":{"description":"Email already in use","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Disassociate a user

> Removes the association between a user and the authenticated partner.\
> This does not delete the user from the system, only removes the association.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the User endpoints:\n\n- **user:create** - Create new users and associate them with your partner account\n- **user:read** - View users associated with your partner account\n- **user:update** - Modify user information for users associated with your partner account\n- **user:delete** - Disassociate users from your partner account\n"}},"schemas":{"DeleteUserResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Success message indicating the user was disassociated"}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code identifying the type of error"},"message":{"type":"string","description":"Human-readable error message"},"details":{"type":"object","nullable":true,"description":"Additional details about the error (when available)"}}}}}}},"paths":{"/users/{id}":{"delete":{"summary":"Disassociate a user","description":"Removes the association between a user and the authenticated partner.\nThis does not delete the user from the system, only removes the association.\n","tags":["Users"],"responses":{"200":{"description":"User disassociated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteUserResponse"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"Association not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Disconnect wallet

> Disconnects a wallet from a specific user by setting their walletAddress to null.\
> The user must be associated with the authenticated partner and must have a wallet connected.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the User endpoints:\n\n- **user:create** - Create new users and associate them with your partner account\n- **user:read** - View users associated with your partner account\n- **user:update** - Modify user information for users associated with your partner account\n- **user:delete** - Disassociate users from your partner account\n"}},"schemas":{"DisconnectWalletResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the user"},"email":{"type":"string","format":"email","description":"User's email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's twitter username"},"walletAddress":{"type":"string","nullable":true,"description":"User's wallet address (now null after disconnection)"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp when the wallet was disconnected"}}},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Success message"}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code identifying the type of error"},"message":{"type":"string","description":"Human-readable error message"},"details":{"type":"object","nullable":true,"description":"Additional details about the error (when available)"}}}}}}},"paths":{"/users/{id}/disconnect-wallet":{"post":{"summary":"Disconnect wallet","description":"Disconnects a wallet from a specific user by setting their walletAddress to null.\nThe user must be associated with the authenticated partner and must have a wallet connected.\n","tags":["Users"],"responses":{"200":{"description":"Wallet disconnected successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisconnectWalletResponse"}}}},"400":{"description":"No wallet connected","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get a user by email

> Retrieves a specific user by their email address.\
> The user must exist and be associated with the authenticated partner.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the User endpoints:\n\n- **user:create** - Create new users and associate them with your partner account\n- **user:read** - View users associated with your partner account\n- **user:update** - Modify user information for users associated with your partner account\n- **user:delete** - Disassociate users from your partner account\n"}},"schemas":{"GetUserResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"$ref":"#/components/schemas/User"},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Success message"}}}}},"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the user"},"email":{"type":"string","format":"email","description":"User's email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's twitter username (optional)"},"walletAddress":{"type":"string","nullable":true,"description":"User's blockchain wallet address (optional)"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"},"updatedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when the user was last updated"},"payId":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the payId"},"name":{"type":"string","description":"The payId name"}},"description":"User's associated PayID (if any)"}}},"Error":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code identifying the type of error"},"message":{"type":"string","description":"Human-readable error message"},"details":{"type":"object","nullable":true,"description":"Additional details about the error (when available)"}}}}}}},"paths":{"/users/email/{email}":{"get":{"summary":"Get a user by email","description":"Retrieves a specific user by their email address.\nThe user must exist and be associated with the authenticated partner.\n","tags":["Users"],"responses":{"200":{"description":"User retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUserResponse"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## The User object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the user"},"email":{"type":"string","format":"email","description":"User's email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's twitter username (optional)"},"walletAddress":{"type":"string","nullable":true,"description":"User's blockchain wallet address (optional)"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"},"updatedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when the user was last updated"},"payId":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the payId"},"name":{"type":"string","description":"The payId name"}},"description":"User's associated PayID (if any)"}}}}}}
```

## The Error object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"Error":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Error code identifying the type of error"},"message":{"type":"string","description":"Human-readable error message"},"details":{"type":"object","nullable":true,"description":"Additional details about the error (when available)"}}}}}}}}
```

## The ValidationError object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"ValidationError":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was unsuccessful"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Indicates a validation error"},"message":{"type":"string","description":"Comma-separated list of validation errors"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}}}
```

## The CreateUserRequest object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"CreateUserRequest":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"User's email address (required)"},"twitterUsername":{"type":"string","description":"User's twitter username (optional)"},"walletAddress":{"type":"string","description":"User's blockchain wallet address (optional)"}}}}}}
```

## The UpdateUserRequest object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"UpdateUserRequest":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"User's updated email address"},"twitterUsername":{"type":"string","description":"User's updated twitter username"},"walletAddress":{"type":"string","description":"User's updated blockchain wallet address"}}}}}}
```

## The CreateUserResponse object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"CreateUserResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the created user"},"email":{"type":"string","format":"email","description":"User's email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's twitter username (if provided)"},"walletAddress":{"type":"string","nullable":true,"description":"User's blockchain wallet address (if provided)"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"}}},"meta":{"type":"object","description":"Additional metadata (empty for user creation)"}}}}}}
```

## The GetUsersResponse object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"GetUsersResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"type":"array","items":{"$ref":"#/components/schemas/User"},"description":"List of users associated with the partner"},"meta":{"type":"object","properties":{"count":{"type":"integer","description":"Total number of users in the response"}}}}},"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the user"},"email":{"type":"string","format":"email","description":"User's email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's twitter username (optional)"},"walletAddress":{"type":"string","nullable":true,"description":"User's blockchain wallet address (optional)"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"},"updatedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when the user was last updated"},"payId":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the payId"},"name":{"type":"string","description":"The payId name"}},"description":"User's associated PayID (if any)"}}}}}}
```

## The GetUserResponse object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"GetUserResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"$ref":"#/components/schemas/User"},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Success message"}}}}},"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the user"},"email":{"type":"string","format":"email","description":"User's email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's twitter username (optional)"},"walletAddress":{"type":"string","nullable":true,"description":"User's blockchain wallet address (optional)"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"},"updatedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when the user was last updated"},"payId":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the payId"},"name":{"type":"string","description":"The payId name"}},"description":"User's associated PayID (if any)"}}}}}}
```

## The UpdateUserResponse object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"UpdateUserResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the user"},"email":{"type":"string","format":"email","description":"User's updated email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's updated twitter username"},"walletAddress":{"type":"string","nullable":true,"description":"User's updated blockchain wallet address"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp when the user was updated"}}},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Success message"}}}}}}}}
```

## The DisconnectWalletResponse object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"DisconnectWalletResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the user"},"email":{"type":"string","format":"email","description":"User's email address"},"twitterUsername":{"type":"string","nullable":true,"description":"User's twitter username"},"walletAddress":{"type":"string","nullable":true,"description":"User's wallet address (now null after disconnection)"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the user was created"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp when the wallet was disconnected"}}},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Success message"}}}}}}}}
```

## The DeleteUserResponse object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API  - Users","version":"1.0.0"},"components":{"schemas":{"DeleteUserResponse":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates that the request was successful"},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Success message indicating the user was disassociated"}}}}}}}}
```


# PayIDs

## Claim a PayID

> Claims a PayID for a user. All PayIDs are currently free to claim.\
> \
> The PayID must meet these requirements:\
> \- Must contain only letters, numbers, hyphens, and underscores\
> \- Must be at least 1 character long\
> \- Must not be already claimed by another user\
> \
> Users can only have one active PayID at a time. If a user claims a new PayID,\
> their previous PayID will be automatically replaced.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Pay IDs","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n"}},"schemas":{"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}},"paths":{"/pay-ids":{"post":{"summary":"Claim a PayID","description":"Claims a PayID for a user. All PayIDs are currently free to claim.\n\nThe PayID must meet these requirements:\n- Must contain only letters, numbers, hyphens, and underscores\n- Must be at least 1 character long\n- Must not be already claimed by another user\n\nUsers can only have one active PayID at a time. If a user claims a new PayID,\ntheir previous PayID will be automatically replaced.\n","tags":["Pay ID"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","payId","expiresInYears"],"properties":{"email":{"type":"string","format":"email","description":"Email address of the user"},"twitterUsername":{"type":"string","description":"Twitter username of the user"},"payId":{"type":"string","description":"The PayID to claim. Can only contain letters, numbers, hyphens, and underscores.\nMust match the pattern [a-zA-Z0-9-_]+\n"},"expiresInYears":{"type":"integer","minimum":1,"maximum":10,"description":"Number of years until the PayID expires (1-10)"}}}}}},"responses":{"201":{"description":"PayID claimed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"payId":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"transactionId":{"type":"string","format":"uuid"}}},"meta":{"type":"object","properties":{"message":{"type":"string"}}}}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"PayID already taken","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Search for PayIDs and retrieve user information

> Search for PayIDs based on query parameters. The search is case-insensitive\
> and will return partial matches.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Pay IDs","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n"}},"schemas":{"PayId":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"The PayID name. Can only contain letters, numbers, hyphens, and underscores.\nMust match the pattern [a-zA-Z0-9-_]+\n"},"userId":{"type":"string","format":"uuid","nullable":true},"status":{"type":"string","enum":["ACTIVE","RESERVED"]},"expiresAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}},"paths":{"/pay-ids/search":{"get":{"summary":"Search for PayIDs and retrieve user information","description":"Search for PayIDs based on query parameters. The search is case-insensitive\nand will return partial matches.\n","tags":["Pay ID"],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1},"description":"Search query (minimum 1 character)"},{"name":"limit","in":"query","schema":{"type":"integer","default":10,"maximum":100},"description":"Maximum number of results to return (up to 100)"},{"name":"activeOnly","in":"query","schema":{"type":"boolean","default":true},"description":"When true, only returns active PayIDs (not temporary reservations)"}],"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/PayId"}}}},"meta":{"type":"object","properties":{"count":{"type":"integer"},"message":{"type":"string"}}}}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## The Error object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Pay IDs","version":"1.0.0"},"components":{"schemas":{"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}}}
```

## The ValidationError object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Pay IDs","version":"1.0.0"},"components":{"schemas":{"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}}}}}
```

## The PayId object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Pay IDs","version":"1.0.0"},"components":{"schemas":{"PayId":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"The PayID name. Can only contain letters, numbers, hyphens, and underscores.\nMust match the pattern [a-zA-Z0-9-_]+\n"},"userId":{"type":"string","format":"uuid","nullable":true},"status":{"type":"string","enum":["ACTIVE","RESERVED"]},"expiresAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}
```


# Routes

API endpoints for managing Routes in the PayID platform.

Routes define how incoming payments are handled, including which networks and tokens are accepted, optional token swaps, and the destination wallet for final transfers.

When creating a route, consider these important factors:

* Each route must have a unique combination of incoming networks and tokens per user.
* Certain network-token combinations are not supported (see Unsupported Combinations section).
* Users can have multiple routes with different configurations.

## Create a new route

> Create a new route for a specific user. A route defines how incoming payments should be processed.\
> Routes must have a unique combination of incoming networks and tokens per user.\
> Certain network-token combinations are not supported (see API description for details).<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Routes","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the Routes endpoints:\n\n- **route:create** - Create new routes for users associated with your partner account\n- **route:read** - View routes for users associated with your partner account\n- **route:update** - Modify route information for users associated with your partner account\n- **route:delete** - Delete routes for users associated with your partner account\n"}},"schemas":{"Route":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"Name of the route.\nMinimum length: 1 character\n"},"incomingWallets":{"type":"array","items":{"type":"string"}},"incomingNetworks":{"type":"array","items":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"]}},"incomingTokens":{"type":"array","items":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"]}},"swapNetwork":{"type":"string","nullable":true,"enum":["ETH","POL","OP","BNB","BASE"]},"swapToken":{"type":"string","nullable":true,"enum":["USDT","USDC","ETH","BNB","POL"]},"outgoingWallet":{"type":"string","description":"Destination wallet address where funds will be sent.\nThe system does minimal validation on this field - it only verifies it's a non-empty string.\nEnsure you're providing a valid blockchain address for the corresponding network.\n"},"userId":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}},"paths":{"/routes":{"post":{"summary":"Create a new route","description":"Create a new route for a specific user. A route defines how incoming payments should be processed.\nRoutes must have a unique combination of incoming networks and tokens per user.\nCertain network-token combinations are not supported (see API description for details).\n","tags":["Routes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId","name","incomingNetworks","incomingTokens","outgoingWallet"],"properties":{"userId":{"type":"string","format":"uuid","description":"ID of the user this route belongs to"},"name":{"type":"string","description":"Name of the route.\nMinimum length: 1 character.\n"},"incomingWallets":{"type":"array","items":{"type":"string"},"description":"List of incoming wallet addresses that can use this route.\nThe system performs minimal validation - verify addresses are valid for the corresponding blockchain.\n"},"incomingNetworks":{"type":"array","items":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"]},"description":"List of incoming networks this route supports"},"incomingTokens":{"type":"array","items":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"]},"description":"List of incoming tokens this route supports.\nNote that certain network-token combinations are not supported.\n"},"swapNetwork":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"],"nullable":true,"description":"Network to swap on (optional).\nIf provided, swapToken must also be specified.\n"},"swapToken":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"],"nullable":true,"description":"Token to swap to (optional).\nIf provided, swapNetwork must also be specified.\n"},"outgoingWallet":{"type":"string","description":"Destination wallet address where funds will be sent.\nThe system performs minimal validation - ensure you're providing a valid blockchain address \nfor the corresponding network.\n"}}}}}},"responses":{"201":{"description":"Route created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful"},"data":{"type":"object","properties":{"route":{"$ref":"#/components/schemas/Route"}}},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Status message"}}}}}}}},"400":{"description":"Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

### Unsupported Combinations

The following network - token combinations are not supported:

| Network | Token |
| ------- | ----- |
| OP      | POL   |
| OP      | BNB   |
| BASE    | USDT  |
| BASE    | BNB   |
| BASE    | POL   |

## Get all routes for a user

> Retrieve all routes for a specific user.

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Routes","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the Routes endpoints:\n\n- **route:create** - Create new routes for users associated with your partner account\n- **route:read** - View routes for users associated with your partner account\n- **route:update** - Modify route information for users associated with your partner account\n- **route:delete** - Delete routes for users associated with your partner account\n"}},"schemas":{"Route":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"Name of the route.\nMinimum length: 1 character\n"},"incomingWallets":{"type":"array","items":{"type":"string"}},"incomingNetworks":{"type":"array","items":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"]}},"incomingTokens":{"type":"array","items":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"]}},"swapNetwork":{"type":"string","nullable":true,"enum":["ETH","POL","OP","BNB","BASE"]},"swapToken":{"type":"string","nullable":true,"enum":["USDT","USDC","ETH","BNB","POL"]},"outgoingWallet":{"type":"string","description":"Destination wallet address where funds will be sent.\nThe system does minimal validation on this field - it only verifies it's a non-empty string.\nEnsure you're providing a valid blockchain address for the corresponding network.\n"},"userId":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}},"paths":{"/routes/{userId}":{"get":{"summary":"Get all routes for a user","description":"Retrieve all routes for a specific user.","tags":["Routes"],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the user to get routes for"}],"responses":{"200":{"description":"Routes retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful"},"data":{"type":"object","properties":{"routes":{"type":"array","items":{"$ref":"#/components/schemas/Route"}},"count":{"type":"integer","description":"Total number of routes"}}},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Status message"}}}}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Update an existing route

> Update an existing route by ID. Supports partial updates.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Routes","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the Routes endpoints:\n\n- **route:create** - Create new routes for users associated with your partner account\n- **route:read** - View routes for users associated with your partner account\n- **route:update** - Modify route information for users associated with your partner account\n- **route:delete** - Delete routes for users associated with your partner account\n"}},"schemas":{"Route":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"Name of the route.\nMinimum length: 1 character\n"},"incomingWallets":{"type":"array","items":{"type":"string"}},"incomingNetworks":{"type":"array","items":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"]}},"incomingTokens":{"type":"array","items":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"]}},"swapNetwork":{"type":"string","nullable":true,"enum":["ETH","POL","OP","BNB","BASE"]},"swapToken":{"type":"string","nullable":true,"enum":["USDT","USDC","ETH","BNB","POL"]},"outgoingWallet":{"type":"string","description":"Destination wallet address where funds will be sent.\nThe system does minimal validation on this field - it only verifies it's a non-empty string.\nEnsure you're providing a valid blockchain address for the corresponding network.\n"},"userId":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}},"paths":{"/routes/{id}":{"put":{"summary":"Update an existing route","description":"Update an existing route by ID. Supports partial updates.\n","tags":["Routes"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the route to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId"],"properties":{"userId":{"type":"string","format":"uuid","description":"ID of the user this route belongs to.\nThis is required as an authorization check, not as a field to update.\n"},"name":{"type":"string","description":"Name of the route.\nMinimum length: 1 character.\n"},"incomingWallets":{"type":"array","items":{"type":"string"},"description":"List of incoming wallet addresses"},"incomingNetworks":{"type":"array","items":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"]},"description":"List of incoming networks.\nIf updated, will be validated against incomingTokens for supported combinations.\n"},"incomingTokens":{"type":"array","items":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"]},"description":"List of incoming tokens.\nIf updated, will be validated against incomingNetworks for supported combinations.\n"},"swapNetwork":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"],"nullable":true,"description":"Network to swap on (optional)"},"swapToken":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"],"description":"Token to swap to (optional)"},"outgoingWallet":{"type":"string","description":"Destination wallet address.\nMinimal validation is performed - ensure it's a valid address for the network.\n"}}}}}},"responses":{"200":{"description":"Route updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful"},"data":{"type":"object","properties":{"route":{"$ref":"#/components/schemas/Route"}}},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Status message"}}}}}}}},"400":{"description":"Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden - User does not have access to this route","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Route or user not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Delete a route

> Delete a route by ID.

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Routes","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n\n## Required Permissions\n\nThe following permissions are required for the Routes endpoints:\n\n- **route:create** - Create new routes for users associated with your partner account\n- **route:read** - View routes for users associated with your partner account\n- **route:update** - Modify route information for users associated with your partner account\n- **route:delete** - Delete routes for users associated with your partner account\n"}},"schemas":{"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}},"paths":{"/routes/{id}":{"delete":{"summary":"Delete a route","description":"Delete a route by ID.","tags":["Routes"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the route to delete"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId"],"properties":{"userId":{"type":"string","format":"uuid","description":"ID of the user this route belongs to"}}}}}},"responses":{"200":{"description":"Route deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful"},"data":{"type":"object"},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Status message"}}}}}}}},"400":{"description":"Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden - User does not have access to this route","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Route or user not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## The Error object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Routes","version":"1.0.0"},"components":{"schemas":{"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}}}
```

## The ValidationError object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Routes","version":"1.0.0"},"components":{"schemas":{"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}}}}}
```

## The Route object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Routes","version":"1.0.0"},"components":{"schemas":{"Route":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"Name of the route.\nMinimum length: 1 character\n"},"incomingWallets":{"type":"array","items":{"type":"string"}},"incomingNetworks":{"type":"array","items":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"]}},"incomingTokens":{"type":"array","items":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"]}},"swapNetwork":{"type":"string","nullable":true,"enum":["ETH","POL","OP","BNB","BASE"]},"swapToken":{"type":"string","nullable":true,"enum":["USDT","USDC","ETH","BNB","POL"]},"outgoingWallet":{"type":"string","description":"Destination wallet address where funds will be sent.\nThe system does minimal validation on this field - it only verifies it's a non-empty string.\nEnsure you're providing a valid blockchain address for the corresponding network.\n"},"userId":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}
```


# Transactions

API endpoints for managing transactions in the PayID platform

&#x20;These endpoints enable users to initiate transactions for sending tokens to PayID recipients or wallet addresses. Also they provide users with the ability to retrieve their transaction activity history.

## Initialize a transaction

> Initialize a transaction for sending tokens to a PayID recipient or wallet address.\
> \
> \## Token & Network Compatibility\
> \
> Only specific token and network combinations are supported. Currently supported:\
> \
> \*\*Tokens\*\*: USDT, USDC, ETH, BNB, POL\
> \
> \*\*Networks\*\*: ETH, POL, OP, BNB, BASE\
> \
> \*\*Unsupported combinations\*\*:\
> \- POL token on OP network\
> \- BNB token on OP network\
> \- USDT token on BASE network\
> \- BNB token on BASE network\
> \- POL token on BASE network\
> \
> \## ERC20 Token Approvals\
> \
> For ERC20 tokens (USDT, USDC), when the user has insufficient token allowance, an \`approveTx\` will be included in the response.\
> The client must execute this approval transaction first, then execute the main transaction.\
> \
> Native tokens (ETH, BNB, POL) do not require approval transactions.\
> \
> \## Route and Swap Logic\
> \
> When sending to a PayID that has routes configured, automatic token swapping may occur based on the route settings.\
> In such cases, fee information will be included in the response.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Transactions","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n"}},"schemas":{"TransactionInitialize":{"type":"object","properties":{"amount":{"type":"number","format":"float"},"token":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"]},"network":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"]},"tx":{"type":"object","properties":{"to":{"type":"string"},"data":{"type":"string"},"value":{"type":"string"},"chainId":{"type":"integer"}}},"fees":{"type":"object","properties":{"applicationFee":{"type":"number","nullable":true},"protocolFee":{"type":"number","nullable":true},"bridgeFee":{"type":"number","nullable":true}}},"approveTx":{"type":"object","nullable":true,"description":"When sending ERC20 tokens (such as USDT, USDC), this transaction must be executed first to approve the token spending.\nThis field is only included when the user has insufficient token allowance for the transaction.\nThe client must execute this approval transaction first, then execute the main transaction.\n\nNative tokens (like ETH, BNB, POL) do not require approval, so this field will be null in those cases.\n","properties":{"to":{"type":"string","description":"Token contract address"},"data":{"type":"string","description":"Approval transaction data (encoded approve function call)"},"chainId":{"type":"integer","description":"Chain ID for the approval transaction"}}}}},"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}},"paths":{"/transactions":{"post":{"summary":"Initialize a transaction","description":"Initialize a transaction for sending tokens to a PayID recipient or wallet address.\n\n## Token & Network Compatibility\n\nOnly specific token and network combinations are supported. Currently supported:\n\n**Tokens**: USDT, USDC, ETH, BNB, POL\n\n**Networks**: ETH, POL, OP, BNB, BASE\n\n**Unsupported combinations**:\n- POL token on OP network\n- BNB token on OP network\n- USDT token on BASE network\n- BNB token on BASE network\n- POL token on BASE network\n\n## ERC20 Token Approvals\n\nFor ERC20 tokens (USDT, USDC), when the user has insufficient token allowance, an `approveTx` will be included in the response.\nThe client must execute this approval transaction first, then execute the main transaction.\n\nNative tokens (ETH, BNB, POL) do not require approval transactions.\n\n## Route and Swap Logic\n\nWhen sending to a PayID that has routes configured, automatic token swapping may occur based on the route settings.\nIn such cases, fee information will be included in the response.\n","tags":["Transactions"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId","amount","token","network"],"properties":{"userId":{"type":"string","format":"uuid","description":"ID of the user initiating the transaction"},"amount":{"type":"number","format":"float","description":"Amount to send (must be a positive number)"},"token":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"],"description":"Token to send"},"network":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"],"description":"Network to use for the transaction"},"recipientPayId":{"type":"string","description":"PayID of the recipient (either recipientPayId or walletAddress is required, but not both)"},"walletAddress":{"type":"string","description":"Wallet address of the recipient (either recipientPayId or walletAddress is required, but not both)"},"message":{"type":"string","maxLength":280,"description":"Optional message to include with the transaction (max 280 characters)"}}}}}},"responses":{"200":{"description":"Transaction initialized successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful"},"data":{"$ref":"#/components/schemas/TransactionInitialize"},"meta":{"type":"object","properties":{"message":{"type":"string","description":"Status message"}}}}}}}},"400":{"description":"Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Recipient not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get user transaction activities

> Get transaction activities for a specific user with pagination.\
> \
> This endpoint returns both incoming (RECEIVE) and outgoing (SEND) transactions\
> for the specified user, sorted by creation date in descending order (newest first).\
> \
> The response includes detailed information about each transaction, including\
> amounts, fees, and related route information when applicable.<br>

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Transactions","version":"1.0.0"},"servers":[{"url":"https://api.reveel.id/v1","description":"Production API Server"},{"url":"https://staging-api.reveel.id/v1","description":"Staging API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API keys are provided when a partner account is created and can be regenerated if needed.\nTo authenticate requests, include your API key in the request headers using the Bearer token format:\n`Authorization: Bearer your-api-key`\n"}},"schemas":{"TransactionActivity":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["SEND","RECEIVE"]},"amount":{"type":"number","format":"float"},"token":{"type":"string"},"network":{"type":"string"},"status":{"type":"string","enum":["PENDING","COMPLETED","FAILED"]},"txHash":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Pagination":{"type":"object","properties":{"totalCount":{"type":"integer"},"totalPages":{"type":"integer"},"currentPage":{"type":"integer"},"pageSize":{"type":"integer"}}},"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}},"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}},"paths":{"/transactions/users/{userId}/activities":{"get":{"summary":"Get user transaction activities","description":"Get transaction activities for a specific user with pagination.\n\nThis endpoint returns both incoming (RECEIVE) and outgoing (SEND) transactions\nfor the specified user, sorted by creation date in descending order (newest first).\n\nThe response includes detailed information about each transaction, including\namounts, fees, and related route information when applicable.\n","tags":["Transactions"],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the user to get activities for"},{"name":"page","in":"query","schema":{"type":"integer","default":1},"description":"Page number for pagination"},{"name":"pageSize","in":"query","schema":{"type":"integer","default":10},"description":"Number of items per page"}],"responses":{"200":{"description":"Transaction activities retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful"},"data":{"type":"object","properties":{"activities":{"type":"array","items":{"$ref":"#/components/schemas/TransactionActivity"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"meta":{"type":"object"}}}}}},"400":{"description":"Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden - User does not have access to this data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## The Error object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Transactions","version":"1.0.0"},"components":{"schemas":{"Error":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","nullable":true}}}}}}}}
```

## The ValidationError object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Transactions","version":"1.0.0"},"components":{"schemas":{"ValidationError":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}}}}}}}}}
```

## The TransactionInitialize object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Transactions","version":"1.0.0"},"components":{"schemas":{"TransactionInitialize":{"type":"object","properties":{"amount":{"type":"number","format":"float"},"token":{"type":"string","enum":["USDT","USDC","ETH","BNB","POL"]},"network":{"type":"string","enum":["ETH","POL","OP","BNB","BASE"]},"tx":{"type":"object","properties":{"to":{"type":"string"},"data":{"type":"string"},"value":{"type":"string"},"chainId":{"type":"integer"}}},"fees":{"type":"object","properties":{"applicationFee":{"type":"number","nullable":true},"protocolFee":{"type":"number","nullable":true},"bridgeFee":{"type":"number","nullable":true}}},"approveTx":{"type":"object","nullable":true,"description":"When sending ERC20 tokens (such as USDT, USDC), this transaction must be executed first to approve the token spending.\nThis field is only included when the user has insufficient token allowance for the transaction.\nThe client must execute this approval transaction first, then execute the main transaction.\n\nNative tokens (like ETH, BNB, POL) do not require approval, so this field will be null in those cases.\n","properties":{"to":{"type":"string","description":"Token contract address"},"data":{"type":"string","description":"Approval transaction data (encoded approve function call)"},"chainId":{"type":"integer","description":"Chain ID for the approval transaction"}}}}}}}}
```

## The TransactionActivity object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Transactions","version":"1.0.0"},"components":{"schemas":{"TransactionActivity":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["SEND","RECEIVE"]},"amount":{"type":"number","format":"float"},"token":{"type":"string"},"network":{"type":"string"},"status":{"type":"string","enum":["PENDING","COMPLETED","FAILED"]},"txHash":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}
```

## The Pagination object

```json
{"openapi":"3.0.0","info":{"title":"PayID REST API - Transactions","version":"1.0.0"},"components":{"schemas":{"Pagination":{"type":"object","properties":{"totalCount":{"type":"integer"},"totalPages":{"type":"integer"},"currentPage":{"type":"integer"},"pageSize":{"type":"integer"}}}}}}
```


# Transactions - old

Here is the complete **Transactions API** page for Reveel PayID. It includes detailed request/response formats, error cases, and a parameter reference table.

***

### Parameter Reference

| Field            | Type      | Required               | Description                                                      |
| ---------------- | --------- | ---------------------- | ---------------------------------------------------------------- |
| `userId`         | string    | Yes                    | Sender’s user ID                                                 |
| `recipientPayId` | string    | Required\*             | PayID of the recipient (optional if `walletAddress` is provided) |
| `walletAddress`  | string    | Required\*             | Recipient's wallet address (alternative to PayID)                |
| `amount`         | number    | Yes                    | Amount to send                                                   |
| `token`          | string    | Yes                    | Token symbol (e.g. ETH, USDC)                                    |
| `network`        | string    | Yes                    | Network symbol (e.g. ETH, POL, BNB)                              |
| `message`        | string    | Optional               | Optional message                                                 |
| `privateKey`     | string    | Yes (in test endpoint) | Sender's private key for testing submission                      |
| `transaction`    | object    | Yes (in test endpoint) | Raw transaction object for signing                               |
| `confirmed`      | boolean   | Yes (webhook)          | Whether the tx is confirmed                                      |
| `txs`            | object\[] | Yes (webhook)          | Array of transaction metadata                                    |
| `page`           | number    | Optional               | Page number (for activity pagination)                            |
| `pageSize`       | number    | Optional               | Items per page (pagination)                                      |

### 1. Initialize Transaction

&#x20;`POST /transact/init-transaction`\
**Authentication:** Required

**Description**

Initializes a payment transaction for a user. The API computes routing logic, swap requirements, fees, and returns all data needed to sign and broadcast the transaction.

**Request Body**

```json
{
  "userId": "user-id",
  "recipientPayId": "username",        // Optional
  "walletAddress": "0x123abc...",      // Optional
  "amount": 1.5,
  "token": "ETH",
  "network": "ETH",
  "message": "Payment for services"    // Optional
}
```

> Note: Either `recipientPayId` or `walletAddress` must be provided.

**Success Response — `200 OK`**

```json
{
  "success": true,
  "message": "Transaction initialized successfully",
  "data": {
    "amount": 1.5,
    "token": "ETH",
    "network": "ETH",
    "tx": {
      "to": "0xrecipient...",
      "data": "0x6572b...",
      "value": "1500000000000000000",
      "chainId": "1"
    },
    "fees": {
      "applicationFee": null,
      "protocolFee": null,
      "bridgeFee": null
    }
  }
}
```

**Error Responses**

| HTTP Code                   | Description                                                 |
| --------------------------- | ----------------------------------------------------------- |
| `400 Bad Request`           | Missing fields, invalid types, unsupported token or network |
| `404 Not Found`             | PayID or wallet not found                                   |
| `500 Internal Server Error` | Transaction setup failed                                    |

Example:

```json
{
  "success": false,
  "message": "Unsupported token or network combination",
  "error": "Token ETH is not supported on network XYZ"
}
```

***

### 2. Transaction Webhook

&#x20;`POST /transact/txn-webhook`\
**Authentication:** None\
**Description:** Receives real-time transaction confirmations (from Moralis or equivalent).

**Request Body**

```json
{
  "confirmed": true,
  "chainId": "1",
  "txs": [
    {
      "hash": "0xtxhash...",
      "gas": "21000",
      "input": "0xinput...",
      "fromAddress": "0xsender...",
      "toAddress": "0xrecipient...",
      "value": "1000000000000000000",
      "triggered_by": ["0xsender..."]
    }
  ]
}
```

**Success Response — `200 OK`**

```json
{
  "ok": true
}
```

**Error Responses**

| HTTP Code                   | Description                                                        |
| --------------------------- | ------------------------------------------------------------------ |
| `200 OK`                    | If payload is invalid, returns `success: false` with error message |
| `500 Internal Server Error` | Unexpected error during processing                                 |

***

### 3. Get User Activity

`GET /transact/get-activity`\
**Authentication:** Required

**Query Parameters**

* `userId` (string, required)
* `page` (number, optional, default: 1)
* `pageSize` (number, optional, default: 10)

**Success Response — `200 OK`**

```json
{
  "success": true,
  "data": {
    "activities": [
      {
        "id": "activity-id",
        "hash": "0xtxhash...",
        "confirmed": true,
        "message": "Payment for services",
        "amount": "1.5",
        "senderId": "sender-user-id",
        "receiverId": "receiver-user-id",
        "walletAddress": "0xwallet...",
        "routeId": "route-id",
        "incomingNetwork": "ETH",
        "incomingToken": "ETH",
        "swapNetwork": "POL",
        "swapToken": "USDC",
        "applicationFee": "0.01",
        "bridgeFee": "0.02",
        "protocolFee": "0.005",
        "totalFee": "0.035",
        "createdAt": "2023-01-01T00:00:00.000Z",
        "updatedAt": "2023-01-01T00:00:00.000Z"
      }
    ],
    "pagination": {
      "totalCount": 45,
      "totalPages": 5,
      "currentPage": 1,
      "pageSize": 10
    }
  }
}
```

**Error Responses**

| HTTP Code                   | Description             |
| --------------------------- | ----------------------- |
| `400 Bad Request`           | Missing `userId`        |
| `401 Unauthorized`          | Invalid/missing API key |
| `500 Internal Server Error` | Data fetch failed       |


# Overview -old

Welcome to the Reveel PayID REST API reference. This section contains detailed documentation for every publicly accessible endpoint available to partner applications, wallets, and agents.

Reveel PayID APIs allow you to:

* Register users and PayIDs
* Define and manage custom routing rules
* Initiate cross-chain transactions
* Retrieve user and transaction history

***

#### 🔐 Authentication

All API requests require a valid API key in the `Authorization` header.

```http
httpCopyEditAuthorization: Bearer your-api-key
Content-Type: application/json
Accept: application/json
```

> 💡 API keys are issued after your application is approved. Request access here

***

#### 🌍 Base URL

```
https://api.reveel.id/v1
```

***

#### 🗂 API Categories

Endpoints are organized by functionality:

| Category             | Description                                      |
| -------------------- | ------------------------------------------------ |
| **User APIs**        | Create and manage platform users                 |
| **PayID APIs**       | Claim, check, and search PayIDs                  |
| **Routes APIs**      | Configure how users want to receive payments     |
| **Transaction APIs** | Trigger, track, and monitor payment flows        |
| **Agent APIs**       | Engage with a smart assistant to handle payments |

***

#### 📦 Response Format

All responses follow a standard structure:

```json
jsonCopyEdit{
  "success": true,
  "message": "Action completed successfully",
  "data": {
    // endpoint-specific payload
  }
}
```

In case of error:

```json
jsonCopyEdit{
  "success": false,
  "message": "Invalid PayID",
  "error": "PAYID_NOT_FOUND"
}
```

***

#### 📋 Rate Limits & Versioning

* All endpoints are versioned under `/v1`
* Current rate limits: **100 requests/minute** (subject to change)
* Abuse or misuse of APIs may result in throttling or key revocation

***

#### 🧰 Tools

You can test the API using:

* cURL
* Postman Collection (coming soon)
* API playground (coming soon)


# Integration Best Practices - old

This guide outlines best practices for developers integrating with the Reveel PayID API. Following these principles will help ensure a reliable, secure, and scalable integration.

***

### 1. **Authentication Best Practices**

* Always include the following headers in every request:

  ```
  Authorization: Bearer your-api-key
  Accept: application/json
  Content-Type: application/json  // For POST/PUT/DELETE
  ```
* Store API keys securely — never expose them in frontend code or public repositories.
* If your backend supports it, rotate API keys periodically and use environment variables for injection.

***

### 2. **Use Idempotent Requests**

* **Avoid duplicate actions** by ensuring critical POST operations (e.g., route creation, transaction initialization) are idempotent on your side using:
  * **Idempotency keys** (UUID v4 stored per action)
  * **Client-side tracking** of previously submitted data
* While the Reveel API does not currently enforce idempotency keys natively, it’s a good client-side practice to avoid accidental duplicates (e.g., resubmitting forms or retrying after a timeout).

***

### 3. **Graceful Error Handling**

* All errors follow a consistent format:

  ```json
  {
    "success": false,
    "message": "Descriptive error",
    "error": "Field-level validation or server error details"
  }
  ```
* Parse the response safely and display human-readable messages to users, especially for known issues like:
  * `PayID already taken`
  * `Route conflict detected`
  * `Invalid token/network combination`
* Fallback to generic messages (e.g., "Something went wrong") only when necessary.

***

### 4. **Retry Logic & Backoff**

* Implement **retry with exponential backoff** for transient errors like `500` or timeouts.
* Do **not retry** on:
  * `400 Bad Request`
  * `401 Unauthorized`
  * `409 Conflict`
* Consider adding retry safeguards:
  * Max 3 retries
  * Backoff (e.g. 1s, 2s, 4s)

***

### 5. **Pagination & Rate Control**

* For endpoints like `/user/list` and `/transact/get-activity`, always:
  * Respect `page` and `pageSize` parameters
  * Implement pagination UI or auto-scroll loading
  * Cache recent pages where possible to reduce API calls

***

### 6. **Monitoring & Logging**

* Log all outgoing API requests with:
  * Timestamp
  * Endpoint
  * Response status
  * Any error messages received
* This helps in debugging user issues and diagnosing performance bottlenecks.

***

### 7. **Avoid Over-fetching**

* Fetch data only when needed (e.g., avoid calling `/get-routes` on every page load).
* Use local state caching, revalidation, or SWR-style hooks for React apps.

***

### 8. **Prepare for Changes**

* While current endpoints do not include version prefixes, breaking changes (when introduced) will be versioned via the base URL, e.g.:

  ```
  https://api.reveel.id/v2/
  ```
* Stay subscribed to dev notifications and changelogs if provided.

***

### 9. **Content-Type Issues**

To avoid incorrect HTML responses:

* Always set the `Accept: application/json` header.
* Never omit the `Content-Type: application/json` header for POST/PUT/DELETE.
* Add logic to detect unexpected content types in responses.

***

### 10. **Security Considerations**

* Throttle requests per user or per IP to prevent abuse.
* Never log sensitive data like private keys or full API keys.
* If integrating wallets, validate addresses and perform checks against phishing or scam lists.


# Users - old

The Users API allows you to create, fetch, update, disconnect, and disassociate users from your partner application. These users are the foundation for routing, identity, and transactions on Reveel PayID.

All endpoints require partner authentication.

***

### Authentication

```http
Authorization: Bearer your-api-key
Content-Type: application/json
Accept: application/json
```

***

### 1. Create user&#x20;

`POST /user/create`&#x20;

**Authentication**: Required

**Description**: Creates a new user and associates them with your partner account.

**Request Body**:

```json
{
  "email": "user@example.com",
  "twitterUsername": "username",
  "walletAddress": "0x123abc456def789ghi"
}
```

**Success Response – 201 Created**:

```json
{
  "message": "User created successfully",
  "user": {
    "id": "user-id",
    "email": "user@example.com",
    "twitterUsername": "username",
    "walletAddress": "0x123abc456def789ghi",
    "createdAt": "2023-03-01T00:00:00.000Z"
  }
}
```

**Error Responses**:

* 400 Bad Request

```json
{
  "error": "Validation error",
  "message": "Email is required"
}
```

* 401 Unauthorized

```json
{
  "error": "Unauthorized",
  "message": "Partner authentication required"
}
```

* 409 Conflict

```json
{
  "error": "User already exists",
  "message": "This user is already associated with your partner account",
  "userId": "existing-user-id"
}
```

* 500 Internal Server Error

```json
{
  "error": "Internal server error",
  "message": "Error message details"
}
```

***

### 2. Get All users&#x20;

&#x20;`GET /user/list`&#x20;

**Authentication**: Required

**Description**: Lists users associated with your partner.

**Query Parameters**:

* `page`: Page number (default: 1)
* `limit`: Users per page (default: 20)

**Success Response – 200 OK**:

```json
{
  "message": "Users retrieved successfully",
  "count": 2,
  "users": [
    {
      "id": "user-id-1",
      "email": "user1@example.com",
      "twitterUsername": "username1",
      "walletAddress": "0x123...",
      "createdAt": "2023-03-01T00:00:00.000Z",
      "payId": {
        "id": "payid-id-1",
        "name": "username1"
      }
    }
  ],
  "pagination": {
    "currentPage": 1,
    "totalPages": 1,
    "totalCount": 2,
    "perPage": 20
  }
}
```

**Error Responses**:

* 401 Unauthorized

```json
{
  "error": "Unauthorized",
  "message": "Partner authentication required"
}
```

* 500 Internal Server Error

```json
{
  "error": "Internal server error",
  "message": "Error message details"
}
```

***

### 3. Get a particular user by ID

&#x20;`GET /user/:id`&#x20;

**Authentication**: Required

**Description**: Fetches a user by ID if associated with your account.

**Success Response – 200 OK**:

```json
{
  "message": "User retrieved successfully",
  "user": {
    "id": "user-id-1",
    "email": "user1@example.com",
    "twitterUsername": "username1",
    "walletAddress": "0x123...",
    "createdAt": "2023-03-01T00:00:00.000Z",
    "payId": {
      "id": "payid-id-1",
      "name": "username1"
    }
  }
}
```

**Error Responses**:

* 401 Unauthorized

```json
{
  "error": "Unauthorized",
  "message": "Partner authentication required"
}
```

* 404 Not Found

```json
{
  "error": "User not found",
  "message": "This user does not exist or is not associated with your partner account"
}
```

* 500 Internal Server Error

```json
{
  "error": "Internal server error",
  "message": "Error message details"
}
```

***

### 4. Update user

&#x20; `PUT /user/:id`&#x20;

**Authentication**: Required

**Description**: Updates an existing user.

**Request Body**:

```json
{
  "email": "updated@example.com",
  "twitterUsername": "newusername",
  "walletAddress": "0x987zyx654wvu321tsr"
}
```

**Success Response – 200 OK**:

```json
{
  "message": "User updated successfully",
  "user": {
    "id": "user-id-1",
    "email": "updated@example.com",
    "twitterUsername": "newusername",
    "walletAddress": "0x987zyx654wvu321tsr",
    "updatedAt": "2023-03-10T00:00:00.000Z"
  }
}
```

**Error Responses**:

* 400 Bad Request

```json
{
  "error": "Validation error",
  "message": "Field validation failed"
}
```

* 401 Unauthorized

```json
{
  "error": "Unauthorized",
  "message": "Partner authentication required"
}
```

* 404 Not Found

```json
{
  "error": "User not found",
  "message": "This user does not exist or is not associated with your partner account"
}
```

* 409 Conflict

```json
{
  "error": "Update failed",
  "message": "The provided email is already associated with another user"
}
```

* 500 Internal Server Error

```json
{
  "error": "Internal server error",
  "message": "Error message details"
}
```

***

### 5. Disconnect Wallet

`POST /user/:id/disconnect-wallet`&#x20;

**Authentication**: Required

**Description**: Disconnects the wallet address of a user.

**Success Response – 200 OK**:

```json
{
  "message": "Wallet disconnected successfully",
  "user": {
    "id": "user-id-1",
    "walletAddress": null,
    "updatedAt": "2023-03-15T00:00:00.000Z"
  }
}
```

**Error Responses**:

* 400 Bad Request

```json
{
  "error": "Wallet disconnection failed",
  "message": "User does not have a connected wallet"
}
```

* 401 Unauthorized

```json
{
  "error": "Unauthorized",
  "message": "Partner authentication required"
}
```

* 404 Not Found

```json
{
  "error": "User not found",
  "message": "This user does not exist or is not associated with your partner account"
}
```

* 500 Internal Server Error

```json
{
  "error": "Internal server error",
  "message": "Error message details"
}
```

***

### 6. Delete user

`DELETE /user/:id`&#x20;

**Description**: Disassociates a user from your partner account (does not delete the user globally).

**Success Response – 200 OK**:

```json
{
  "message": "User disassociated from partner successfully"
}
```

**Error Responses**:

* 401 Unauthorized

```json
{
  "error": "Unauthorized",
  "message": "Partner authentication required"
}
```

* 404 Not Found

```json
{
  "error": "Association not found",
  "message": "No association between this user and partner found"
}
```

* 500 Internal Server Error

```json
{
  "error": "Internal server error",
  "message": "Error message details"
}
```


# PayIDs - old

### Parameter Reference

| Field            | Type    | Required     | Description                                             |
| ---------------- | ------- | ------------ | ------------------------------------------------------- |
| `userId`         | string  | Yes          | Unique ID of the user registering or checking a PayID   |
| `payId`          | string  | Yes          | Desired PayID username (case-insensitive, alphanumeric) |
| `expiresInYears` | number  | No           | For premium PayIDs: the number of years to reserve      |
| `q`              | string  | Yes (search) | Keyword to search PayIDs                                |
| `limit`          | number  | No           | Max number of search results (default: 10)              |
| `activeOnly`     | boolean | No           | Whether to return only active PayIDs (default: true)    |

***

### Authentication

All endpoints require authentication unless explicitly stated otherwise.

**Required Headers:**

```
Authorization: Bearer your-api-key
Content-Type: application/json
Accept: application/json
```

***

### 1. Register PayID

`POST /payid/claim`\
**Description:** Registers a free or premium PayID for a user.

#### Request Body

```json
{
  "userId": "user-id",
  "payId": "username",
  "expiresInYears": 1
}
```

#### Response – Premium PayID (Reserved)

```json
{
  "success": true,
  "message": "Premium PayID reserved for checkout",
  "data": {
    "payId": "username",
    "price": 10.0,
    "reservedUntil": "2023-01-01T00:30:00.000Z",
    "reservationId": "reservation-id",
    "checkoutUrl": "https://checkout.loop.markets/...",
    "loopItemId": "item-id"
  }
}
```

#### Response – Free PayID (Claimed)

```json
{
  "success": true,
  "message": "PayID claimed successfully",
  "data": {
    "payId": "username",
    "price": 0,
    "expiresAt": null,
    "transactionId": "transaction-id"
  }
}
```

#### Error Responses

| HTTP Code                   | Description                      |
| --------------------------- | -------------------------------- |
| `400 Bad Request`           | Missing or invalid fields        |
| `409 Conflict`              | PayID already claimed            |
| `500 Internal Server Error` | General server or Loop API issue |

```json
{
  "success": false,
  "message": "Invalid request data",
  "error": [
    {
      "code": "invalid_type",
      "expected": "string",
      "received": "undefined",
      "path": ["userId"],
      "message": "userId is required"
    }
  ]
}
```

***

### 2. Get PayID Price

`GET /payid/check-price`\
**Description:** Returns the current price for a given PayID using AI scoring.

#### Query Parameters

* `userId` (required)
* `payId` (required)

#### Success Response

```json
{
  "success": true,
  "message": "PayID price calculated successfully",
  "data": {
    "payId": "username",
    "price": 10.0,
    "score": 0.85,
    "cached": true
  }
}
```

#### Error Responses

| HTTP Code                   | Description                 |
| --------------------------- | --------------------------- |
| `400 Bad Request`           | Missing or malformed fields |
| `409 Conflict`              | PayID already taken         |
| `500 Internal Server Error` | Price check failure         |

***

### 3. Search PayIDs

`GET /payid/search`\
**Description:** Searches Reveel's database for PayIDs by keyword.

#### Query Parameters

* `q` (required): Search term
* `limit` (optional): Max number of results (default: 10)
* `activeOnly` (optional): Only return active PayIDs (default: true)

#### Success Response

```json
{
  "success": true,
  "message": "Found 1 PayID(s)",
  "data": {
    "results": [
      {
        "id": "payid-id",
        "name": "username",
        "userId": "user-id",
        "email": "user@example.com",
        "twitterUsername": "username",
        "walletAddress": "0x..."
      }
    ],
    "count": 1
  }
}
```

#### Error Responses

| HTTP Code                   | Description                      |
| --------------------------- | -------------------------------- |
| `400 Bad Request`           | Invalid or missing `q` parameter |
| `500 Internal Server Error` | Search error                     |

```json
{
  "success": false,
  "message": "Invalid search parameters",
  "error": [
    {
      "code": "invalid_type",
      "expected": "string",
      "received": "undefined",
      "path": ["q"],
      "message": "Search query is required"
    }
  ]
}
```

***

### 4. Premium PayID Purchase Webhook (Loop)

`POST /payid/loop-webhook`\
**Description:** Receives webhook events from Loop on premium PayID purchases.

#### Request Body

```json
{
  "agreementId": "agreement-id",
  "event": "TransferCreated",
  "itemId": "item-id",
  "invoiceId": "invoice-id",
  "networkName": "ethereum",
  "networkId": "1",
  "tokenSymbol": "USDC",
  "transferId": "transfer-id",
  "refId": "reservation-id"
}
```

#### Success Response

```json
{
  "success": true,
  "message": "received event TransferCreated"
}
```

#### Error Responses

| HTTP Code                   | Description               |
| --------------------------- | ------------------------- |
| `400 Bad Request`           | Invalid or missing fields |
| `404 Not Found`             | Reservation ID not found  |
| `500 Internal Server Error` | Failed to process webhook |

```json
{
  "success": false,
  "message": "Reservation not found",
  "error": "Reservation with ID reservation-id not found"
}
```


# Routes - old

The Routes API allows partners to configure how incoming funds should be routed, swapped, or sent out for each user. These configurations support cross-chain and token-specific routing logic.

### Parameter Reference

| Field              | Type      | Required                   | Description                                      |
| ------------------ | --------- | -------------------------- | ------------------------------------------------ |
| `userId`           | string    | Yes                        | ID of the user associated with the route         |
| `id`               | string    | Required for update/delete | Route identifier                                 |
| `name`             | string    | Optional                   | Friendly name for the route                      |
| `incomingWallets`  | string\[] | Optional                   | Specific wallets allowed to send to this route   |
| `incomingNetworks` | string\[] | Yes                        | Incoming chain identifiers (e.g., ETH, POL)      |
| `incomingTokens`   | string\[] | Yes                        | Supported tokens for the route (e.g., USDC, ETH) |
| `swapNetwork`      | string    | Optional                   | Chain where token should be swapped              |
| `swapToken`        | string    | Optional                   | Token to receive after swap                      |
| `outgoingWallet`   | string    | Yes                        | Final destination address for routed funds       |
| `routeId`          | string    | Optional                   | Used in conflict checks when editing             |

### 1. Create Route

**URL:** `POST /routes/create`\
**Authentication:** Required

**Request Body**

```json
{
  "userId": "user-id",
  "name": "Default Route",
  "incomingWallets": ["0x123...", "0x456..."],
  "incomingNetworks": ["ETH", "POL"],
  "incomingTokens": ["ETH", "USDC"],
  "swapNetwork": "POL",
  "swapToken": "USDC",
  "outgoingWallet": "0x789..."
}
```

**Success Response — `201 Created`**

```json
{
  "success": true,
  "message": "Route created successfully",
  "data": {
    "route": {
      "id": "route-id",
      "userId": "user-id",
      "name": "Default Route",
      "incomingWallets": ["0x123...", "0x456..."],
      "incomingNetworks": ["ETH", "POL"],
      "incomingTokens": ["ETH", "USDC"],
      "swapNetwork": "POL",
      "swapToken": "USDC",
      "outgoingWallet": "0x789...",
      "createdAt": "2023-01-01T00:00:00.000Z",
      "updatedAt": "2023-01-01T00:00:00.000Z"
    }
  }
}
```

**Error Responses**

| HTTP Code                   | Description                   |
| --------------------------- | ----------------------------- |
| `400 Bad Request`           | Missing or invalid parameters |
| `409 Conflict`              | Duplicate configuration       |
| `500 Internal Server Error` | Unexpected server failure     |

Example:

```json
{
  "success": false,
  "message": "Route configuration conflicts with existing routes",
  "error": "You already have routes configured for these network and token combinations"
}
```

***

### 2. Update Route

**URL:** `PUT /routes/edit-route`\
**Authentication:** Required

**Request Body**

```json
{
  "id": "route-id",
  "userId": "user-id",
  "name": "Updated Route",
  "incomingWallets": ["0x123..."],
  "incomingNetworks": ["ETH", "OP"],
  "incomingTokens": ["ETH", "USDT"],
  "swapNetwork": "BNB",
  "swapToken": "BNB",
  "outgoingWallet": "0x999..."
}
```

**Success Response — `200 OK`**

```json
{
  "success": true,
  "message": "Route updated successfully",
  "data": {
    "route": {
      "id": "route-id",
      ...
    }
  }
}
```

**Error Responses**

| HTTP Code                   | Description                            |
| --------------------------- | -------------------------------------- |
| `400 Bad Request`           | Missing required fields                |
| `403 Forbidden`             | Unauthorized to update the route       |
| `404 Not Found`             | Route does not exist                   |
| `409 Conflict`              | Route config clashes with existing one |
| `500 Internal Server Error` | Server-side issue                      |

***

### 3. Delete Route

**URL:** `DELETE /routes/delete-route`\
**Authentication:** Required

**Request Body**

```json
{
  "userId": "user-id",
  "id": "route-id"
}
```

**Success Response — `200 OK`**

```json
{
  "success": true,
  "message": "Route deleted successfully"
}
```

**Error Responses**

| HTTP Code                   | Description             |
| --------------------------- | ----------------------- |
| `400 Bad Request`           | Missing route ID        |
| `403 Forbidden`             | No permission to delete |
| `404 Not Found`             | Route not found         |
| `500 Internal Server Error` | Unexpected error        |

***

### 4. Get Routes

**URL:** `GET /routes/get-routes`\
**Authentication:** Required

**Query Parameters**

* `userId` (string, required)

**Success Response — `200 OK`**

```json
{
  "success": true,
  "message": "Found 2 route(s)",
  "data": {
    "routes": [ ... ],
    "count": 2
  }
}
```

**Error Responses**

| HTTP Code                   | Description      |
| --------------------------- | ---------------- |
| `400 Bad Request`           | Missing `userId` |
| `500 Internal Server Error` | Server error     |

***

### 5. Check Route Conflicts

**URL:** `POST /routes/route-exists`\
**Authentication:** Required

**Request Body**

```json
{
  "userId": "user-id",
  "incomingNetworks": ["ETH", "POL"],
  "incomingTokens": ["ETH", "USDC"],
  "routeId": "route-id" // optional when updating
}
```

**Success Response — No Conflict (200 OK)**

```json
{
  "success": true,
  "message": "Route configuration is available",
  "data": {
    "exists": false,
    "conflictingRoutes": []
  }
}
```

**Success Response — Conflict Found (200 OK)**

```json
{
  "success": true,
  "message": "Route configuration conflicts with existing routes",
  "data": {
    "exists": true,
    "conflictingRoutes": [
      {
        "id": "route-id-1",
        "name": "Default Route",
        "incomingNetworks": ["ETH"],
        "incomingTokens": ["USDC"]
      }
    ]
  }
}
```

**Error Responses**

| HTTP Code                   | Description                |
| --------------------------- | -------------------------- |
| `400 Bad Request`           | Missing or invalid request |
| `500 Internal Server Error` | Unexpected server failure  |


# Agents - old

The Agent API enables conversational interactions and message-driven workflows through a smart assistant interface. Users can send messages like "Send 5 USDC to Alice" and receive structured prompts or automated transaction suggestions.

### Parameter Reference

| Field            | Type    | Required                      | Description                                                    |
| ---------------- | ------- | ----------------------------- | -------------------------------------------------------------- |
| `userId`         | string  | Yes                           | The ID of the user sending/receiving messages                  |
| `message`        | string  | Yes                           | User input text for the agent                                  |
| `walletAddress`  | string  | Optional                      | Wallet context for the conversation                            |
| `roomId`         | string  | Yes (for room-specific fetch) | Identifier for a specific chat room                            |
| `page`           | number  | Optional                      | Page number for pagination                                     |
| `pageSize`       | number  | Optional                      | Number of messages per page                                    |
| `messageContent` | string  | Output                        | Agent or user message body                                     |
| `isSystem`       | boolean | Output                        | Indicates whether the message is generated by the system/agent |
| `action`         | string  | Output                        | Action type, e.g. `"NONE"` (may expand in future)              |

### 1. Send Message to Agent

`POST /agent/message`\
**Authentication:** Required

**Description**

Sends a message to the Reveel agent from a user. The agent can respond with a prompt, system action, or next-step suggestion.

**Request Body**

```json
{
  "message": "Hello, I'd like to send some ETH to bob",
  "walletAddress": "0x...",
  "userId": "user-id"
}
```

**Success Response — `200 OK`**

```json
{
  "roomCreated": {
    "roomId": "room-id",
    "ownerId": "user-id",
    "isNew": true
  },
  "messages": [
    {
      "roomId": "room-id",
      "messageId": "message-id",
      "messageContent": "I'll help you send ETH to bob. How much would you like to send?",
      "ownerId": "user-id",
      "action": "NONE",
      "isSystem": true
    }
  ],
  "data": null
}
```

**Error Responses**

| HTTP Code                   | Description                         |
| --------------------------- | ----------------------------------- |
| `400 Bad Request`           | Missing `userId` or invalid message |
| `404 Not Found`             | User not found                      |
| `500 Internal Server Error` | Messaging or AI agent error         |

***

### 2. Get Rooms

`GET /agent/rooms`\
**Authentication:** Required

**Query Parameters**

* `userId` (string, required)

**Success Response — `200 OK`**

```json
[
  {
    "roomId": "room-id-1",
    "ownerId": "user-id",
    "createdAt": "2023-01-01T00:00:00.000Z",
    "updatedAt": "2023-01-01T00:00:00.000Z"
  },
  {
    "roomId": "room-id-2",
    "ownerId": "user-id",
    "createdAt": "2023-01-01T00:00:00.000Z",
    "updatedAt": "2023-01-01T00:00:00.000Z"
  }
]
```

**Error Responses**

| HTTP Code         | Description                          |
| ----------------- | ------------------------------------ |
| `400 Bad Request` | Missing user ID                      |
| `404 Not Found`   | User not found                       |
| `400 Bad Request` | General error (e.g. malformed input) |

***

### 3. Get Latest Room Messages

&#x20;`GET /agent/get-latest-room-messages`\
**Authentication:** Required

**Query Parameters**

* `userId` (string, required)
* `page` (number, optional, default: 1)
* `pageSize` (number, optional, default: 20)

**Success Response — `200 OK`**

```json
{
  "messages": [
    {
      "id": "message-id",
      "roomId": "room-id",
      "messageId": "message-uuid",
      "messageContent": "Hello, I'd like to send some ETH to bob",
      "ownerId": "user-id",
      "action": "NONE",
      "isSystem": false,
      "createdAt": "2023-01-01T00:00:00.000Z"
    },
    {
      "id": "message-id-2",
      "roomId": "room-id",
      "messageId": "message-uuid-2",
      "messageContent": "I'll help you send ETH to bob. How much would you like to send?",
      "ownerId": "user-id",
      "action": "NONE",
      "isSystem": true,
      "createdAt": "2023-01-01T00:00:00.000Z"
    }
  ],
  "totalCount": 2,
  "page": 1,
  "pageSize": 20,
  "totalPages": 1
}
```

**Error Responses**

| HTTP Code         | Description                   |
| ----------------- | ----------------------------- |
| `400 Bad Request` | Missing user ID or room ID    |
| `404 Not Found`   | User not found                |
| `400 Bad Request` | Invalid input or system error |

***

### 4. Get Messages from Specific Room

`GET /agent/rooms/:roomId`\
**Authentication:** Required

**Path Parameters**

* `roomId` (string, required)

**Query Parameters**

* `userId` (string, required)
* `page` (number, optional, default: 1)
* `pageSize` (number, optional, default: 20)

**Success Response — `200 OK`**

```json
{
  "messages": [
    {
      "id": "message-id",
      "roomId": "room-id",
      "messageId": "message-uuid",
      "messageContent": "Hello",
      "ownerId": "user-id",
      "action": "NONE",
      "isSystem": false,
      "createdAt": "2023-01-01T00:00:00.000Z"
    }
  ],
  "totalCount": 1,
  "page": 1,
  "pageSize": 20,
  "totalPages": 1
}
```

**Error Responses**

| HTTP Code         | Description                |
| ----------------- | -------------------------- |
| `400 Bad Request` | Missing user ID or room ID |
| `404 Not Found`   | User or room not found     |


# PayID Management

**PayIDs** are:

* A **globally unique identifier** linked to a user (e.g., `Alice(id)`)
* **Chain-agnostic**: works across EVM networks (Ethereum, Base, Polygon, Optimism, etc.)
* **Wallet-flexible**: mapped to one or more wallets, configured through routing logic
* **Human-friendly**: branded and easy to remember, like ENS or Lens handles
* **Programmable**: supports rules for incoming token/network and maps to destination logic

PayID enables seamless user-to-user and app-to-user payments without needing to deal with bridging, token conversions, or wallet compatibility on the sender’s side.

***

### Lifecycle of a PayID

| Phase                    | Description                                                                 |
| ------------------------ | --------------------------------------------------------------------------- |
| **Registration**         | Partner creates a user → claims a PayID via `/payid/claim`                  |
| **Validation & Pricing** | Pricing is determined by AI scoring (free if ≥13 characters)                |
| **Checkout**             | For premium PayIDs, a Loop checkout URL is provided                         |
| **Reservation**          | PayIDs are temporarily reserved until checkout expires or succeeds          |
| **Activation**           | After payment confirmation (via webhook), the PayID becomes active          |
| **Search & Resolve**     | PayIDs can be searched or resolved using `/payid/search` or metadata lookup |

***

***

### PayID Metadata

Each PayID is associated with:

* **userId**: backend identity
* **walletAddress**: default wallet (may be overwritten by routes)
* **email**: optional
* **twitterUsername**: optional
* **ENS/DID**: optional integrations (future)
* **Routes**: active payment logic mapped to incoming tx conditions


# Routes Engine

The Routes Engine is the programmable heart of Reveel PayID. It determines how incoming payments should be **processed, routed, and settled**, based on **user-defined rules**. This engine is what allows Reveel to go beyond simple address redirection and support intelligent, omnichain payment behavior.

***

### What is a Route?

A **route** is a logical set of conditions and outcomes configured by the user (or application) that defines:

* **What payment types are accepted** (by network, token, sender wallet)
* **Where those payments should end up** (target chain, token, wallet)
* **Whether a swap or bridge is needed** (optional, configurable)

Each user can define **multiple routes**, allowing fine-grained control over how different types of incoming payments are handled.

***

### Why It Matters

Without routing, a PayID would just be a static alias for a wallet. With the Routes Engine, Reveel unlocks:

* **Network abstraction**: sender doesn’t need to know recipient’s chain
* **Token normalization**: receive USDC even if sender sends USDT
* **Smart fallback logic**: default wallets for unknown senders or tokens
* **Enterprise-style flexibility**: tailor rules by partner, product, use case

It brings Web2-style conditional logic into the programmable payment space.

***

### Routing Rules: How They Work

Each route contains **match conditions** and **output instructions**.

#### Match Conditions (Inputs)

These define **when** a route should activate:

* `incomingToken`: Which tokens should trigger this route
* `incomingNetwork`: Which chains the payment may come from
* `incomingWallets`: (Optional) Which sender wallets this route applies to

#### Output Instructions

These define **what to do** with the matched funds:

* `swapToken`: Which token the user prefers to receive (optional)
* `swapNetwork`: Which chain to settle the funds on (optional)
* `outgoingWallet`: Final destination wallet

***

### Deterministic vs. Flexible Logic

Reveel allows routes to be either:

* **Strictly deterministic**: routes trigger only when all match conditions are met
* **Fallback-friendly**: if no exact match, default route can apply

This makes the system powerful enough for:

* Basic personal use (receive USDC on Base always)
* Complex app flows (route payments from `App A` to Chain A, `App B` to Chain B)

***

### Multi-Route Architecture

Users can have **multiple active routes**, and the engine evaluates them in order of **specificity and priority**. This allows:

* **Granular override**: route payments from a specific sender differently
* **General rules**: apply a catch-all fallback route for everything else

Each route is **stateless**, meaning the logic is evaluated per transaction, not stored across sessions.

***

### Design Considerations

The Routes Engine is designed to be:

| Feature              | Benefit                                                 |
| -------------------- | ------------------------------------------------------- |
| Stateless evaluation | Easier caching, fewer bugs, no cross-transaction memory |
| Conflict-checked     | Users can’t create overlapping or ambiguous routes      |
| Composable           | Works with future liquidity and swap modules            |
| Chain-agnostic       | Built to support new EVM chains and token standards     |
| User-scoped          | Routes are isolated per user to prevent collisions      |

***

### Future Plans:

* **Time-based logic** (route payments differently on weekdays vs weekends)
* **Geofenced rules** (based on sender location metadata)
* **Token splitting** (e.g. split $100: $80 to wallet A, $20 to wallet B)


# RLOL (Coming Soon)

The **Reveel Liquidity Orchestration Layer** (RLOL) is a forthcoming infrastructure component designed to supercharge cross-chain stablecoin transactions. While still under active development, RLOL is being architected as a middleware intelligence layer that connects Reveel PayID to the fragmented world of bridges, AMMs, and chain liquidity — turning complex, error-prone transfers into seamless programmable flows.

***

### Why RLOL Matters

Today, cross-chain transactions are riddled with inefficiencies:

* Fragmented liquidity across multiple bridges
* Slow, multi-step manual user flows
* High failure rates, slippage, and gas volatility
* No real-time intelligence for route optimization

RLOL aims to **solve this** with a plug-and-play, intelligent liquidity backend that will power every PayID-based transfer on Reveel — abstracting away the hard parts of cross-chain movement and replacing them with:

* Dynamic route selection
* Cost optimization
* Predictive success scoring
* Seamless execution

***

### Key Design Principles

| Objective                | Target Outcome                                    |
| ------------------------ | ------------------------------------------------- |
| **Optimization**         | Reduce average settlement time by 5%, fees by 10% |
| **Reliability**          | >90% transaction success rate                     |
| **Scalability**          | Launch with 5 chains, scale to 15+ in 12 months   |
| **Liquidity Efficiency** | Maintain >85% active liquidity utilization        |
| **User Abstraction**     | Hide complexity from end-users and frontends      |

***

### Conceptual Architecture

RLOL will function as an **intelligent routing engine** between:

* **User intent** (e.g., "send 50 USDC to `@bob(id)`")
* **Available infrastructure** (bridges, DEXs, liquidity pools)
* **Execution logic** (wallets, chains, tokens, fallback handling)

It’s composed of several interoperable microservices:

1. **Liquidity Aggregator Engine**\
   Queries and maintains access to bridge liquidity across multiple sources.
2. **Route Optimization Service**\
   Uses graph theory, scoring models, and market data to determine best paths.
3. **Transaction Execution Engine**\
   Manages execution, confirmations, retries, and on-chain operations.
4. **Bridge Adapters**\
   Standardized modules for integrating protocols like Connext, Hop, LayerZero, etc.
5. **Market Data Service**\
   Feeds the optimizer with real-time pricing, slippage, and liquidity insights.
6. **State Monitoring & Recovery**\
   Ensures robust tracking, fallback, and audit trails across chains.

This is an evolving system, and documentation, SDKs, and monitoring tools will be shared as development progresses. Early partners will have access to:

* RLOL-based routing reports per transaction
* Cost/latency comparison with raw bridge usage
* Beta SDK modules for simulation and dry-run estimates


# AI Agent Frameworks

Reveel Pay(ID) API for AI Agent Frameworks

#### Summary

Enable AI Agents to transact across chains with a single identity using Pay(ID) — simplifying Agent-to-Agent and Human-to-Agent payments.

#### Who It's For

* Agent framework developers (e.g. ElizaOS, Virtuals, Olas, Fetch.ai, Aethir)
* AI agents interacting with users or other agents
* Cross-chain payment systems embedded in AI protocols

#### Problem

AI agents often operate across domains and applications — but managing multiple wallets, bridging assets, and sending payments across chains creates unnecessary friction in the agent stack, preventing agent to transact with other agents or humans on different networks.

#### How Pay(ID) Solves It

Pay(ID) allows each Agent to have its own omnichain payment identity, removing the need to manage multiple wallets or networks. Funds sent to an Agent's Pay(ID) are routed automatically to its preferred token and chain, allowing agents to transact with any other party while holding only 1 type of stablecoin.

#### Implementation Outline

* Integrate Reveel Pay(ID) API as a plug in/skill for the agent framework
* Let users empower each agents with a Pay(ID)
* Define Route rules for token/network preferences
* Agents can then use the Reveel API to resolve Pay(ID)s and trigger cross-chain payments

#### Outcome / Benefits

* Abstracted Agent-to-Agent payments
* Simplified multi-agent financial coordination
* Cleaner architecture for AI payment logic


# ElizaOS POC

A proof-of-concept plugin that integrates Reveel Pay(ID) directly into the ElizaOS agent framework, enabling agents to search, authenticate, manage routes, and view transaction history using Pay(ID).

#### Plugin

* [plugin-reveel-payid](https://github.com/r3vl/plugin-reveel-payid)
* [PoC Docs](https://r3vl.notion.site/PoC-Eliza-1eafbc1efb8f8030b55ff7fb9a1f9848)
* [README](https://r3vl.notion.site/README-1eafbc1efb8f804bb86dc03c30a4e4f2)
* [Implementation Guide](https://r3vl.notion.site/Implementation-Guide-1eafbc1efb8f8048bf80d6feca3fe2a4)
* [Technical Spec](https://r3vl.notion.site/Technical-Specification-1eafbc1efb8f8063b5d5e8fc72a25152)

#### What it enables

* Each ElizaOS agent can be assigned a Pay(ID) and transact across chains
* Pay(ID) resolution and cross-chain payment triggering via the Reveel API
* Email-based sign-in and session management within the agent runtime
* Full transaction history retrieval for the authenticated agent

#### Agent actions

<table data-view="cards"><thead><tr><th></th></tr></thead><tbody><tr><td><p><strong>SEARCH_PAYID</strong></p><p></p><p>Search and resolve Pay(ID) identities across the network</p></td></tr><tr><td><p><strong>SIGNIN_WITH_FB</strong></p><p></p><p>Authenticate the agent session via email </p></td></tr><tr><td><p><strong>OTPGET_USER_ROUTES</strong></p><p></p><p>Fetch token and network routing preferences for the current agent</p></td></tr><tr><td><p><strong>GET_USER_TX_HISTORY</strong></p><p></p><p>Retrieve full transaction history for the authenticated agent</p></td></tr></tbody></table>

#### Installation

```
npm install @r3vl/plugin-reveel-payid
```

#### Example usage

{% code overflow="wrap" %}

```
// In your ElizaOS agent character config
import { reveelPayIdPlugin } from '@r3vl/plugin-reveel-payid'; 

export const character = { 
name: "MyAgent",
plugins: [reveelPayIdPlugin],
// ... }
```

{% endcode %}

#### How it works

* Install the plugin as part of the ElizaOS agent configuration
* Set environment variables for Reveel API authentication
* Agents can then resolve Pay(ID)s and trigger cross-chain payments via natural language
* Route rules are defined per agent — specifying preferred token and network


# Openclaw Skill

The Reva Openclaw Skill gives any OpenClaw agent a wallet and a Pay(ID), enabling it to earn, pay, hire, and settle. Built on Privy wallet infrastructure and Reveel's routing layer.

* [openclaw.revapay.ai](https://openclaw.revapay.ai/)
* [openclaw-skill](https://github.com/r3vl/openclaw-skill)

#### Features

* Passwordless authentication — email-based OTP verification, no passwords required
* Pay(ID) name claiming — register a unique PayID name for the agent
* Send funds to other users via PayID, wallet address, or Twitter/X handle
* Multi-chain support — Ethereum, Base, BNB Chain, Polygon, Optimism
* Balance tracking across all supported networks
* Human-to-agent delegation — humans can grant agents permission to settle on their behalf

#### Installation

{% code overflow="wrap" %}

```
curl -sSL https://raw.githubusercontent.com/r3vl/openclaw-skill/main/install.sh | bash
```

{% endcode %}

Installs to `~/.openclaw/skills/reva` and sets up all scripts automatically.

#### Example interactions

<table data-view="cards"><thead><tr><th></th></tr></thead><tbody><tr><td><p><strong>Send funds</strong></p><p></p><p>"Send 0.01 USDT on BNB to @alice" → agent routes and executes the transfer, returning a transaction link</p></td></tr><tr><td><p><strong>Claim a Pay(ID) name</strong></p><p></p><p>"I want to claim a PayID name" → "redd47" → agent claims the name and confirms</p></td></tr><tr><td><p><strong>Check balance</strong></p><p></p><p>"What's my balance?" → agent returns balances across all connected chains and tokens</p></td></tr></tbody></table>

#### Pricing

* 3 gas-free transactions per month included
* Standard transaction fee: 0.25% (min $0.05)
* Cross-chain / cross-stablecoin routing: 3 bps (0.03%)

#### Infrastructure

* Wallet layer — Privy embedded wallet infrastructure
* Identity layer — Universal Pay(ID) by Reveel
* Liquidity — cross-network routing and stablecoin conversion
* Social identity — connects wallets to X handles, Telegram, WhatsApp, Discord


# DIDs (Decentralized Identifiers)

Reveel Pay(ID) API for DIDs

#### Summary

Turn any DID into a payment-ready identity with Pay(ID) — making it a universal, chain-agnostic stablecoin receiver.

#### Who It's For

* DID providers (e.g. ENS, Lens, MocaID)
* Custom application-level identity frameworks
* Any protocol that uses DIDs as user identities

#### Problem

DIDs lack built-in payment logic. While they resolve to addresses, they don’t support cross-chain routing, stablecoin settlement, or programmable preferences.

#### How Pay(ID) Solves It

Reveel enables DIDs to link to a Pay(ID), turning them into omnichain payment endpoints. Developers can recognize a DID, resolve the underlying Pay(ID), and trigger stablecoin payments that follow the user’s routing preferences.

#### Implementation Outline

* Link existing DID (e.g. ENS name) to a Pay(ID)
* Define Routes behind the Pay(ID)
* Integrate DID recognition + Reveel API in the app

#### Outcome / Benefits

* DIDs become payment-enabled identities
* Cross-app, cross-chain usability for user IDs
* Reduced cognitive load for users


# Embedded Wallets

Reveel Pay(ID) API for Embedded Wallets

#### Summary

Integrate Pay(ID) directly into embedded wallets to enable seamless cross-chain stablecoin transfers within the wallet UI.

#### Who It's For

* Embedded wallet providers
* Consumer or app-native wallets
* Developers building wallet SDKs for games or apps

#### &#x20;Problem

Users must bridge assets or manually switch networks to send funds — creating friction, loss of funds, or dropped transactions.

#### How Pay(ID) Solves It

By linking the embedded wallet to a user's Pay(ID), all cross-chain routing and settlement is handled via Reveel’s API. Users can send any stablecoin to any recipient without leaving the wallet interface.

#### Implementation Outline

* Register a Pay(ID) for each wallet user
* Set the embedded wallet as the primary settlement wallet
* Integrate Pay(ID) resolution + send flow via Reveel API

#### Outcome / Benefits

* Simplified UX = higher conversion and retention
* Embedded wallet becomes the user’s default stablecoin wallet
* Increases TVL and user activity


# Portal POC

A proof-of-concept integration combining Portal's embedded wallet infrastructure with Reveel Pay(ID), enabling applications to give their users a single omnichain payment identity.

#### What it demonstrates

* Spin up a non-custodial Portal wallet for any user inside your app
* Attach a Pay(ID) to that wallet as a universal payment identity
* Accept any stablecoin from any supported chain — routed automatically to the user's preferred token and network
* No bridging or manual swaps required from the user's perspective

#### Who it's for

* Consumer app developers already using or evaluating Portal for wallet infrastructure
* Products that want to add stablecoin payment flows without exposing chain complexity to users
* Teams building wallet-gated features who need a simple payment identity layer

#### How it works

<table data-view="cards"><thead><tr><th></th></tr></thead><tbody><tr><td><p><strong>1. Portal wallet creation</strong></p><p></p><p>User signs up in the app — Portal generates an MPC-based non-custodial wallet. No seed phrase required on the user side.</p></td></tr><tr><td><p><strong>2. Pay(ID) attachment</strong></p><p></p><p>The Reveel API links a Pay(ID) to the Portal wallet address. Route rules define which token and chain the user wants to receive on.</p></td></tr><tr><td><p><strong>3. Omnichain receive</strong></p><p></p><p>Anyone can send funds to the user's Pay(ID) from any supported network. Reveel routes the payment to the Portal wallet automatically.</p></td></tr></tbody></table>

#### Outcome / benefits

* Embedded, non-custodial wallets with no UX complexity
* Single Pay(ID) identifier works across all supported chains
* Users hold only their preferred stablecoin — routing is fully abstracted
* Easy integration path for teams already using Portal SDK


# Custodial Accounts

Reveel Pay(ID) API for Custodial Solution Providers

#### Summary

Enable custodial platforms to offer users Pay(ID)-based receipt of stablecoins — with automatic settlement into a secure, managed account.

#### Who It's For

* Centralized exchanges
* Custody solutions
* Fiat on/off-ramps and cross-border platforms

#### Problem

Customers often require holding a single, secure stablecoin asset (e.g. RLUSD, PYUSD...), limiting the ability to receive or send other stablecoins. Furthermore, Centralized exchange users often send funds to the wrong network or token, creating failed transfers, stuck assets, or expensive customer support issues.

#### How Pay(ID) Solves It

Reveel allows custodial accounts to register a Pay(ID) and configure Routes that settle incoming funds correctly to their token of choice. This allows quicker & simpler transactions with custodians that might transact with a different token. Customers can just send funds to the recipient Pay(ID), and the Reveel Liquidity Layer ensures correct asset delivery.

#### Implementation Outline

* Assign a Pay(ID) to each custody user
* Configure default Routes per account
* Integrate Reveel API into custodial dashboard or backend

#### Outcome / Benefits

* Universal “receive-anything” payment address
* Fewer support tickets and lost funds
* Boosted trust, security, and UX for users


# Dapps (Decentralized Aplications)

Reveel Pay(ID) API for Dapps

#### Summary

Enable native omnichain payment flows within any dapp by integrating Pay(ID) — unlocking seamless payments across networks and assets.

#### Who It's For

* DeFi platforms
* Social, gaming, and messaging dapps
* Creator economy apps & NFT marketplaces

#### Problem

Dapps are often limited by the chain they’re deployed on. Cross-chain transfers or deposits typically require bridges, wrappers, or manual steps — degrading UX and limiting adoption.

#### How Pay(ID) Solves It

Dapps can allow users to send/receive payments using Pay(ID) — which handles cross-chain resolution, routing, and final delivery automatically. This allows dapps to support universal stablecoin payments without complex infrastructure.

#### Implementation Outline

* Embed Pay(ID) registration in user onboarding
* Use Reveel API to resolve incoming/outgoing Pay(IDs)
* Route stablecoin transfers based on user Routes

#### Outcome / Benefits

* Enables universal P2P payments natively
* Reduces drop-off during complex payment flows
* Simplify payouts & let users define thier payout currency
* Improves cross-chain liquidity and interoperability


# Admin Dashboard

COMING SOON


# Fees

COMING SOON


# Supported Networks

Pay(ID) is currently live on:

* Ethereum - ChainID: 1&#x20;
* Base - ChainID: 8453&#x20;
* Optimism - ChainID: 10&#x20;
* Polygon - ChainID: 137&#x20;
* BNB Chain - ChainID: 56&#x20;

Coming Soon

* Arbitrum One - ChainID: 42161&#x20;
* Avalanche - ChainID: 43114&#x20;
* Celo - ChainID: 42220&#x20;
* Gnosis - ChainID: 100&#x20;
* Linea - ChainID: 59144&#x20;
* Mantle - ChainID: 5000&#x20;
* Starknet - ChainID: *N/A*
* zkSync Era - ChainID: 324
* Solana - ChainID: Non-EVM
* Ton - ChainID: Non-EVM
* Tron - ChainID: Non-EVM


