> ## 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.

# V1 to V2 ID Mapping

> Translate the V1 IDs and RiseIDs you have stored into V2 nanoids, RiseIDs, RiseAccounts and pay handlers

A V1 integration stores V1 IDs (numeric company, team and user IDs) and V1 RiseIDs. The V2 API works with nanoids (`co-…`, `te-…`, `us-…`), V2 RiseIDs and RiseAccounts. The mapping endpoint gives you all of them side by side in one call, so you can translate your stored identifiers before switching to V2.

It returns your company, its teams, and every manager and payee, each with:

* **V1 identifiers**: `v1_id` and `v1_riseid`
* **V2 identifiers**: `nanoid`, `riseid` and `rise_account`
* **Pay handlers**: each payee's pay handler, per team

## How it works

<Steps>
  <Step title="Authenticate">
    Use your usual token: a V1 token on `/v1/mapping`, or a V2 SIWE JWT on either endpoint. See [Authentication](/authentication/authentication).
  </Step>

  <Step title="Identify the company">
    Pass any company identifier you already hold in `company_id`, or leave it out to use the company you own.
  </Step>

  <Step title="Rise checks your access">
    The company owner and organization roles see the whole company. Team managers see only their own teams.
  </Step>

  <Step title="Store the mapping">
    Index the response by `v1_id` or `v1_riseid` and save the V2 nanoids next to your V1 records.
  </Step>
</Steps>

## Endpoints

| Endpoint | Use it when | Response envelope |
| - | - | - |
| `GET /v1/mapping` | You are still calling the V1 API | `{ "data": {...}, "pagination"? }` |
| `GET /v2/mapping` | You have moved to the V2 API | `{ "success": true, "data": {...} }` |

In the [Rise SDK](/sdk/installation) these are `client.mapping.get(params)` (V2) and `client.v1Legacy.getMapping(params)` (V1). Both take the same optional `company_id`, `page`, `offset` and `count`.

Both endpoints accept the same parameters, apply the same access rules, and return the same `data`. See [Environments](/concepts/environments) for the base URL of each environment.

<Warning>
  Send a plain `GET` with **no request body**. A GET that carries a body (for example, a leftover raw body in Postman) is rejected before it reaches the API, with an intermittent `400` or `502`. In Postman, set **Body** to **none**.
</Warning>

## Request

| Query parameter | Required | Description |
| - | - | - |
| `company_id` | No | The company to map, in any supported form (see below). Defaults to the company you own. |
| `company_nanoid` | No | `GET /v2/mapping` only. Same as `company_id` with a `co-` nanoid; kept for compatibility. Send one or the other: both together returns `400`. |
| `page` | No | 1-indexed page of users. Turns pagination on. |
| `offset` | No | Row offset into users; an alternative to `page`. Turns pagination on. |
| `count` | No | Page size, 1–500. Defaults to 100. |

### Accepted `company_id` values

Pass whichever identifier you already have. Both endpoints resolve it the same way.

| You pass | Example | Resolves to |
| - | - | - |
| V1 company ID | `10393` | The V2 company |
| V1 team ID (a V1 company that became a V2 team) | `20001` | The company that owns that team |
| Company nanoid | `co-def456ghi789` | That company |
| Team nanoid | `te-abc123def456` | The team's company |
| V1 or V2 RiseID of a company or team | `0x3333…3333` | The owning company |
| RiseAccount of a company or team | `0x2222…2222` | The owning company |
| Nothing | | The company you own |

If you leave out `company_id`:

* If you own exactly one company, that company is used.
* If you own none or more than one, you get `400`.

## Examples

<CodeGroup>
  ```javascript SDK (V2) theme={null}
  const { data } = await client.mapping.get({ company_id: 'co-def456ghi789' });
  ```

  ```javascript SDK (V1) theme={null}
  const { data } = await client.v1Legacy.getMapping({ company_id: '10393' });
  ```

  ```bash V1 theme={null}
  curl 'https://b2b-api.riseworks.io/v1/mapping?company_id=10393' \
    -H 'Authorization: Bearer <token>'
  ```

  ```bash V2 theme={null}
  curl 'https://integrations-api.riseworks.io/v2/mapping?company_id=co-def456ghi789' \
    -H 'Authorization: Bearer <token>'
  ```

  ```bash V2 (paginated) theme={null}
  curl 'https://integrations-api.riseworks.io/v2/mapping?company_id=co-def456ghi789&page=1&count=100' \
    -H 'Authorization: Bearer <token>'
  ```
</CodeGroup>

## Response

```json theme={null}
{
  "success": true,
  "data": {
    "scope": "company",
    "company": {
      "nanoid": "co-def456ghi789",
      "riseid": "0x1111111111111111111111111111111111111111",
      "rise_account": "0x2222222222222222222222222222222222222222",
      "v1_id": 10393,
      "v1_riseid": "0x3333333333333333333333333333333333333333",
      "name": "Acme Inc"
    },
    "teams": [
      {
        "nanoid": "te-abc123def456",
        "riseid": "0x4444444444444444444444444444444444444444",
        "rise_account": "0x5555555555555555555555555555555555555555",
        "v1_id": 10393,
        "v1_riseid": "0x3333333333333333333333333333333333333333",
        "name": "Acme Inc"
      },
      {
        "nanoid": "te-xyz987uvw654",
        "riseid": "0xaaaa000000000000000000000000000000000001",
        "rise_account": "0xaaaa000000000000000000000000000000000002",
        "v1_id": null,
        "v1_riseid": null,
        "name": "Created in V2"
      }
    ],
    "users": [
      {
        "nanoid": "us-ghi789jkl012",
        "riseid": "0x6666666666666666666666666666666666666666",
        "rise_account": "0x7777777777777777777777777777777777777777",
        "v1_id": 456,
        "v1_riseid": "0x8888888888888888888888888888888888888888",
        "email": "payee@example.com",
        "company_roles": [],
        "teams": [
          {
            "team_nanoid": "te-abc123def456",
            "role": "contractor",
            "type": "payee",
            "pay_handler": "0x9999999999999999999999999999999999999999"
          }
        ]
      },
      {
        "nanoid": "us-mno345pqr678",
        "riseid": "0xcccc000000000000000000000000000000000001",
        "rise_account": "0xcccc000000000000000000000000000000000002",
        "v1_id": 789,
        "v1_riseid": null,
        "email": "manager@example.com",
        "company_roles": ["org_admin"],
        "teams": [
          {
            "team_nanoid": "te-abc123def456",
            "role": "team_admin",
            "type": "manager",
            "pay_handler": null
          }
        ]
      }
    ]
  }
}
```

The V2 response puts `pagination` inside `data`. `GET /v1/mapping` returns the same `data` without the `success` field, and puts `pagination` at the top level next to `data`.

### Fields

| Field | Description |
| - | - |
| `scope` | `company` or `teams`. See [Access and scope](#access-and-scope). |
| `nanoid` | V2 identifier (`co-`, `te-` or `us-`). Use it in V2 API calls. |
| `riseid` | V2 RiseID: the entity's on-chain identity contract. Use it wherever the V2 API asks for a RiseID. |
| `rise_account` | V2 RiseAccount: the contract that holds the entity's funds. A different address from the RiseID. |
| `v1_id` | V1 numeric ID. `null` for anything created in V2. |
| `v1_riseid` | V1 RiseID. `null` for anything created in V2, or when it was not carried over during migration (usually managers). |
| `company_roles` | The user's company-level roles: `company` (owner), `org_admin`, `org_finance_admin`, `org_hr_admin`, `org_viewer`, `org_delegate_admin`, `org_non_delegate_admin`. |
| `teams[].role` | The user's role on that team. |
| `teams[].type` | `payee` for `contractor`, `aor_contractor` and `team_employee`; `manager` for every other team role. |
| `teams[].pay_handler` | The payee's active pay handler for that team. Always `null` for managers, and `null` for a payee with no active handler. |

<Note>
  Your main V1 company became both the V2 company and its default team, so both carry the same `v1_id` (`10393` above). Every other V1 company became a separate V2 team. Teams created in V2 have `null` V1 fields.
</Note>

## Access and scope

What you get depends on your own active, direct role on the company. Roles through an accounting firm and terminated memberships do not count.

| Your role | What you get | `scope` |
| - | - | - |
| Company owner, `org_admin`, `org_finance_admin`, `org_hr_admin` or `org_viewer` | Every team and member, including company roles | `company` |
| Team manager only (`team_admin`, `team_finance_admin`, `team_viewer`, `team_payment_initiator`, `team_invite_initiator`) | Only the teams you manage and their members. `company_roles` is empty and `company.rise_account` is `null`. | `teams` |
| Payee only, terminated, accounting-firm access, or no relationship | `404 Company not found` | |

Team scope is the usual case for V1 integrators, whose V1 "company" is a V2 team.

<Note>
  A company you cannot access returns the same `404 Company not found` as a company that does not exist. The endpoint never reveals whether another company exists or anything about it.
</Note>

## Pagination

| Request | Result |
| - | - |
| No `page` or `offset` | Every user, with no `pagination` field |
| `page=2&count=100` | Users 101–200 |
| `offset=250&count=50` | Users 251–300 |

Pagination applies to `users` only, ordered by user nanoid. `company` and `teams` are always returned in full. The `pagination` object contains `page`, `count`, `offset`, `has_more`, `next_page` and `next_offset`.

## Errors

| Status | When | V1 body | V2 body |
| - | - | - | - |
| `400` | `company_id` is not a supported form, it is missing and you own none or several companies, or `company_id` and `company_nanoid` are both sent (V2) | `{"error":"Bad Request","message":{"type":"invalid_parameters","errors":{"company_id":["…"]}}}` | `{"success":false,"data":"…"}` |
| `401` | Missing or invalid token | | `{"success":false,"data":"Authentication required…"}` |
| `403` | Your company is not enabled for B2B API access | `{"success":false,"data":"Company is not enabled for B2B API access","error_code":"B2B_ACCESS_DENIED"}` | Same as V1 |
| `404` | The company does not exist, or you have no access to it | `{"error":"Not Found","message":"Company not found"}` | `{"success":false,"data":"Company not found"}` |

## Edge cases

| Situation | What happens |
| - | - |
| The method is not `GET` (for example `PUT`) | `404`. The endpoint exists only as `GET`. |
| A V1 token for an account that was never migrated | The request is handled by the original V1 API, which has no mapping endpoint. There are no V2 IDs to map yet. |
| A RiseID in different letter case | Matched anyway; RiseIDs are compared case-insensitively. |
| A user who manages one team and is paid in another | One user entry with two `teams[]` items: a `manager` item and a `payee` item with its pay handler. |
| Terminated teams and memberships | Not included. |

## Using the mapping in a migration

Fetch the mapping once (page through it for large companies), then build lookups from your stored V1 values to V2 identifiers. With the [Rise SDK](/sdk/installation):

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

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

// company_id accepts your V1 company ID, a nanoid, a RiseID or a RiseAccount
const { data } = await client.mapping.get({ company_id: '10393' });

const teamByV1Id = new Map(
  data.teams.filter((t) => t.v1_id !== null).map((t) => [t.v1_id, t.nanoid]),
);
const userByV1Id = new Map(
  data.users.filter((u) => u.v1_id !== null).map((u) => [u.v1_id, u.nanoid]),
);

// V1 talent 456 on V1 company 10393 → V2 IDs for /v2/teams/{team_nanoid}/users
const teamNanoid = teamByV1Id.get(10393);
const userNanoid = userByV1Id.get(456);
```

## Related

<CardGroup cols={2}>
  <Card title="Migrating from V1" icon="arrow-right-arrow-left" href="/guides/migrating-from-v1">
    Endpoint-by-endpoint guide to moving to the V2 API
  </Card>

  <Card title="Entity nanoids" icon="fingerprint" href="/concepts/entity-nanoid">
    How V2 identifiers are structured
  </Card>

  <Card title="V2 API reference" icon="code" href="/api-reference/b2b-mapping/map-v1-ids-to-v2-ids">
    GET /v2/mapping
  </Card>

  <Card title="V1 API reference" icon="clock-rotate-left" href="/api-reference-v1/mapping/map-v1-ids-to-v2-ids-v1-legacy">
    GET /v1/mapping
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.