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

# Migrating from V1 to B2B API

> Complete guide to migrate from Rise V1 API to the new B2B API

Welcome to the Rise B2B API! This guide will help you migrate from the V1 API to our new, more powerful B2B API. The B2B API introduces significant improvements in security, functionality, and developer experience.

<Note>
  **SDK Recommended**: For the best developer experience with the B2B API, install the Rise SDK: `npm install @riseworks/riseworks-sdk` (or `yarn add @riseworks/riseworks-sdk` / `pnpm add @riseworks/riseworks-sdk`)
</Note>

<Note>
  **Helpful skill**: If you use Claude-style coding skills, add the migration skill with `npx @riseworks/riseworks-sdk add-skills rise-v1-migration`.
</Note>

<CardGroup cols={2}>
  <Card title="Enhanced Security" icon="shield">
    SIWE authentication replaces X-Auth-Token for better security
  </Card>

  <Card title="Better Performance" icon="bolt">
    Optimized endpoints with improved response times
  </Card>

  <Card title="Web3 Native" icon="globe">
    Built for blockchain with EIP-712 typed data signing
  </Card>

  <Card title="Improved Data" icon="chart-bar">
    Enhanced response formats with better error handling
  </Card>
</CardGroup>

## Key Changes Overview

### Authentication Changes

* **V1**: Used SIWE authentication with `/v1/api/siwe` endpoints
* **B2B**: Uses **Sign-In with Ethereum (SIWE)** with `/v2/auth/siwe` endpoints
* **JWT Tokens**: Still used but obtained through updated SIWE flow

### Endpoint Structure

* **V1**: Used `/v1/` prefix with various endpoint patterns
* **B2B**: Uses `/v2/` prefix with consistent REST patterns
* **Base URL**: Updated to use the new B2B API URLs - see [Environments](/environments) for API URLs

### Data Formats

* **V1**: Mixed response formats and error structures
* **B2B**: Consistent `{ success: boolean, data: any }` response format
* **Error Handling**: Standardized HTTP status codes with detailed error messages

## Endpoint Migration Table

### Authentication Endpoints

| V1 Endpoint         | B2B Endpoint           |
| ------------------- | ---------------------- |
| `GET /v1/api/siwe`  | `GET /v2/auth/siwe`    |
| `POST /v1/api/siwe` | `POST /v2/auth/verify` |

### Team Management

| V1 Endpoint                                   | B2B Endpoint                                               |
| --------------------------------------------- | ---------------------------------------------------------- |
| `GET /v1/teams`                               | `GET /v2/user/teams`                                       |
| `GET /v1/teams/{teamId}/talent`               | `GET /v2/teams/{team_nanoid}/users`                        |
| `GET /v1/teams/{teamId}/talent/{talentId}`    | `GET /v2/teams/{team_nanoid}/member/{user_nanoid}/summary` |
| `DELETE /v1/teams/{teamId}/talent/{talentId}` | `DELETE /v2/teams/{team_nanoid}/member/{user_nanoid}`      |

### Payment Processing

| V1 Endpoint                           | B2B Endpoint                             |
| ------------------------------------- | ---------------------------------------- |
| `POST /v1/payments/pay`               | `POST /v2/payments` + `PUT /v2/payments` |
| `PUT /v1/payments/pay`                | `POST /v2/payments` + `PUT /v2/payments` |
| `POST /v1/payments/batch-pay`         | `POST /v2/payments` + `PUT /v2/payments` |
| `PUT /v1/payments/batch-pay`          | `POST /v2/payments` + `PUT /v2/payments` |
| `POST /v1/payments/batch-pay/intents` | `POST /v2/payments` + `PUT /v2/payments` |
| `GET /v1/payments/`                   | `GET /v2/payments`                       |

### Balance Management

| V1 Endpoint                        | B2B Endpoint                      |
| ---------------------------------- | --------------------------------- |
| `GET /v1/riseid/{rise_id}/balance` | `GET /v2/balance?nanoid={nanoid}` |

### Invites Management

| V1 Endpoint                                 | B2B Endpoint                                           |
| ------------------------------------------- | ------------------------------------------------------ |
| `GET /v1/invites/`                          | `GET /v2/invites`                                      |
| `POST /v1/invites/` (employees/contractors) | `POST /v2/invites`                                     |
| `POST /v1/invites/` (managers)              | `POST /v2/invites/manager` + `PUT /v2/invites/manager` |
| `POST /v1/invites/warmed`                   | `POST /v2/invites`                                     |

## New B2B API Endpoints (Not in V1)

The B2B API introduces several new endpoints that weren't available in V1:

### Team Management (Enhanced)

* `GET /v2/teams/{team_nanoid}/settings` - Get team settings
* `PUT /v2/teams/{team_nanoid}/settings` - Update team settings
* `GET /v2/teams/{team_nanoid}` - Get team by nanoid
* `DELETE /v2/teams/{team_nanoid}` - Delete team by nanoid
* `PUT /v2/teams/{team_nanoid}` - Update team by nanoid
* `POST /v2/teams` - Create a team
* `GET /v2/teams/{team_nanoid}/member/{user_nanoid}/settings` - Get member settings
* `PUT /v2/teams/{team_nanoid}/member/{user_nanoid}/settings` - Update member settings

## Authentication Migration

### B2B Authentication (New)

**Using the Rise SDK (Recommended):**

```javascript theme={null}
const { RiseApiClient } = require('@riseworks/riseworks-sdk');

// Initialize SDK with Rise ID and private key
const client = new RiseApiClient({
  environment: 'prod',
  riseIdAuth: {
    riseId: process.env.RISE_ID,
    privateKey: process.env.PRIVATE_KEY
  }
});

// SDK automatically handles SIWE authentication and JWT management
const user = await client.me.get();
console.log('Authenticated as:', user.data.name);
```

**Alternative: Manual Authentication (Advanced):**

```javascript theme={null}
// Manual SIWE authentication flow (for advanced use cases)
class RiseAuth {
  constructor(baseUrl) {
    this.baseUrl = baseUrl;
  }

  async authenticate(walletAddress, privateKey, riseId) {
    // Step 1: Get SIWE message
    const siweResponse = await fetch(
      `${this.baseUrl}/v2/auth/siwe?wallet=${walletAddress}&riseid=${riseId}`
    );
    const { siwe } = siweResponse.data.data;

    // Step 2: Sign with wallet
    const wallet = new ethers.Wallet(privateKey);
    const signature = await wallet.signMessage(siwe);

    // Extract nonce from SIWE message
    const nonceMatch = siwe.match(/Nonce: (.+)/);
    const nonce = nonceMatch ? nonceMatch[1] : '';

    // Step 3: Verify and get JWT
    const verifyResponse = await fetch(`${this.baseUrl}/v2/auth/verify`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ message: siwe, sig: signature, nonce })
    });

    const { jwt } = verifyResponse.data.data;
    return jwt;
  }
}

// Use JWT in requests (same as V1)
const apiResponse = await fetch(`${this.baseUrl}/v2/teams`, {
  headers: { 'Authorization': `Bearer ${jwt}` }
});
```

## Data Format Changes

### Response Format

**B2B Response:**

```json theme={null}
{
  "success": true,
  "data": {
    "teams": [
      {
        "nanoid": "te-abc123def456",
        "name": "Engineering Team",
        "created_at": "2024-01-01T00:00:00Z"
      }
    ]
  }
}
```

### Error Format

**B2B Error:**

```json theme={null}
{
  "success": false,
  "data": "Team te-abc123def456 not found"
}
```

## ID System Changes

### V1: Mixed ID System

* Teams: `123`, `456`, `789` (numeric IDs)
* Users: `talentId` (numeric IDs)
* RiseID: `rise_id` (string format)

### B2B: Nanoid System

* Teams: `te-abc123def456`
* Users: `us-ghi789jkl012`
* Companies: `co-def456ghi789`
* Payments: `pa-pay123def456`

## Migration Checklist

### Phase 1: Preparation

* [ ] **Review new authentication flow** - Update SIWE authentication paths
* [ ] **Update base URL** - Change to new B2B API URLs (see [Environments](/environments))
* [ ] **Update endpoint paths** - Change from `/v1/` to `/v2/`
* [ ] **Test authentication** - Verify updated SIWE flow works

### Phase 2: Core Migration

* [ ] **Update team endpoints** - Replace numeric IDs with nanoids
* [ ] **Update user endpoints** - Replace numeric IDs with nanoids
* [ ] **Update balance endpoints** - Use new query parameter format
* [ ] **Update response handling** - Handle new `{ success, data }` format

### Phase 3: Advanced Features

* [ ] **Implement EIP-712 signing** - For payments and team management
* [ ] **Update error handling** - Handle new error format
* [ ] **Test all endpoints** - Verify functionality works as expected
* [ ] **Update documentation** - Update internal API documentation

## Code Migration Examples

### Team Member Retrieval

**V1 Code:**

```javascript theme={null}
const getTeamMembers = async (teamId) => {
  const response = await fetch(`${this.baseUrl}/v1/teams/${teamId}/talent`, {
    headers: { 'Authorization': `Bearer ${jwt}` }
  });

  const members = await response.json();
  return members; // Returns array of members
};
```

**B2B Code (Using SDK):**

```javascript theme={null}
const { RiseApiClient } = require('@riseworks/riseworks-sdk');

const client = new RiseApiClient({
  environment: 'prod',
  riseIdAuth: {
    riseId: process.env.RISE_ID,
    privateKey: process.env.PRIVATE_KEY
  }
});

const getTeamMembers = async (teamNanoid) => {
  const response = await client.teams.getUsers({
    team_nanoid: teamNanoid
  });
  
  return response.data.users; // Returns array of users
};
```

**B2B Code (Manual HTTP):**

```javascript theme={null}
const getTeamMembers = async (teamNanoid) => {
  const response = await fetch(`${this.baseUrl}/v2/teams/${teamNanoid}/users`, {
    headers: { 'Authorization': `Bearer ${jwt}` }
  });

  const result = await response.json();
  return result.data.users; // Returns array of users
};
```

### Payment Processing

**V1 Code:**

```javascript theme={null}
const payV1 = async (teamId, recipients, token) => {
  const response = await fetch(`${this.baseUrl}/v1/payments/pay`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      team_id: teamId,
      recipients: recipients.map(r => ({
        user_id: r.userId,
        amount: r.amount,
        currency: r.currency,
        description: r.description
      }))
    })
  });
  return await response.json();
};
```

**B2B Code (Using SDK - Automatic):**

```javascript theme={null}
const { RiseApiClient } = require('@riseworks/riseworks-sdk');

const client = new RiseApiClient({
  environment: 'prod',
  riseIdAuth: {
    riseId: process.env.RISE_ID,
    privateKey: process.env.PRIVATE_KEY  // Required for automatic signing
  }
});

const payB2B = async (teamNanoid, recipients) => {
  // SDK handles the entire payment flow automatically
  const payment = await client.payments.sendPayment({
    from: teamNanoid,
    to: recipients,
    pay_now: true, // true = pay immediately, false = intent (pay later)
    network: 'arbitrum'
  });
  
  return payment.data;
};

// Usage example
const recipients = [
  {
    to: 'us-jRxg2LRL54DJ',
    amount_cents: 300,
    currency_symbol: 'USD',
    invoice_description: 'Papa Sent you',
  },
  {
    to: 'us-d6JHBF2kuZjE',
    amount_cents: 700,
    currency_symbol: 'USD',
    invoice_description: 'Papa Sent you',
  },
];

const payment = await payB2B('te-bXy7gjb_Iga-', recipients);
console.log('Payment executed:', payment);
```

**B2B Code (Using SDK - Manual):**

```javascript theme={null}
const { RiseApiClient } = require('@riseworks/riseworks-sdk');

const client = new RiseApiClient({
  environment: 'prod',
  jwtToken: process.env.JWT_TOKEN  // JWT token is sufficient for manual flow
});

const payB2BManual = async (teamNanoid, recipients, walletAddress, privateKey) => {
  // Step 1: Create payment draft
  const createResponse = await client.payments.getPaymentTypedData({
    from: teamNanoid,
    to: recipients,
    pay_now: true,
    network: 'arbitrum'
  });

  const { typed_data } = createResponse.data;
  console.log('Payment draft created:', typed_data);

  // Step 2: Sign typed data
  const { ethers } = require('ethers');
  const wallet = new ethers.Wallet(privateKey);
  const signature = await wallet.signTypedData(
    typed_data.domain,
    typed_data.types,
    typed_data.typed_data
  );

  // Step 3: Execute payment
  const executeResponse = await client.payments.executePaymentWithSignedData({
    signer: walletAddress,
    from: teamNanoid,
    to: recipients,
    pay_now: true,
    typed_data: typed_data.typed_data,
    signature: signature
  });

  console.log('Payment executed:', executeResponse.data);
  return executeResponse.data;
};
```

**B2B Code (Manual HTTP):**

```javascript theme={null}
import { ethers } from 'ethers';

async function createPayment(teamNanoid, recipients, walletAddress, privateKey, payNow = true) {
  // Step 1: Create payment draft
  const createResponse = await fetch(`${this.baseUrl}/v2/payments`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${jwt}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      from: teamNanoid,
      to: recipients,
      pay_now: payNow, // true = pay immediately, false = intent (pay later)
      network: 'arbitrum'
    })
  });

  if (!createResponse.ok) {
    const errorText = await createResponse.text();
    throw new Error(`Failed to create payment draft: ${createResponse.status} - ${errorText}`);
  }

  const { data: typedData } = await createResponse.json();
  console.log('Payment draft created:', typedData);

  // Step 2: Sign typed data
  const wallet = new ethers.Wallet(privateKey);
  const signature = await wallet.signTypedData(
    typedData.domain,
    typedData.types,
    typedData.typed_data
  );

  // Step 3: Execute payment
  const executeResponse = await fetch(`${this.baseUrl}/v2/payments`, {
    method: 'PUT',
    headers: {
      'Authorization': `Bearer ${jwt}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      signer: walletAddress,
      from: teamNanoid,
      to: recipients,
      pay_now: payNow,
      typed_data: typedData.typed_data,
      signature: signature
    })
  });

  const response = await executeResponse.json();
  console.log('Payment executed:', response.data);
  return response.data;
}

// Usage example
const to = [
  {
    to: 'us-jRxg2LRL54DJ',
    amount_cents: 300,
    currency_symbol: 'USD',
    invoice_description: 'Papa Sent you',
  },
  {
    to: 'us-d6JHBF2kuZjE',
    amount_cents: 700,
    currency_symbol: 'USD',
    invoice_description: 'Papa Sent you',
  },
];

const payment = await createPayment(
  'te-bXy7gjb_Iga-',
  to,
  '<WALLET_ADDRESS>',
  '<WALLET_PRIVATE_KEY>',
  true // true = pay immediately, false = pay intent (pay later)
);
```

<Note>
  Use `pay_now: true` to execute payments immediately, or `pay_now: false` to create a payment intent for later execution.
</Note>

### Balance Retrieval

**B2B Code (Using SDK):**

```javascript theme={null}
const { RiseApiClient } = require('@riseworks/riseworks-sdk');

const client = new RiseApiClient({
  environment: 'prod',
  riseIdAuth: {
    riseId: process.env.RISE_ID,
    privateKey: process.env.PRIVATE_KEY
  }
});

const getBalance = async (nanoid) => {
  const response = await client.entityBalance.get({
    nanoid: nanoid
  });
  
  return response.data; // Returns balance with account address and currency breakdown
};
```

**B2B Code (Manual HTTP):**

```javascript theme={null}
const getBalance = async (nanoid) => {
  const response = await fetch(`${this.baseUrl}/v2/balance?nanoid=${nanoid}`, {
    headers: { 'Authorization': `Bearer ${jwt}` }
  });

  const result = await response.json();
  return result.data; // Returns balance with account address and currency breakdown
};
```

## Common Migration Issues

### Issue 1: Authentication Errors

**Problem:** Getting 401 errors after migration
**Solution:**

* Update SIWE endpoint paths from `/v1/api/siwe` to `/v2/auth/siwe` and `/v2/auth/verify`
* Check that JWT tokens are included as `Authorization: Bearer <jwt>` headers
* Verify JWT hasn't expired (24-hour lifetime)

### Issue 2: ID Format Errors

**Problem:** Getting 404 errors for resources that should exist
**Solution:**

* Replace numeric IDs with nanoids
* Update all endpoint URLs to use nanoid format
* Check that you're using the correct nanoid type (team, user, company)

### Issue 3: Response Format Errors

**Problem:** Code expecting old response format
**Solution:**

* Update response handling to use `response.data.data` instead of direct properties
* Handle the new `{ success, data }` wrapper format
* Update error handling to use `response.data` for error messages

### Issue 4: Missing EIP-712 Signing

**Problem:** Getting errors about missing signatures
**Solution:**

* Implement EIP-712 typed data signing for operations that require it
* Use the two-step process (create + execute) for payments and team management
* Ensure wallet is connected and has proper permissions

## Support During Migration

<CardGroup cols={2}>
  <Card title="Documentation" icon="book" href="/authentication">
    Complete B2B API documentation
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference">
    Interactive API reference
  </Card>

  <Card title="Support Email" icon="envelope" href="mailto:Hello@Riseworks.io">
    Get migration assistance
  </Card>

  <Card title="Status Page" icon="chart-line" href="https://status.rise.works">
    Check API status
  </Card>
</CardGroup>

<Note>
  **Need Help?** Our support team is available to help with your migration. Contact us at [Hello@Riseworks.io](mailto:Hello@Riseworks.io) for personalized assistance.
</Note>

<Warning>
  **Important**: The V1 API will be deprecated in the future. We recommend completing your migration as soon as possible to ensure continued access to Rise services.
</Warning>
