# Set Up Organization

Source: https://developers.bitgo.com/docs/crypto-as-a-service-organization

## Overview

An organization is a grouping mechanism that's a level above an enterprise. Organizations can contain many enterprises, but enterprises can belong to only 1 organization. Within your organization, you can set up a child enterprise for each of your users, enabling them to independently take certain actions such as initiating trades and withdrawals. However, you can also collectively manage certain things for child enterprises, including segregating assets across Go Accounts.

Organizations require organization admins, who are people you select from among your enterprise admins. Organization admins can access child enterprise details, such as balances and addresses. Organization admins are also responsible for managing organization-wide policies that affect all child enterprises. Unlike the service user, organization admins can't initiate transactions, such as trades and withdrawals.

> 📘 **Note**
> 
> Organization admins and the service user are two separate roles. Although it's likely that the organization admin has access to the service user, these are still distinct roles in Crypto-as-a-Service.

Similar to how your enterprise has an enterprise name and enterprise ID, your organization has an organization name and organization ID. The enterprise name and the organization name are the same. However, enterprise IDs and organization IDs always differ.

## Prerequisites

[Get Started](/docs/get-started-intro)

## 1. Create Access Token

You must create an access token to authenticate your requests to the BitGo API. This will be required for operations like programmatically adding users to an enterprise, setting up child enterprises, submitting their KYC verification, creating, and trading with their Go Accounts.

You can create short-lived access tokens and keep rotating them or long-lived access tokens with timed rotations. BitGo recommends using long-lived access tokens. The following example uses relevant scopes for a long-lived access token.

> 📘 **Note**
>
> You must use a short-lived access token to programmatically generate a long-lived access token. Alternatively, you can generate long-lived access tokens in the BitGo web app.

>Endpoints:
>* [Create access token ](/reference/v2accesstokenadd) (long lived)
>* [Login](/reference/userlogin) (short lived)

```shell cURL (long lived)
export ACCESS_TOKEN="<YOUR_SHORT_LIVED_ACCESS_TOKEN>"
export DURATION="<DURATION>"
export LABEL="<DESIRED_TOKEN_NAME>"
export IP_RESTRICT="<IP_ADDRESS_OR_CIDR_BLOCK>"

curl -X POST \
  https://app.bitgo-test.com/api/v2/user/accesstoken \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
  "scope": [
    "pending_approval_update", # Update pending approvals
    "profile", # View your BitGo profile
    "settlement_network_read", # Enables partners engage in allocations with clients
    "settlement_network_write", # Enables partners engage in allocations with clients
    "trade_trade", # Make trades
    "trade_view", # View trades
    "wallet_approve_all", # Approve transactions for all wallets
    "wallet_create", # Create wallets
    "wallet_edit_all", # Edit comments for all wallets
    "wallet_freeze_all", # Freeze all wallets
    "wallet_manage_all", # Manage settings for all wallets (required to use webhooks)
    "enterprise_view_all", # View child enterprises
    "enterprise_manage_all", # Manage users and settings for child enterprises
    "wallet_spend_all", # Send transactions from a wallet
    "wallet_view_all" # View transactions for all wallets
  ],
  "duration": "'"$DURATION"'",
  "label": "'"$LABEL"'",
  "ipRestrict": ["'"$IP_RESTRICT"'"]
}'
```
```shell cURL (short lived)
export EMAIL="<YOUR_LOGIN_EMAIL>"
export PASSWORD="<YOUR_LOGIN_PASSPHRASE>" # BitGo recommends passing your hashed password that the SDK provides from the `preprocessAuthenticationParams` function

curl -X POST \
  "https://app.bitgo-test.com/api/v2/user/login" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "'"$EMAIL"'",
    "otp": "0000000", # testnet OTP is always 0000000
    "password": "'"$PASSWORD"'"
}'
```
```js JavaScript (long lived)
import { BitGoAPI } from '@bitgo/sdk-api';
const bitgo = new BitGoAPI({ env: 'test' });
const auth_res = await bitgo.authenticate({
  username: "user@example.com",
  password: process.env.PASS,
  otp: "0000000",
});
const access_token = await bitgo.addAccessToken({
  otp: "0000000",
  label: "Service user long lived access Token",
  "duration": 157788000,
  "ipRestrict": [], // required for access tokens in production. CIDR blocks must have prefix lengths between /24 and /32 for IPv4, and between /64 and /128 for IPv6.
  scope: [
    "pending_approval_update", // Update pending approvals
    "profile", // View your BitGo profile
    "settlement_network_read", // Enables partners engage in allocations with clients
    "settlement_network_write", // Enables partners engage in allocations with clients
    "trade_trade", // Make trades
    "trade_view", // View trades
    "wallet_approve_all", // Approve transactions for all wallets
    "wallet_create", // Create wallets
    "wallet_edit_all", // Edit comments for all wallets
    "wallet_freeze_all", // Freeze all wallets
    "wallet_manage_all", // Manage settings for all wallets (required to use webhooks)
    "enterprise_view_all", // View child enterprises
    "enterprise_manage_all", // Manage users and settings for child enterprises
    "wallet_spend_all", // Send transactions from a wallet
    "wallet_view_all", // View transactions for all wallets
    ]
});
console.log(access_token);
```
```js JavaScript (short lived)
bitgo.authenticate({ username: 'user@example.com', password: password, otp: '0000000' }).then(function (response) {
  var token = response.access_token;
  var user = response.user;
  // etc.
});
```

#### Step Result

```json JSON (long lived)
{
  "id": "68fbacf7cb97a5715c070799676efb54",
  "client": "bitgo",
  "user": "68928b8c66417fe09212fda389cc92c6",
  "scope": [
      "pending_approval_update",
      "profile",
      "settlement_network_read",
      "settlement_network_write",
      "trade_trade",
      "trade_view",
      "wallet_approve_all",
      "wallet_create",
      "wallet_edit_all",
      "wallet_freeze_all",
      "wallet_manage_all",
      "wallet_spend_all",
      "enterprise_view_all",
      "enterprise_manage_all",
      "wallet_view_all"
  ],
  "created": "2025-10-24T16:44:39.108Z",
  "expires": "2030-10-24T22:44:39.108Z",
  "ip": "142.122.155.155",
  "ipRestrict": [
      "127.0.0.0"
  ],
  "origin": "app.bitgo-test.com",
  "label": "Taseen-Test-CaaS-long-access-token",
  "isExtensible": false,
  "organizations": [
      "68928b9066417fe09212fe9965c88552"
  ],
  "oauth": {
      "oauthRequired": false
  },
  "token": "5c1e0147645d92ae774c2f35f823467fbfcaffea92bd420d2cbacab25686c782"
}
```
```json JSON (short lived)
{
  "token_type": "bearer",
  "access_token": "c9e4574dea9c706377907177d2861bf17e65476587cda449c08d81024aad8f5f",
  "expires_in": 86400,
  "expires_at": 1710016687,
  "scope": [
    "user_manage",
    "openid",
    "openid_enterprises",
    "profile",
    "wallet_create",
    "wallet_freeze_all",
    "wallet_manage_all",
    "wallet_approve_all",
    "wallet_spend_all",
    "wallet_edit_all",
    "wallet_view_all",
    "settlement_network_read",
    "settlement_network_write",
    "trade_view",
    "trade_trade",
    "portfolio_view",
    "pending_approval_update",
    "metamask_institutional",
    "crypto_compare",
    "third_party_user_lookup",
    "enterprise_view_all",
    "enterprise_manage_all"
  ],
  "user": {
    "id": "62ab90e06dfda30007974f0a52a12995",
    "username": "nakamoto@bitcoin.com",
    "enterprises": [
      {
        "id": "61fab88a336c18000813831c85a3f2fe",
        "permissions": ["admin"],
        "beneficialOwner": false
      },
      {
        "id": "62c5ae8174ac860007aff138a2d74df7",
        "permissions": ["admin"],
        "beneficialOwner": false
      },
      {
        "id": "640971cfba5a34e391cd52daaaffd4c6",
        "permissions": ["admin"],
        "beneficialOwner": false
      },
      {
        "id": "5ef51a6c7c74daa7004d4e23c62022b2",
        "permissions": ["admin"],
        "beneficialOwner": false
      }
    ],
    "organizations": [],
    "name": { "full": "Satoshi Nakamoto", "first": "Satoshi", "last": "Nakamoto" },
    "email": { "email": "nakamoto@bitcoin.com", "verified": true },
    "phone": { "phone": "", "verified": false },
    "country": "USA",
    "identity": {
      "kyc": {
        "failureCount": 0,
        "fullyRequired": false,
        "required": true,
        "available": true,
        "hasVideoID": false,
        "passport": { "required": false, "state": "unverified" },
        "isScreeningRequired": true,
        "data": {
          "state": "approved",
          "fields": {
            "country": "USA",
            "firstName": "Satoshi",
            "lastName": "Nakamoto",
            "dob": "19XX-XX-XX"
          }
        },
        "overallState": "approved",
        "documents": { "state": "unverified" },
        "residency": { "state": "unverified" }
      },
      "verified": false
    },
    "otpDevices": [
      {
        "id": "62ab917e4159d500079e5b836e41fba2",
        "createDate": "2022-06-16T20:24:30.000Z",
        "type": "totp",
        "label": "Google Authenticator",
        "verified": true,
        "lastValidatedDate": "2023-02-06T21:14:09.469Z",
        "scopes": []
      }
    ],
    "rateLimits": {},
    "disableReset2FA": false,
    "currency": { "currency": "USD", "bitcoinUnit": "BTC" },
    "timezone": "America/Los_Angeles",
    "isActive": true,
    "ecdhKeychain": "xpub661MyMwAqRbcG9rxFyVx56soHRSzi6kCD1GPwd838qDJ7piucKe8JYfBS4VVLChNHZytXUkWf8sQb5jjXC1abjdS968rJEDjJrGQu3qVsCP",
    "referrer": { "source": null, "campaign": null },
    "forceResetPassword": false,
    "allowedCoins": [],
    "agreements": {
      "termsOfUse": 1,
      "termsOfUseAcceptanceDate": "2022-06-16T20:24:33.159Z",
      "patriotAct": 0
    },
    "lastLogin": "2024-03-08T20:38:07.708Z",
    "featureFlags": [],
    "bitgoEmployee": false,
    "state": "California",
    "sourceVerificationRequiredForReadOnlyAccess": true
  }
}
```

## 2. Add Admins to Enterprises

Before you can add admins to your organization, you must first add them as users with `admin` permission to your enterprise. 

>Endpoint: [Add User to Enterprise](/reference/v2enterpriseuseradd)

```shell cURL
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"

curl -X POST \
  "https://app.bitgo-test.com/api/v2/enterprise/$ENTERPRISE_ID/user" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "permission": "admin",
    "usernames": [
        "user1@example.com",
        "user2@example.com",
        "user3@example.com"
    ]
}'
```

#### Step Result

You sent email invitations to join your enterprise with an admin role.

```json JSON
{
  "id": "65eb7a68d35b5e7856e94fcc1f7a48bb",
  "enterprise": "62c5ae8174ac860007aff138a2d74df7",
  "creator": "62ab90e06dfda30007974f0a52a12995",
  "createDate": "2024-03-08T20:51:52.447Z",
  "info": {
    "type": "updateEnterpriseRequest",
    "updateEnterpriseRequest": {
      "action": "add",
      "email": "user2@bitcoin.com",
      "permissions": "admin",
      "userId": "5f063f7e319d6800263aff885de41fa0"
    }
  },
  "approvers": [],
  "state": "pending",
  "scope": "enterprise",
  "userIds": [
    "5543247a32d9b1f4037cfd782fc4b06d",
    "621d08a634ad8a0007fcddffd7c429cc",
    "627ff9325a5c1b0007c05a40d15e1522",
    "62ab90e06dfda30007974f0a52a12995"
  ],
  "approvalsRequired": 1,
  "singleRunResults": [],
  "resolvers": [],
  "actions": [],
  "resolutionOrder": []
}
```

> 📘 **Note**
>
> Ensure you select a number of admins to be video approvers. BitGo requires video approval for withdrawals that exceed $250,000 USD.

## 3. Fetch Organization Details

BitGo uses your organization name and organization ID to link child enterprises together.

>Endpoint: [Get Enterprise](/reference/enterprisegetbyid)

```shell cURL
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"

curl -X GET \
  "http://$BITGO_EXPRESS_HOST/api/v2/enterprise/$ENTERPRISE_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

#### Step Result

The following abridged response highlights the organization details:

```json JSON
{
  "id": "62c5ae8174ac860007aff138a2d74df7", // your enterprise ID
  "name": "Prestige Worldwide", // your enterprise and organization name
  "type": "Other",
  "organizationId": "62c5ae8174ac860007aff1555ffb960d", // your organization ID
  "wallets": []
}
```

## 4. Add Organization Admins

Select enterprise admins that you want to make organization admins.

Currently, you cannot do this programmatically. You must contact support@bitgo.com and request that BitGo make specific enterprise admins organization admins.

#### Step Result

Your organization has admins that can create and manage child enterprises.

## 5. Configure Organization

Contact support@bitgo.com to configure your organization. BitGo Support works with you to configure your organization settings for your integration. BitGo uses these settings during child enterprise creation and you must configure them before moving forward.

#### Step Result

Your organization is now ready, you may move forward to creating child enterprises.

## Next Steps

[Set Up Child Enterprises](/docs/crypto-as-a-service-child-enterprises)

## See Also

* [API Reference: Add User to Enterprise](/reference/v2enterpriseuseradd)
* [API Reference: Create access token](/reference/v2accesstokenadd)
* [API Reference: Get Enterprise](/reference/enterprisegetbyid)
* [API Reference: Login](/reference/userlogin)
