Off-Exchange Settlement: Connect to Partners
Create a connection to a partner platform to trade assets custodied at BitGo. See the Guide.
-
You create a connection to a partner platform so you can trade assets custodied at BitGo Bank & Trust on their platform. You sign the connection request with your Go Account (OFC wallet) key and send it with a connection token that the partner uses to identify you. You can connect with multiple partners and have multiple connections to the same partner.
The cURL flow has three steps: build the request payload, sign it via BitGo Express, then submit the signed connection request to the BitGo API. The JavaScript SDK flow handles signing internally in a single step.
Prerequisites: Obtain your Go Account (OFC wallet) ID and passphrase, the partner's UUID from the partner platform, and a running BitGo Express instance (cURL only).
// 1. Build Payload
export PARTNER_ID="<YOUR_PARTNER_ID>"
export LABEL="<YOUR_CONNECTION_NAME>"
export NONCE="<YOUR_NONCE>"
export CONNECTION_TOKEN="<YOUR_CONNECTION_TOKEN>"
# Payload is the request body stringified without payload/signature.
# Example shape (use your real values; nonce and connectionToken must match step 3):
export PAYLOAD='{"partnerId":"<YOUR_PARTNER_ID>","name":"<YOUR_CONNECTION_NAME>","nonce":"<YOUR_NONCE>","connectionKey":{"schema":"token","connectionToken":"<YOUR_CONNECTION_TOKEN>"}}'
// 2. Sign Payload
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export WALLET_ID="<YOUR_GO_ACCOUNT_WALLET_ID>"
export WALLET_PASSPHRASE="<YOUR_GO_ACCOUNT_PASSPHRASE>"
curl -X POST \
http://$BITGO_EXPRESS_HOST/api/v2/ofc/signPayload \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"walletId": "'"$WALLET_ID"'",
"walletPassphrase": "'"$WALLET_PASSPHRASE"'",
"payload": "'"$PAYLOAD"'"
}'
// 3. Create Client Connection
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export SIGNATURE="<SIGNATURE_FROM_SIGN_PAYLOAD_STEP>"
curl -X POST \
https://app.bitgo-test.com/api/network/v1/enterprises/$ENTERPRISE_ID/clients/connections \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"partnerId": "'"$PARTNER_ID"'",
"name": "'"$LABEL"'",
"nonce": "'"$NONCE"'",
"payload": "'"$PAYLOAD"'",
"signature": "'"$SIGNATURE"'",
"connectionKey": {
"schema": "token",
"connectionToken": "'"$CONNECTION_TOKEN"'"
}
}'
// 1. Create Client Connection
import { BitGoAPI } from '@bitgo/sdk-api';
import { coins } from '@bitgo/sdk-core';
import { randomUUID } from 'crypto';
import * as dotenv from 'dotenv';
dotenv.config();
const {
ACCESS_TOKEN,
ENTERPRISE_ID,
PARTNER_ID, // e.g. nifty-exchange: 4327da90-151b-40a9-813f-dd248e8ca5af
GO_ACCOUNT_ID, // ofc wallet id
WALLET_PASSPHRASE, // Go Account passphrase
CONNECTION_TOKEN, // optional; for Nifty, any random UUID works
} = process.env;
const bitgo = new BitGoAPI({
accessToken: ACCESS_TOKEN,
env: 'test', // Use 'prod' for the production environment
customRootURI: 'https://app.bitgo-test.com',
});
bitgo.register('ofc', coins.Ofc.createInstance);
async function createClientConnection() {
if (!ENTERPRISE_ID || !PARTNER_ID || !GO_ACCOUNT_ID || !WALLET_PASSPHRASE) {
console.error('Error: Missing required environment variables.');
return;
}
try {
// Body fields only — do NOT include payload/signature here
const baseReq = {
partnerId: PARTNER_ID,
name: 'My New API Connection',
nonce: randomUUID(),
connectionKey: {
schema: 'token',
// For Nifty / BITGO_MOCK_EXCHANGE, a random UUID is fine
connectionToken: CONNECTION_TOKEN || randomUUID(),
},
};
// Payload = stringified request body (less payload + signature)
const payload = JSON.stringify(baseReq);
// Sign with Go Account key
const wallet = await bitgo.coin('ofc').wallets().get({ id: GO_ACCOUNT_ID });
const tradingAccount = wallet.toTradingAccount();
const signature = await tradingAccount.signPayload({
payload,
walletPassphrase: WALLET_PASSPHRASE,
});
const connectionParams = {
...baseReq,
payload,
signature,
};
console.log('Sending signed request to create connection...');
const connection = await tradingAccount.toNetwork().createConnection(connectionParams);
console.log('Connection created successfully!');
console.dir(connection, { depth: null });
} catch (error) {
console.error('Failed to create connection:', error);
}
}
createClientConnection();
// 1. Create Client Connection Response
{
"connection": {
"active": true,
"clientId": "a2c8b149-621d-58ee-b490-9b1e6fdbca91",
"initialized": true,
"name": "My New API Connection",
"partnersConnectionId": "3ff9457f-c22c-4149-969c-7d709e2b04c3",
"partnersClientId": "83ea620f-ebd2-46c3-92f7-2c0737d6890d",
"partnerId": "4327da90-151b-40a9-813f-dd248e8ca5af",
"networkAccountId": "03185f11-81e8-4dd7-ad29-9f53bec0ad65",
"proof": "eyJzaWduYXR1cmVGb3JtYXQiOiJiaXAzMiIsInBheWxvYWQiOiJ7fSIsInNpZ25hdHVyZSI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIsInB1YmxpY0tleSI6InhwdWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifQ==",
"nonce": "842f2bc9-f4ae-425c-a70c-68f5afed0732",
"id": "50d2aadf-a7e7-4e5b-9dba-52626cbd6f75",
"createdAt": "2026-08-06T20:01:44.231Z",
"updatedAt": "2026-08-06T20:01:44.265Z"
}
}
// 3. Create Client Connection Response
{
"connection": {
"active": true,
"clientId": "a2c8b149-621d-58ee-b490-9b1e6fdbca91",
"initialized": true,
"name": "My New API Connection",
"partnersConnectionId": "3ff9457f-c22c-4149-969c-7d709e2b04c3",
"partnersClientId": "83ea620f-ebd2-46c3-92f7-2c0737d6890d",
"partnerId": "4327da90-151b-40a9-813f-dd248e8ca5af",
"networkAccountId": "03185f11-81e8-4dd7-ad29-9f53bec0ad65",
"proof": "eyJzaWduYXR1cmVGb3JtYXQiOiJiaXAzMiIsInBheWxvYWQiOiJ7fSIsInNpZ25hdHVyZSI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIsInB1YmxpY0tleSI6InhwdWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifQ==",
"nonce": "842f2bc9-f4ae-425c-a70c-68f5afed0732",
"id": "50d2aadf-a7e7-4e5b-9dba-52626cbd6f75",
"createdAt": "2026-08-06T20:01:44.231Z",
"updatedAt": "2026-08-06T20:01:44.265Z"
}
}