Tutorial · 1 hour

Build a Copy-Trading SaaSin 1 Hour.

From zero to your first signed webhook event hitting your endpoint — using CopyBridge as the copy-trading backend behind your product.

Step 1 of 5

Get Integrator Access

Visit the developers page and click "Get Integrator Access". You'll go through Whop checkout (per-seat billing) — when complete, our webhook auto-provisions a parent provider for you and emails your X-Integrator-Key credential.

What you receive in your inbox:

  • Your X-Integrator-Key (shown ONCE — store it securely)
  • A quick-start curl example
  • Link to the API reference + this tutorial
Step 2 of 5

Create Your First Child Provider

Each of your customers becomes a "child provider" in CopyBridge. Provision them via API — they never need to visit copybridge.io. Start with is_sandbox: true so you can test without real broker execution.

curl -X POST https://api.copybridge.io/api/v1/integrator/providers \
  -H "X-Integrator-Key: ${INTEGRATOR_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Trader Joe",
    "email": "[email protected]",
    "is_sandbox": true
  }'

Response (201 Created):

{
  "provider": {
    "id": "uuid-of-trader-joe",
    "name": "Trader Joe",
    "is_sandbox": true,
    "parent_provider_id": "your-integrator-id"
  },
  "master_api_key": "uuid-master-key-shown-once",
  "jwt_token": "eyJ..."
}

The master_api_key + jwt_token are returned ONCE. Save them in your own database — you'll use them to interact with this child provider on your customer's behalf.

Step 3 of 5

Receive Outbound Webhooks

When the child provider's trades fire (or when followers are added/removed), CopyBridge POSTs a Standard-Webhooks-signed event to YOUR endpoint. Verify the signature, then route the event in your own system.

Node (Express):

import { createHmac } from 'node:crypto';

function verifyCopyBridge(rawBody, headers, secret) {
  const id  = headers['webhook-id'];
  const ts  = headers['webhook-timestamp'];
  const sig = (headers['webhook-signature'] || '').replace(/^v1,/, '');
  const key = Buffer.from(secret.slice(6), 'base64'); // strip 'whsec_'
  const expected = createHmac('sha256', key)
    .update(`${id}.${ts}.${rawBody}`)
    .digest('base64');
  // Constant-time: a plain === leaks timing, and the Python example on this
  // same page already uses hmac.compare_digest. timingSafeEqual throws on a
  // length mismatch, so check that first.
  const a = Buffer.from(sig), b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Python (Flask):

import base64, hashlib, hmac

def verify_copybridge(raw_body: bytes, headers: dict, secret: str) -> bool:
    eid = headers.get('webhook-id', '')
    ts  = headers.get('webhook-timestamp', '')
    sig = headers.get('webhook-signature', '').replace('v1,', '')
    key = base64.b64decode(secret[len('whsec_'):])
    msg = f'{eid}.{ts}.{raw_body.decode("utf-8")}'.encode('utf-8')
    expected = base64.b64encode(hmac.new(key, msg, hashlib.sha256).digest()).decode('ascii')
    return hmac.compare_digest(sig, expected)
Step 4 of 5

Test with Sandbox Mode

The child provider you just created has is_sandbox: true — meaning trades flow through the system end-to-end but copier EAs SKIP placing real broker orders. Outbound webhooks carry an extra sandbox: true field so you can filter or route them differently in your code.

What you can verify in sandbox:

  • API key creation, follower provisioning, key rotation
  • Outbound webhook signing + delivery + replay
  • Your end-to-end event processing pipeline
  • Trade lifecycle UI (trade.opened, trade.closed events arrive normally)

What does NOT happen in sandbox: real broker orders. The copier EA logs [SANDBOX] Skipping OrderSend instead of calling OrderSend().

Step 5 of 5

Going Live

When your integration is rock-solid in sandbox, toggle the child provider to live with a single API call. Note: CopyBridge refuses (HTTP 422) to enable sandbox mode if any attached follower's copier EA is below MIN_COPIER_VERSION — preventing the catastrophic case where an old EA processes a sandbox trade as real money.

curl -X PATCH https://api.copybridge.io/api/v1/integrator/providers/<child-id> \
  -H "X-Integrator-Key: ${INTEGRATOR_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"is_sandbox": false}'

You're integration-ready.

That's the whole flow. Full API reference + code samples below.