# Create Crypto Address Source: https://developer.copper.co/api-reference/address-book/create-crypto-address /copper-open-api-public.json post /crypto-addresses Create a new crypto address in an organization's address book # Deactivate Crypto Address Source: https://developer.copper.co/api-reference/address-book/deactivate-crypto-address /copper-open-api-public.json delete /crypto-addresses/{cryptoAddressId} Deactivate a crypto address in an organization's address book # Get Crypto Address by ID Source: https://developer.copper.co/api-reference/address-book/get-crypto-address-by-id /copper-open-api-public.json get /crypto-addresses/{cryptoAddressId} Retrieve information about a crypto address in an organization's address book # Get Crypto Addresses Source: https://developer.copper.co/api-reference/address-book/get-crypto-addresses /copper-open-api-public.json get /crypto-addresses Retrieve information about crypto addresses in an organization's address book # Authentication Source: https://developer.copper.co/api-reference/authentication Authentication to the API is performed via the Authorization header with an API key. Each request requires an API key to authenticate the user and a signature to verify the request’s integrity, ensuring safe and authorized access to our API. To provide access to the API, all requests must contain the following headers: | Header | Description | | :- | :- | | `Authorization` | API key obtained on the Copper Platform | | `X-Signature` | Signature of your request | | `X-Timestamp` | Timestamp of your request in UNIX Timestamp format (in milliseconds) | Generated API keys have no expiration date. However, they will be disabled if they are not used during a 6-month period. Users manage the full lifecycle of their API keys, including creation and revocation, through the platform. For information on creating an API key, see [Create an API key](/api-reference/create-api-key). ### Generating a signature **1. Concatenate the following strings:** * Value of the `X-Timestamp` header * HTTP request method uppercase * Path of the requested endpoint including the `platform` prefix and all additional parameters (e.g., `/platform/orders?limit=1000`) * All fields of the request body (use an empty string if the request does not include a body) `"$timestamp${req.method.value.toUpperCase}${req.uri}${body.data.utf8}"` For example: `1730482675607POST/platform/orders{"orderType":"withdraw","amount":"1.0"}` **2. Sign the concatenated string with your API Secret using the HMAC SHA256 method.** **3. Encode the generated signature in hexadecimal format.** ```bash Bash theme={"system"} #!/bin/bash -ex API_KEY='ksgJrNOT1...i02V1hLfZs1I' SECRET='W02cN5UDsF...SJtTyjDtq5SN' TIMESTAMP="$(($(date +%s) * 1000))" METHOD="GET" URL_PATH="/platform/portfolios" BODY="" SIGNATURE="$(echo -n "${TIMESTAMP}${METHOD}${URL_PATH}${BODY}" | openssl dgst -sha256 -hmac ${SECRET})" curl -v "https://api.copper.co${URL_PATH}" \ -H "Authorization: ApiKey ${API_KEY}" \ -H "Content-Type: application/json" \ -H "X-Signature: ${SIGNATURE#*= }" \ -H "X-Timestamp: ${TIMESTAMP}" ``` ```python Python theme={"system"} import hashlib import hmac import requests import time ApiKey = 'ksgJrNOT1X...i02V1hLfZs1I' Secret = 'W02cN5UDsF...SJtTyjDtq5SN' timestamp = str(round(time.time() * 1000)) method = "GET" path = "/platform/portfolios" body = "" signature = hmac.new( key=bytes(Secret, 'utf-8'), msg=bytes(timestamp + method + path + body, 'utf-8'), digestmod=hashlib.sha256 ).hexdigest() print(signature) # example: 1b6064ca0d052d1a08d831c915ead54e6c5ff17237c845dab8b8c1cb8439a9c1 url = 'https://api.copper.co' + path resp = requests.get(url, headers={ 'Authorization': 'ApiKey ' + ApiKey, 'X-Signature': signature, 'X-Timestamp': timestamp }) ``` ```java Java theme={"system"} import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.HexFormat; import java.net.HttpURLConnection; import java.net.URL; import java.io.OutputStream; public class CopperApiExample { public static void main(String[] args) throws Exception { String apiKey = "ksgJrNOT1X...i02V1hLfZs1I"; String secret = "W02cN5UDsF...SJtTyjDtq5SN"; long timestamp = System.currentTimeMillis(); String method = "GET"; String path = "/platform/portfolios"; String body = ""; String message = timestamp + method + path + body; Mac sha256Hmac = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); sha256Hmac.init(secretKey); String signature = HexFormat.of().formatHex(sha256Hmac.doFinal(message.getBytes(StandardCharsets.UTF_8))); URL url = new URL("https://api.copper.co" + path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod(method); connection.setRequestProperty("Authorization", "ApiKey " + apiKey); connection.setRequestProperty("X-Signature", signature); connection.setRequestProperty("X-Timestamp", String.valueOf(timestamp)); connection.setRequestProperty("Content-Type", "application/json"); int responseCode = connection.getResponseCode(); System.out.println("Response Code: " + responseCode); } } ``` ```scala Scala theme={"system"} import javax.crypto.Mac import javax.crypto.spec.SecretKeySpec import java.nio.charset.StandardCharsets import java.util.HexFormat; import scalaj.http._ object CopperApiExample extends App { val apiKey = "ksgJrNOT1X...i02V1hLfZs1I" val secret = "W02cN5UDsF...SJtTyjDtq5SN" val timestamp = System.currentTimeMillis().toString val method = "GET" val path = "/platform/portfolios" val body = "" val message = timestamp + method + path + body val sha256Hmac = Mac.getInstance("HmacSHA256") val secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256") sha256Hmac.init(secretKey) val signature = HexFormat.of().formatHex(sha256Hmac.doFinal(message.getBytes(StandardCharsets.UTF_8))) val response = Http("https://api.copper.co" + path) .header("Authorization", "ApiKey " + apiKey) .header("X-Signature", signature) .header("X-Timestamp", timestamp) .asString println("Response Code: " + response.code) } ``` ```go Go theme={"system"} package main import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "fmt" "net/http" "strconv" "time" ) func main() { apiKey := "ksgJrNOT1X...i02V1hLfZs1I" secret := "W02cN5UDsF...SJtTyjDtq5SN" timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10) method := "GET" path := "/platform/portfolios" body := "" message := timestamp + method + path + body mac := hmac.New(sha256.New, []byte(secret)) mac.Write([]byte(message)) signature := hex.EncodeToString(mac.Sum(nil)) client := &http.Client{} req, _ := http.NewRequest(method, "https://api.copper.co"+path, nil) req.Header.Add("Authorization", "ApiKey "+apiKey) req.Header.Add("X-Signature", signature) req.Header.Add("X-Timestamp", timestamp) req.Header.Add("Content-Type", "application/json") resp, _ := client.Do(req) fmt.Println("Response Code:", resp.StatusCode) } ``` # Validate Address Source: https://developer.copper.co/api-reference/blockchain/validate-address /copper-open-api-public.json post /blockchain/validate-address # Get ClearLoop Action by ID Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-action-by-id /copper-open-api-public.json get /clearloop/actions/{actionId} # Get ClearLoop Actions Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-actions /copper-open-api-public.json get /clearloop/actions # Get ClearLoop Balances Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-balances /copper-open-api-public.json get /clearloop/balances # Get ClearLoop Currencies Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-currencies /copper-open-api-public.json get /clearloop/currencies # Get ClearLoop Exchange by ID Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-exchange-by-id /copper-open-api-public.json get /clearloop/exchanges/{exchangeId} # Get ClearLoop Exchanges Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-exchanges /copper-open-api-public.json get /clearloop/exchanges # Get ClearLoop Portfolio by Id Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-portfolio-by-id /copper-open-api-public.json get /clearloop/portfolios/{portfolioId} # Get ClearLoop Portfolios Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-portfolios /copper-open-api-public.json get /clearloop/portfolios # Get ClearLoop Settlement by ID Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-settlement-by-id /copper-open-api-public.json get /clearloop/settlements/{settlementId} # Get ClearLoop Settlements Source: https://developer.copper.co/api-reference/clearloop/get-clearloop-settlements /copper-open-api-public.json get /clearloop/settlements # Create an API key Source: https://developer.copper.co/api-reference/create-api-key To access the Copper API, you need to have an API key. To create an API key, go to the [Copper Platform UI](https://platform.copper.co/) and follow these steps: **1. Go to organisation settings** On your Copper dashboard, click your organisation's name in the top left of your screen, select **Organisation settings**, and then select **API Keys**. ![Organization Settings](https://mintcdn.com/copperco/8EIpazN_ergWo9kn/images/organization-settings.png?fit=max\&auto=format\&n=8EIpazN_ergWo9kn\&q=85\&s=fa7b207355df39a1c006299dd2271657) **2. Choose the owner, set permissions, and configure an IP allowlist** Determine if the API key should be associated with your personal account or a service user account. Optionally, you can restrict its access to specific IP addresses by setting IP addresses restrictions. ![New API Key Form](https://mintcdn.com/copperco/8EIpazN_ergWo9kn/images/new-api-key-form.png?fit=max\&auto=format\&n=8EIpazN_ergWo9kn\&q=85\&s=a97f4952df992f07d28a0c02632b80ad) **3. Save the API key and API secret** All done! Make sure to copy your API secret and store it in a safe place. You won’t be able to see it again. ![API Key Created](https://mintcdn.com/copperco/VjFckwcqW1OMkEwv/images/api-key-created.png?fit=max\&auto=format\&n=VjFckwcqW1OMkEwv\&q=85\&s=21d249247fc3aa79534fe5ed1ff02e27) **4. Use your API key** With your API key in hand, you can now access the Copper Platform API. # Currency Trading Fees for Amount Source: https://developer.copper.co/api-reference/currencies/currency-trading-fees-for-amount /copper-open-api-public.json get /currencies/{currency}-{mainCurrency}/trading-fees Calculates trading fees for a given amount and a currency pair # Get Currencies Source: https://developer.copper.co/api-reference/currencies/get-currencies /copper-open-api-public.json get /currencies # Get Currency Source: https://developer.copper.co/api-reference/currencies/get-currency /copper-open-api-public.json get /currencies/{currency}-{mainCurrency} # Activate Deposit Target Currency Source: https://developer.copper.co/api-reference/deposit-targets/activate-deposit-target-currency /copper-open-api-public.json patch /deposit-targets/{depositTargetId} Update deposit target # Create Deposit Target Source: https://developer.copper.co/api-reference/deposit-targets/create-deposit-target /copper-open-api-public.json post /deposit-targets Create a new deposit target # Get Deposit Targets Source: https://developer.copper.co/api-reference/deposit-targets/get-deposit-targets /copper-open-api-public.json get /deposit-targets Retrieve information about all deposit targets in an organization # Errors Source: https://developer.copper.co/api-reference/errors Copper Platform API returns machine-readable errors and human-readable messages. Here is what an error response looks like: ```json theme={"system"} { "error": "bad-request", "message": "Can't execute request" } ``` ### Common Error Codes | Code | Error | Details | | :- | :- | :- | | 400 | Bad Request | Validation errors: empty required fields, unsupported values | | 401 | Unauthorized | Invalid API Key | | 403 | Forbidden | Access to the requested resource is denied | | 404 | Not Found | The requested endpoint has not been found | | 409 | Conflict | Validation error or the request cannot be completed due to an internal issue | | 429 | Request Limit Exceeded | The request rate limit is exceeded. Request processing is temporarily blocked | | 500 | Internal Server | Problems with the Copper platform server | # Download Files Source: https://developer.copper.co/api-reference/files/download-files /copper-open-api-public.json get /files/{fileId} # Getting started Source: https://developer.copper.co/api-reference/getting-started The Copper platform is equipped with a powerful API to provide integration with your applications. This documentation describes the composition and usage of available API endpoints. > **[OpenAPI Endpoints](/api-reference/try-it-out#openapi-specification)** > > Download the OpenAPI specification > **[Postman Collection](/api-reference/try-it-out#postman-collection)** > > Download the Postman collection ## Base URL ```shell Production theme={"system"} Platform URL - https://platform.copper.co API Base URL - https://api.copper.co/platform ``` ```shell Staging/Demo theme={"system"} Platform URL - https://demo.copper.co API Base URL - https://api.stage.copper.co/platform ``` ```shell Testnet theme={"system"} Platform URL - https://testnet.copper.co API Base URL - https://api.testnet.copper.co/platform ``` ## Date and Time Format All date and time values in the Copper API are represented as `timestamps in milliseconds since the Unix epoch` (January 1, 1970, 00:00:00 UTC). ## Numeric Values Format All numeric values in the Copper API are returned as strings to prevent potential issues with floating-point precision. ## Response Codes The API returns standard HTTP response codes to indicate the success or failure of an API request. Here are a few examples: | Code | Description | | :- | :- | | `200` | The request was successful | | `400` | The request was invalid or cannot be served | | `401` | The request requires user authentication | | `403` | The server understood the request, but refuses to authorize it | | `404` | The requested resource could not be found | | `409` | Business logic error | | `429` | Too many requests | | `500` | The server encountered an unexpected condition which prevented it from fulfilling the request | # Execute exchange action Source: https://developer.copper.co/api-reference/hyperliquid/execute-exchange-action /copper-open-api-public.json post /exchange Execute Hyperliquid exchange action. Mimics https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint # Get agent wallets Source: https://developer.copper.co/api-reference/hyperliquid/get-agent-wallets /copper-open-api-public.json get /agent-wallets Get the active Hyperliquid agent (hot) wallets for a portfolio, or for every portfolio in an organization # Get allowed markets Source: https://developer.copper.co/api-reference/hyperliquid/get-allowed-markets /copper-open-api-public.json get /markets Get the list of allowed Hyperliquid markets # Accept Loan Source: https://developer.copper.co/api-reference/lending/accept-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{acceptLoanId} Accept a loan. This action can only be carried out by the borrower. # Accept Loan Interest Payment Source: https://developer.copper.co/api-reference/lending/accept-loan-interest-payment /copper-open-api-public.json patch /organizations/{organizationId}/loans/{acceptInterestLoanId} Accept the loan interest payment request. # Accept Loan Rebalance Source: https://developer.copper.co/api-reference/lending/accept-loan-rebalance /copper-open-api-public.json patch /organizations/{organizationId}/loans/{acceptRebalanceLoanId} Accept the loan rebalance request. Only a lender can carry out this action. # Accept Loan Repayment Source: https://developer.copper.co/api-reference/lending/accept-loan-repayment /copper-open-api-public.json patch /organizations/{organizationId}/loans/{acceptRepaymentLoanId} Accept the full or partial loan repayment request. Only requests that were initiated by the counterparty can be accepted. # Accept Loan Rerate Source: https://developer.copper.co/api-reference/lending/accept-loan-rerate /copper-open-api-public.json patch /organizations/{organizationId}/loans/{acceptRerateLoanId} Accept the loan interest rerate request. Only the borrower can carry out this action. # Accept Loan Term Extension Source: https://developer.copper.co/api-reference/lending/accept-loan-term-extension /copper-open-api-public.json patch /organizations/{organizationId}/loans/{acceptExtensionLoanId} Accept the loan term extension request. Only requests that were initiated by the counterparty can be accepted. # Accept Loan Top Up Source: https://developer.copper.co/api-reference/lending/accept-loan-top-up /copper-open-api-public.json patch /organizations/{organizationId}/loans/{acceptTopUpLoanId} Accept the loan top up request. Only a borrower can carry out this action. # Approve Loan Source: https://developer.copper.co/api-reference/lending/approve-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{approveLoanId} Approve a loan. This action can only be carried out by the lender if a loan is in awaiting-approval state. # Calculate Loan LTV Dry Run Source: https://developer.copper.co/api-reference/lending/calculate-loan-ltv-dry-run /copper-open-api-public.json patch /organizations/{organizationId}/loans Obtain the loan LTV or needed collateral amount for given loan parameters. # Cancel Loan Source: https://developer.copper.co/api-reference/lending/cancel-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{cancelLoanId} Cancel a loan that is awaiting acceptance. This action can be carried out by the lender or the borrower. # Cancel Loan Default Source: https://developer.copper.co/api-reference/lending/cancel-loan-default /copper-open-api-public.json patch /organizations/{organizationId}/loans/{cancelDefaultLoanId} Cancel a default request for loan. This action can only be carried out by the lender. # Cancel Loan Interest Payment Source: https://developer.copper.co/api-reference/lending/cancel-loan-interest-payment /copper-open-api-public.json patch /organizations/{organizationId}/loans/{cancelInterestLoanId} Cancel the loan interest payment request that is awaiting acceptance. This action can be carried out by the lender or the borrower. # Cancel Loan Rebalance Source: https://developer.copper.co/api-reference/lending/cancel-loan-rebalance /copper-open-api-public.json patch /organizations/{organizationId}/loans/{cancelRebalanceLoanId} Cancel the loan rebalance request that is awaiting acceptance. This action can be carried out by the lender or the borrower. # Cancel Loan Repayment Source: https://developer.copper.co/api-reference/lending/cancel-loan-repayment /copper-open-api-public.json patch /organizations/{organizationId}/loans/{cancelRepaymentLoanId} Cancel the full or partial loan repayment. This action can be carried out by the borrower or the lender. # Cancel Loan Rerate Source: https://developer.copper.co/api-reference/lending/cancel-loan-rerate /copper-open-api-public.json patch /organizations/{organizationId}/loans/{cancelRerateLoanId} Cancel the loan interest rerate request that is awaiting acceptance. This action can be carried out by the lender or the borrower. # Cancel Loan Term Extension Source: https://developer.copper.co/api-reference/lending/cancel-loan-term-extension /copper-open-api-public.json patch /organizations/{organizationId}/loans/{cancelExtensionLoanId} Cancel the loan term extension request. This action can be carried out by the borrower or the lender. # Cancel Loan Top Up Source: https://developer.copper.co/api-reference/lending/cancel-loan-top-up /copper-open-api-public.json patch /organizations/{organizationId}/loans/{cancelTopUpLoanId} Cancel the loan top up request that is awaiting acceptance. This action can be carried out by the lender or the borrower. # Confirm External Disbursement Source: https://developer.copper.co/api-reference/lending/confirm-external-disbursement /copper-open-api-public.json patch /organizations/{organizationId}/loans/{confirmDisbursementLoanId} Confirm the external disbursement of an off-platform managed loan. Only the lender can carry out this action. # Confirm External Interest Payment Source: https://developer.copper.co/api-reference/lending/confirm-external-interest-payment /copper-open-api-public.json patch /organizations/{organizationId}/loans/{confirmInterestLoanId} Confirm the external payment of interest. Only the lender can carry out this action. # Confirm External Repayment Source: https://developer.copper.co/api-reference/lending/confirm-external-repayment /copper-open-api-public.json patch /organizations/{organizationId}/loans/{confirmRepaymentLoanId} Confirm the external repayment of an off-platform managed loan. Only the lender can carry out this action. # Confirm External Top Up Source: https://developer.copper.co/api-reference/lending/confirm-external-top-up /copper-open-api-public.json patch /organizations/{organizationId}/loans/{confirmTopUpLoanId} Confirm the external top up of an off-platform managed loan. Only the lender can carry out this action. # Create Loan Source: https://developer.copper.co/api-reference/lending/create-loan /copper-open-api-public.json post /organizations/{organizationId}/loans Initiate loan creation. This action can only be carried out by the lender. # Default Loan Source: https://developer.copper.co/api-reference/lending/default-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{defaultLoanId} Default a loan that is in a defaultable state. This action can only be carried out by the lender. # Early Terminate Loan Source: https://developer.copper.co/api-reference/lending/early-terminate-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{earlyTerminationLoanId} Early terminate ClearLoop loans within the same portfolio. This action can only be initiated by the Agency Desk. # Estimate Loan Leverage Ratio Source: https://developer.copper.co/api-reference/lending/estimate-loan-leverage-ratio /copper-open-api-public.json patch /organizations/{organizationId}/loans/{estimateLeverageLoanId} Obtain an estimated loan leverage ratio after taking into account requested loan amount and/or collateral amount adjustments. # Estimate Loan LTV Source: https://developer.copper.co/api-reference/lending/estimate-loan-ltv /copper-open-api-public.json patch /organizations/{organizationId}/loans/{estimateLtvLoanId} Obtain an estimated loan LTV after taking into account requested loan amount and/or collateral amount adjustments. # Extend Loan Term Source: https://developer.copper.co/api-reference/lending/extend-loan-term /copper-open-api-public.json patch /organizations/{organizationId}/loans/{extendTermLoanId} Request loan term extension. Loan term extension can only be requested within five days of the loan reaching maturity. This request can be initiated by either the borrower or the lender. The resulting request needs to be accepted by the counterparty. # Get Loan by ID Source: https://developer.copper.co/api-reference/lending/get-loan-by-id /copper-open-api-public.json get /organizations/{organizationId}/loans/{loanId} Retrieve a loan by its ID # Get Loans Source: https://developer.copper.co/api-reference/lending/get-loans /copper-open-api-public.json get /organizations/{organizationId}/loans Retrieve loans # Pay Loan Interest Source: https://developer.copper.co/api-reference/lending/pay-loan-interest /copper-open-api-public.json patch /organizations/{organizationId}/loans/{payInterestLoanId} Create an interest payment request. # Rebalance Loan Source: https://developer.copper.co/api-reference/lending/rebalance-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{rebalanceLoanId} Create a loan rebalance request. This action can only be carried out by the borrower and must be accepted by the lender. # Reject Loan Source: https://developer.copper.co/api-reference/lending/reject-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{rejectLoanId} Reject a loan. This action can only be carried out by the lender if a loan is in awaiting-approval state. # Repay Loan Source: https://developer.copper.co/api-reference/lending/repay-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{repayLoanId} Request the partial or full repayment of a loan. This request can be initiated by either the borrower or the lender. The resulting request needs to be accepted by the counterparty. # Rerate Loan Source: https://developer.copper.co/api-reference/lending/rerate-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{rerateLoanId} Request a new loan interest rerate. The new interest rate must be stated in BPS. This action can only be carried out by the lender. # Secure Collateral Loan Source: https://developer.copper.co/api-reference/lending/secure-collateral-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{secureCollateralLoanId} Secure collateral for a loan. This action can only be carried out by the borrower and should be invoked for both initial and subsequent collateral top ups. # Top Up Loan Source: https://developer.copper.co/api-reference/lending/top-up-loan /copper-open-api-public.json patch /organizations/{organizationId}/loans/{topUpLoanId} Request a loan top up. This action can only be carried out by the lender and must be accepted by the borrower. # Get Counterparties Source: https://developer.copper.co/api-reference/network/get-counterparties /copper-open-api-public.json get /organizations/{organizationId}/counterparties Find participant of the Copper Network # Accept Order Source: https://developer.copper.co/api-reference/orders/accept-order /copper-open-api-public.json patch /orders/{acceptOtcOrderId} Accept counterparty settlement order # Approve (co-sign) Order Source: https://developer.copper.co/api-reference/orders/approve-co-sign-order /copper-open-api-public.json patch /orders/{coSignOrderId} # Cancel Order Source: https://developer.copper.co/api-reference/orders/cancel-order /copper-open-api-public.json patch /orders/{cancelOrderId} # Create Multiple Orders Source: https://developer.copper.co/api-reference/orders/create-multiple-orders /copper-open-api-public.json post /orders/ Bulk orders creation. If the execution of an order fails, it will not affect the execution of other orders. Failed orders will be returned in the response. The bulk size should be less than 50 orders. # Create Order Source: https://developer.copper.co/api-reference/orders/create-order /copper-open-api-public.json post /orders # Dry Run Order Source: https://developer.copper.co/api-reference/orders/dry-run-order /copper-open-api-public.json post /dry-run-orders # Get Order by ID Source: https://developer.copper.co/api-reference/orders/get-order-by-id /copper-open-api-public.json get /orders/{orderId} # Get Orders Source: https://developer.copper.co/api-reference/orders/get-orders /copper-open-api-public.json get /orders # Provide master password for Order Source: https://developer.copper.co/api-reference/orders/provide-master-password-for-order /copper-open-api-public.json patch /orders/{orderId} # Start Signing Source: https://developer.copper.co/api-reference/orders/start-signing /copper-open-api-public.json patch /orders/{startSigningOrderId} Start crypto signing for an order # Get Activities Source: https://developer.copper.co/api-reference/organizations/get-activities /copper-open-api-public.json get /organizations/{organizationId}/activities Retrieve information about all activities in the organization # Get Organization Members Source: https://developer.copper.co/api-reference/organizations/get-organization-members /copper-open-api-public.json get /organizations/{organizationId}/members Retrieve information about organization members # Get Organizations Source: https://developer.copper.co/api-reference/organizations/get-organizations /copper-open-api-public.json get /organizations Retrieve information about organizations # Archive Portfolio Source: https://developer.copper.co/api-reference/portfolios/archive-portfolio /copper-open-api-public.json delete /portfolios/{portfolioId} # Create Portfolio Source: https://developer.copper.co/api-reference/portfolios/create-portfolio /copper-open-api-public.json post /portfolios Create a new portfolio # Get Portfolios Source: https://developer.copper.co/api-reference/portfolios/get-portfolios /copper-open-api-public.json get /portfolios Retrieve your portfolios (in UI terms - accounts) # Retrieve Portfolio by ID Source: https://developer.copper.co/api-reference/portfolios/retrieve-portfolio-by-id /copper-open-api-public.json get /portfolios/{portfolioId} # Rate limits Source: https://developer.copper.co/api-reference/rate-limits Copper API limits the number of API requests. If the limit is exceeded, the request processing for the IP address or UserID is blocked for the specified lockout period and Copper API returns `429 - Too Many Requests` error. | Rate limit type | Limit | Lockout period | | :- | :- | :- | | Any HTTP requests | 30000 requests per 5 minutes for a single IP address | Until the number of requests in the last 5 minutes is less than 30000 | | Any HTTP requests | 1000 requests per 5 minutes for each User ID and Organization ID pair | 5 minutes | | Authentication errors (wrong API key or signature) | 30 failed attempts per hour for each unique API Key and IP address pair | 15 minutes | | Failed API requests (any business logic errors - bad request, missed required parameters, wrong amounts, currencies, etc) | 60 requests per 1 minute for a single User ID | 3 minutes | Some requests may have additional limitations, which are not disclosed. # Create Balance Report Source: https://developer.copper.co/api-reference/reports/create-balance-report /copper-open-api-public.json post /reports/wallets/wallets-snapshots # Create Lending Report Source: https://developer.copper.co/api-reference/reports/create-lending-report /copper-open-api-public.json post /reports/lending # Create Orders NET Report Source: https://developer.copper.co/api-reference/reports/create-orders-net-report /copper-open-api-public.json post /reports/orders/net # Create Position Statement Report Source: https://developer.copper.co/api-reference/reports/create-position-statement-report /copper-open-api-public.json post /reports/wallets/net-asset-values # Create Stake Orders Report Source: https://developer.copper.co/api-reference/reports/create-stake-orders-report /copper-open-api-public.json post /reports/stake/orders # Create Stake Rewards Report Source: https://developer.copper.co/api-reference/reports/create-stake-rewards-report /copper-open-api-public.json post /reports/stake/rewards # Service accounts Source: https://developer.copper.co/api-reference/service-accounts ## What is a service account? A **service account** is a non-personal account used to manage API keys for automated or shared operations. Unlike user accounts, service accounts are not tied to an individual's email address or login credentials. They are ideal for: * Operational continuity * Shared access across teams * Reducing risk when team members leave or change roles ### Service account best practices * Use service accounts for all automated or shared API integrations. * Create different service accounts, with their unique API keys, for each role on the platform. * Limit permissions to those necessary. * Rotate keys periodically and revoke unused ones. * Keep a record of who has access to each key. ### Service account versus user account | Feature | User Account | Service Account | | - | - | - | | Linked to a person | Yes (email and login) | No | | API key ownership | Individual user | Shared operational account | | Key deactivation risk | High (keys disabled if user is removed) | Low (keys remain active unless manually revoked) | | Creation permissions | Users (with approval) | Only Account Controllers | | Use case | Personal access | Team-wide or system-level integrations | ### Service account permissions and actions The following table lists some of the key service account permissions and actions. > [!NOTE] > > You can look up a complete list of permissions and actions, that are available to your organisation on the platform, > when adding, editing, or viewing service accounts, under **Settings > Service accounts**. | Permission | Actions | | - | - | | Approver | Approvers approve requests and actions initiated by platform users; for example, they can sign or cancel transactions. | | Trader | Traders move funds to other Copper accounts within the same organisation. They cannot make direct withdrawals to external addresses. | | Withdrawal Operator | Withdrawal Operators move funds to both internal accounts and external whitelisted addresses. | | Loan Manager | Loan Managers create, modify, and approve loans. | ## Create a service account > [!NOTE] > > Only Account Controllers can create service accounts. To create a service account, go to the [Copper Platform UI](https://platform.copper.co/) and follow these steps: **1. Add a new account** In the menu at the top of the screen, click **Settings**. Under **Organisation settings**, select **Service accounts** and click **Add new**. ![Add a new service account](https://mintcdn.com/copperco/o7UAXdiqVElIkwyY/images/service_account_add_new.png?fit=max\&auto=format\&n=o7UAXdiqVElIkwyY\&q=85\&s=17119fb710d0845d9ef2266ca24182bc) **2. Give the account a name** Give the new service account a name (for example, Finance Ops, Trading Bot) and click **Next**. **3. Begin granting permissions** To assign required permissions to the account, on the **Permissions** page, click **Grant permissions**. **4. Choose permissions** On the **Grant account permissions** page, select the accounts that the account is authorised to access and its permissions, for example, Trader, Loan Manager, Withdrawal Operator. Click **Save**. ![Grant account permissions](https://mintcdn.com/copperco/o7UAXdiqVElIkwyY/images/service_account_grant_permissions.png?fit=max\&auto=format\&n=o7UAXdiqVElIkwyY\&q=85\&s=80e3d18766053125831f7998b04a93a1) > [!NOTE] > > To view the full list of permitted actions for a permission, click the drop-down arrow next to the permission. > > ![Look up permission actions](https://mintcdn.com/copperco/o7UAXdiqVElIkwyY/images/service_account_actions_lookup.png?fit=max\&auto=format\&n=o7UAXdiqVElIkwyY\&q=85\&s=960c09084478cb6c480efc4527d56205) **5. Add order limits for an account or accounts** To add order limits, on the **Order limits** page, click **Add Limit**, and set order limits. 1. Choose an account or accounts that the limits will apply to. 2. Define the maximum individual order amount that, when exceeded, will require approval.\\ Select how many approvals are required. Optionally, you can select specific team members to approve those orders. 3. Define the maximum amount per time period that, when exceeded, will require approval.\\ Select how many approvals are required. Optionally, you can select specific team members to approve those orders. **6. Add order limits for a different account** If you want to set limits for another account or accounts, click **Add another** and repeat the steps for setting order limits.\\ Once you have set all the limits, click **Save**. **7. Review the account details** On the **Summary** page, review the details of the account and click **Confirm**. If you are asked to verify that it’s you as part of multi-factor authentication, provide your second authentication factor, for example, your passkey. > [!NOTE] > > Depending on your approval workflow, the Platform Authorised User and/or Account Controller will receive a notification, > both on the Copper Platform and via email, to approve the new account. Once you have created a service account, you can [create an API key](/api-reference/create-api-key) for it. # Get Active Stakes Source: https://developer.copper.co/api-reference/stake/get-active-stakes /copper-open-api-public.json get /staking/active-stakes # Get Outstanding Stakes Source: https://developer.copper.co/api-reference/stake/get-outstanding-stakes /copper-open-api-public.json get /staking/outstanding-stakes # Get Pending Stakes Source: https://developer.copper.co/api-reference/stake/get-pending-stakes /copper-open-api-public.json get /staking/pending-stakes # Try it out Source: https://developer.copper.co/api-reference/try-it-out Download the OpenAPI Specification and Postman Collection to explore and test the Copper API. These resources offer detailed information about the API’s endpoints and functionalities, helping you integrate smoothly with the Copper Platform. ## OpenAPI Specification The OpenAPI specification provides a detailed description of the Copper API's endpoints, including the request and response formats. > **[Download OpenAPI Endpoints](https://api.copper.co/platform/public-files/copper-open-api-public.json)** > > Access the detailed blueprint of our API's endpoints. ## Postman Collection The collection includes a script that automatically manages authorization, but you'll need to customize the `copperApiKey` and `copperApiSecret` variables with your credentials. This setup ensures a hassle-free experience as you explore and test the various API endpoints. ![Postman Global Variables](https://mintcdn.com/copperco/8EIpazN_ergWo9kn/images/postman-global-variables-light.png?fit=max\&auto=format\&n=8EIpazN_ergWo9kn\&q=85\&s=07af8d500d75e30c05581cbdcecb11c4) After setting up the global variables, you can start testing the API endpoints by sending requests to the Copper API. > **[Download Postman Collection](https://api.copper.co/platform/public-files/copper-postman-collection.json)** > > Access the Postman collection for quick and efficient API testing. To provide dynamic IDs, use the `{{copperExternalId}}` variable in the request body. This variable is automatically generated and can be used to create unique IDs for your requests: ```json {2} theme={"system"} { "externalOrderId": "{{copperExternalId}}", "orderType": "buy" } ``` # Create Wallet Source: https://developer.copper.co/api-reference/wallets/create-wallet /copper-open-api-public.json post /wallets Create a new wallet # Get Wallet by ID Source: https://developer.copper.co/api-reference/wallets/get-wallet-by-id /copper-open-api-public.json get /wallets/{walletId} Fetch wallet details # Get Wallets Source: https://developer.copper.co/api-reference/wallets/get-wallets /copper-open-api-public.json get /wallets When you perform a request without specifying any additional filters like `portfolioId` or `currency`, the method returns all wallets which have non-zero balances only. # API updates Source: https://developer.copper.co/changelog/changelog New features and improvements **September 23, 2026** ## New Hyperliquid API endpoints Three new endpoints add Hyperliquid trading support to the Copper API. * **Get agent wallets** — `GET /agent-wallets`. Retrieves the active Hyperliquid agent wallets for a portfolio, or for every portfolio in your organisation. Each record includes its status, expiry, and the order that created it. * **Get allowed markets** — `GET /markets`. Retrieves the list of Hyperliquid markets available to trade through Copper. * **Execute exchange action** — `POST /exchange`. Submits a Hyperliquid order through Copper's proxy. The `action` payload is identical to a direct Hyperliquid request — send your `organizationId` and `portfolioId` instead of a `nonce` and `signature`, and Copper signs and routes the order on your behalf. Before calling these endpoints, delegate Hyperliquid trading permissions to a Copper agent (API) wallet. See [**Trading on Hyperliquid**](/guides/blockchains/hyperliquid) for setup steps and a full request/response comparison, and `GET /agent-wallets` endpoint reference. **June 5, 2026** ## Documentation update: Highlighted terminal order statuses Updated order status descriptions, where applicable, to mention that, when an order has completed processing, it enters one of the final states and returns a 'terminal' status. At the time of writing, `terminalStatuses` are: `EXECUTED`, `CANCELED`, `LIQUIDATED`, `ERROR`, `BLOCKED`, `DECLINED`, `SUSPENDED`, `REJECTED` **March 10, 2026** ## New order-completed webhook event A new webhook event `order-completed` has been created. The event includes orders with the order status `executed`. No other filters are applied; all order types (deposits, withdrawals, buy, sell, etc.) are included. For more information, see [Order](/guides/webhooks/objects/order). **February 16, 2026** ## Added updatedAt field in ClearLoop actions endpoint Added `updatedAt` field in the [`clearloop/actions`](/api-reference/clearloop/get-clearloop-actions) endpoint that returns ClearLoop delegations/undelegations. **January 29, 2026** ## Change to loan types We have deprecated several loan types to simplify our API and align naming conventions. Deprecated types are automatically migrated to their replacements. All new loans will be created with the new statuses going forward and old types will be removed from the API and documentation following the migration. | Deprecated type | New type | | :- | :- | | `agency-lending-parent-loan` | `agency-inventory` | | `agency-lending-collateralised-child-loan` | `agency-title-transfer-collateralised-loan` | | `agency-lending-pledge-collateralised-child-loan` | `agency-pledge-collateralised-loan` | | `agency-lending-uncollateralised-child-loan` | `agency-uncollateralised-loan` | | `agency-lending-first-lien-child-loan` | `agency-clearloop-loan` | | `bilateral-lending-title-transfer-collateralised-loan` | `bilateral-title-transfer-collateralised-loan` | | `bilateral-lending-pledge-collateralised-loan` | `bilateral-pledge-collateralised-loan` | | `bilateral-lending-uncollateralised-loan` | `bilateral-uncollateralised-loan` | For a full list of loan types, see [`LoanType`](/enums/LoanType). ## Margin call timer for collateralised loans New `marginCallExpiryPeriod` field and `marginCall` object have been added to the Lending API. * The loan booking form now accepts a margin call period (in hours), which is specified in the new field `marginCallExpiryPeriod`, for example, in [Get Loans response](/api-reference/lending/get-loans#response-loans-items-extra-margin-call-expiry-period). The margin call expiry period can be between 1 and 24 hours. It applies only to collateralised loans. It does not apply to ClearLoop loans. * When a loan goes into Margin Call, the `marginCall` object contains the margin call associated with the loan, for example, in [Get Loans response](/api-reference/lending/get-loans#response-loans-items-embedded-margin-call). **January 28, 2026** ## A new settlementStatus field in responses that return ClearLoop portfolios A new `settlementStatus` field now appears in responses that return ClearLoop portfolios, for example, in [Get ClearLoop Portfolios](/api-reference/clearloop/get-clearloop-portfolios#response-portfolios-items-settlement-status). The field contains the status of the last settlement cycle. This change has been introduced as part of platform improvements. For information about settlement status values, see [PortfolioSettlementStatus](/enums/PortfolioSettlementStatus). **January 5, 2026** ## Early termination of ClearLoop loans A new endpoint, [\`PATCH /platform/organizations/\{organizationId}/loans/\{earlyTerminationLoanId}](/api-reference/lending/early-terminate-loan) has been created, that allows Copper's financing desk (Agency Desk) to immediately recall outstanding loans where there has been a breach of loan terms. > [!NOTE] > > Early termination of a loan can only be initiated by an Agency Desk: A specialized organisational entity that acts as > an intermediary between lenders and borrowers. The agency desk is set up and managed by administrators and has the > organization subtype `AGENCY_DESK`. New [`LoanStatus`](/enums/LoanStatus) statuses of the type `enum` have been introduced as part of the early termination flow: * `early-termination-in-progress` - The loan is in the process of being terminated early. * `early-termination-completed` - Early termination of the loan has been completed. **November 13, 2025** ## New transaction types for accepting or rejecting deposits on-chain New [`BlockchainTransactionType`](/enums/BlockchainTransactionType) types `accept-deposit` and `reject-deposit` have been introduced to support on-chain deposit acceptance on the Canton Network. **November 5, 2025** ## ClearLoop documentation update Updated ClearLoop OpenAPI documentation, clarified parameter descriptions. **October 15, 2025** ## API key rate limits improvements Previously, API key rate limits were enforced per user, aggregating requests across all organisations and API keys for that user. This could cause someone with multiple API keys in different organisations to be rate limited globally if one key exceeds the limit, even if other keys are within limits. Now, the [API key rate limits](/api-reference/rate-limits) are enforced per user and per organisation. This prevents excessive usage in one organisation from impacting API keys in another organisation for the same user. This change also enables a more granular rate limit monitoring at the organisation level for both admins and clients. # Trading on Hyperliquid Source: https://developer.copper.co/guides/blockchains/hyperliquid ## API trading Copper provides a dedicated API proxy for clients trading on Hyperliquid, routing all order requests through Copper's platform rather than directly to the exchange endpoint. This intermediary layer enables operational safeguards such as policy engine controls, and governance requirements before orders reach the market. To trade on Hyperliquid via API directly from your Copper MPC wallet address, you must delegate Hyperliquid trading permissions to Copper's dedicated API wallet. This will enable you to submit trades through the Copper Hyperliquid API. The Copper API wallet can submit trades requested on your behalf but cannot **initiate withdrawals**. You can revoke this access at any point. ## Setting up your agent (API) wallet Before you set up your agent wallet, create your Copper Service User API key using the standard setup process. Then, you configure your agent wallet from the "Hyperliquid API Wallet" dashboard in Copper. * This dashboard only appears if you have at least one activated Hyperliquid wallet with HypeCORE funds. * Activate HypeEVM and HypeCORE in your portfolio. * Bridge USDC from ETH to HypeCORE. This requires two steps: ETH to HypeEVM, then HypeEVM to HypeCORE. * The Hyperliquid API Wallet should appear on your dashboard. * From the dashboard click the "+" button. * On first setup, you will be asked to acknowledge and download a legal addendum before you can continue. Once acknowledged, you can proceed to link your Hyperliquid API wallet. * You will be asked to provide: * Validity length (Max 180 days) * You will be asked to sign a transaction using your Copper MPC wallet to link the Copper API wallet to the Master Wallet. * Once this transaction is executed, the API wallet is granted trading rights on behalf of the Master Wallet for the full validity period. *The API wallet never has withdrawal rights.* * From here the API wallet will have access to trade with any funds sitting in the HypeCORE balance on the Master Wallet. * You can revoke the agent permission from your dashboard at any point. > [!NOTE] > > You can have a maximum of one API wallet associated to a single portfolio at a time. This applies to trades submitted through the API and through the trading UI. Once your API wallet is activated, you can trade on Hyperliquid using the native Hyperliquid API and submit to the Copper API proxy. ## Submitting a trade through the Copper API The proxy is designed to mirror the Hyperliquid API as closely as possible, minimising integration overhead while adding Copper's pre-trade validation and audit layer. However the core structure of the request differs in one key area: **authentication and routing parameters**. Note: Copper charges a small on-chain fee for product maintenance and order execution. ### Direct Hyperliquid request When submitting directly to Hyperliquid, the client is responsible for signing the request with their wallet's private key. The payload includes: * `action` — the order details * `nonce` — a Unix timestamp in milliseconds, used to prevent replay attacks * `signature` — a cryptographic signature generated by the client's wallet (`r`, `s`, `v` components) **See below a sample direct API call to Hyperliquid** ```json theme={"system"} { "action": { "type": "order", "orders": [ { "a": "3", "b": true, "p": "64107", "s": "0.0012", "r": false, "t": { "limit": { "tif": "Gtc" } } } ], "grouping": "na" }, "nonce": 1234567890123, "signature": { "r": "0xabc123...", "s": "0xdef456...", "v": 28 } } ``` ### Copper proxy request When submitting through the Copper proxy, the `nonce` and `signature` fields are **removed**. Copper's backend generates these using its own agent wallet on the client's behalf. In their place, two Copper-specific fields are required for routing and audit: * `organizationId` — your Copper organisation identifier * `portfolioId` — the specific portfolio from which the trade should be executed The `action` payload is **identical** to what you would send directly to Hyperliquid — no changes are needed there. **See below a sample API call via the Copper API proxy** Endpoint: `POST https://api.copper.co/platform/exchange` ```json theme={"system"} { "action": { "type": "order", "orders": [ { "a": "3", "b": true, "p": "64107", "s": "0.0012", "r": false, "t": { "limit": { "tif": "Gtc" } } } ], "grouping": "na" }, "organizationId": "clientOrgName", "portfolioId": "abcde12345" } ``` **The** `action` **payload** The `action` object follows the Hyperliquid specification exactly. Refer to the [Hyperliquid Exchange Endpoint documentation](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order) for the full field reference. The example above places a limit order (Good-till-cancelled) for asset index `3`, buying `0.0012` units at a limit price of `64107`. | Field | Description | | - | - | | `a` | Asset index | | `b` | Side — `true` = buy, `false` = sell | | `p` | Limit price | | `s` | Size | | `r` | Reduce-only flag | | `t` | Order type — `limit` with time-in-force (`Gtc`, `Ioc`, `Alo`) | | `grouping` | Order grouping — typically `"na"` | The Copper proxy is designed to be a minimal-friction integration for existing Hyperliquid users. If you are already integrated with Hyperliquid, migrating to the Copper proxy requires only: 1. Changing the **endpoint URL** to Copper's proxy 2. Removing the `nonce` and `signature` fields 3. Adding your `organizationId` and `portfolioId` The `action` payload requires no changes. # Connect Exchange Account Source: https://developer.copper.co/guides/clearloop/binding To set up a ClearLoop account, clients need to connect a Copper Trading Account to an account on the exchange. This is what is also referred to as account binding. To do this, you will need to provide a few details using the Copper Platform’s user interface. These details can vary depending on the exchange; however, they typically include the following: an API key, an API secret, and the account ID. Note that the exchanges available to a client depend on the organization’s administrative settings. If an exchange isn’t shown in the user interface, it must first be enabled by an administrator on the Copper Admin platform. ### Portfolio auto-discovery Once the connection is successful, portfolio auto-discovery is executed, which automatically creates a list of sub-accounts based on the products offered by the exchange. One of the auto-discovered accounts is the Main exchange account, which serves as the entry point to the exchange. When funds are delegated to the exchange, they are credited to the main account’s balance. Conversely, when funds are undelegated, they are deducted from the main account’s balance and released back into the Copper Trading Account. ![ClearLoop accounts overview](https://mintcdn.com/copperco/qc7EFIEkg1kdAkXq/images/clearloop_accounts_overview.png?fit=max\&auto=format\&n=qc7EFIEkg1kdAkXq\&q=85\&s=98f31333172f365f494b843366f5dbc2) For example: ![ClearLoop Binding](https://mintcdn.com/copperco/8EIpazN_ergWo9kn/images/clearloop-binding.png?fit=max\&auto=format\&n=8EIpazN_ergWo9kn\&q=85\&s=385ce3c4e4ac65ae9d3938f83781561b) Some sub-accounts require users to manually input additional information, such as the API key or API secret. In such cases, a notification message will appear on the platform, as shown below. ![ClearLoop Binding Information Required](https://mintcdn.com/copperco/8EIpazN_ergWo9kn/images/clearloop-binding-information-required.png?fit=max\&auto=format\&n=8EIpazN_ergWo9kn\&q=85\&s=73488152070e9b33a02036398b347c25) All information about exchange accounts is sourced directly from the exchange and is provided for informational purposes only. This information is identical to what is available on the exchange. Note that the terms “account” and “transaction” in the user interface correspond to the terms “portfolio” and “order” in the API and codebase. # Delegate (lock) and transfer funds Source: https://developer.copper.co/guides/clearloop/delegate-funds copper-open-api-create-order-delegate-or-undelegate post /orders ## Delegate (lock) funds to an exchange You can delegate funds to an exchange on the ClearLoop Network using the Copper user interface or API. When funds are delegated, they are locked in the client’s Copper Trading Account and credited to the exchange account. Two orders are created as a result: * Withdrawal order in the Trading portfolio, containing `isClearLoopDelegation` under order `extra`. * Deposit order in the ClearLoop portfolio. For example: ![ClearLoop delegation transactions](https://mintcdn.com/copperco/qc7EFIEkg1kdAkXq/images/clearloop_delegation_ui_entry.png?fit=max\&auto=format\&n=qc7EFIEkg1kdAkXq\&q=85\&s=44fec748adc1102ad3d86395cb01912d) Both orders are linked under order extra by `withdrawOrderId` and `depositOrderId`. Note that the terms “account” and “transaction” in the user interface correspond to the terms “portfolio” and “order” in the API and codebase. To delegate funds to a ClearLoop exchange, create an order with the following parameters, where: * `portfolioId` is the ID of the Trading Account. * `toPortfolioId` is the ID of a ClearLoop Settlement Account that is bound to the exchange. Your delegated funds are automatically credited from the settlement account to the main exchange account. > [!NOTE] > > For an example of a ClearLoop accounts structure, see [Connect Exchange Account](binding). ## Transfer funds between the main exchange account and subaccounts Once the funds are delegated to an exchange and automatically credited to your main exchange account, you can transfer funds to exchange sub-accounts. In that case, `portfolioId` is the ID of the main exchange account and `toPortfolioId` is the ID of the sub-account. > [!WARNING] > > You cannot transfer to a sub-account from a ClearLoop Settlement Account. # Fetch delegated balances Source: https://developer.copper.co/guides/clearloop/fetch-delegated-balances get /clearloop/balances The ClearLoop balance displayed on the Trading Account Dashboard on the platform represents the total balance currently delegated to exchanges for exclusive use within ClearLoop. Because the same Copper Trading Account can be connected to multiple exchanges, the ClearLoop balance represents the cumulative asset total across all connected exchanges. ![Trading Account Balances](https://mintcdn.com/copperco/8EIpazN_ergWo9kn/images/ta-balances.png?fit=max\&auto=format\&n=8EIpazN_ergWo9kn\&q=85\&s=7a301bbaceeb2f153957563832a2a0b2) In every ClearLoop account, you can see both the balances on the exchange and the delegated balances. Please note that the Total delegated balances may not immediately reflect recent activity on the exchange. ![ClearLoop Account Balances](https://mintcdn.com/copperco/8EIpazN_ergWo9kn/images/clearloop-balances.png?fit=max\&auto=format\&n=8EIpazN_ergWo9kn\&q=85\&s=945bf7d0a5152e772b9bd250ee0b517a) The `Available to undelegate` balance is calculated as: minimum(Total delegated, Main Account Available). The `Total available` to undelegate corresponds to the sum of all amounts available to undelegate across both the main account and sub-accounts. Note that only funds in the main account can be undelegated. You can fetch ClearLoop Balances for an organization via API: # Introduction Source: https://developer.copper.co/guides/clearloop/introduction ClearLoop is an off-exchange settlement solution designed for institutional investors. It allows Copper clients to delegate and trade virtual balances on centralised exchanges, with settlements occurring on Copper’s infrastructure. This solution mitigates counterparty and insolvency risks, while improving operational efficiency at scale. When funds are delegated to an exchange, no actual transfer occurs until settlement. Instead, the delegated funds are locked in a dedicated ClearLoop omnibus account, and a virtual balance is credited to the exchange account. This virtual balance can be used for trading supported instruments on the exchange, such as spot and margin trading. To reconcile the difference between the exchange balance and the delegated balance, ClearLoop settlements are performed at regular intervals (every 2, 4, or 24 hours depending on the exchange). Settlements ensure that the profit and loss (P\&L) generated on the exchange is accurately reflected on Copper. This guide provides key information about ClearLoop, from account setup to operations management: * Connect a ClearLoop exchange account * Delegate and undelegate funds * Fetch delegated balances * ClearLoop settlements If you want to receive information about exchanges, please see the ClearLoop Exchanges API. # ClearLoop Settlements Source: https://developer.copper.co/guides/clearloop/settlements get /clearloop/settlements P\&L is settled for all clients at the same time. If an exchange lacks sufficient collateral to meet all client settlement requirements, a margin call is issued, and client orders remain pending until the exchange tops up its account. Note that Copper does not act as a calculation agent – P\&L is always calculated by the exchange. There is a dedicated section for settlements cycles in the user interface of every ClearLoop account, as shown below. ![ClearLoop Settlements](https://mintcdn.com/copperco/8EIpazN_ergWo9kn/images/clearloop-settlements.png?fit=max\&auto=format\&n=8EIpazN_ergWo9kn\&q=85\&s=a90e754714ae4898092bd624d3612165) To obtain information about past settlements, use the Settlements API with the following parameters: # Undelegate (unlock) funds Source: https://developer.copper.co/guides/clearloop/undelegate-funds copper-open-api-create-order-delegate-or-undelegate post /orders Undelegate funds from a ClearLoop exchange using the Copper user interface or API. When funds are undelegated, they are withdrawn from the exchange and released back into the Copper Trading Account. Two orders are created as a result: * Deposit order in the Trading portfolio, containing isClearLoopUnDelegation under order extra. * Withdrawal order in the ClearLoop portfolio. Both orders are linked under order extra by withdrawOrderId and depositOrderId. Note that the terms “account” and “transaction” in the user interface correspond to the terms “portfolio” and “order” in the API and codebase. To undelegate funds from a ClearLoop exchange, create an order with the following parameters: # Introduction Source: https://developer.copper.co/guides/copper-network/introduction The Copper Network is a network that enables counterparties to create and execute bilateral settlements or one-way transfers while minimizing counterparty risk on the Copper Platform. Copper Network supports both crypto-to-crypto settlements and fiat-linked settlements. The following settlement order types are currently supported by the Copper Network: * **Payment vs Payment (PvP)**: PvP settlement orders require both counterparties to settle their legs simultaneously. The funds are reserved/prefunded on both sides before settlement, at the point of acceptance. A delivery occurs only if another delivery has occurred (and vice versa). * **Free of Payment (FoP)**: In FoP settlement orders, the settlement legs are transferred independently of each other. There is no fund reservation at settlement acceptance; each counterparty needs to explicitly trigger the transfer of funds. The FoP order type bears higher risk as there is no guarantee on the platform that, once one side has settled, the other side will also settle. The option is only available to those who signed the Terms and Conditions for FoP. The status of active Copper Network settlements and transfers can be monitored and actioned for approval or cancellation from the order response. # Accept a settlement order Source: https://developer.copper.co/guides/copper-network/settlements/accept-settle-order patch /orders/{acceptOtcOrderId} Accept counterparty settlement order # Cancel a settlement order Source: https://developer.copper.co/guides/copper-network/settlements/cancel-settle-order patch /orders/{cancelOrderId} # Create a settlement order Source: https://developer.copper.co/guides/copper-network/settlements/create-settlement-order copper-open-api-create-order-create-network-settlement post /orders Using the following API, you can create a settlement order on the Copper Network. You need to set the following parameters: # Find supported currencies Source: https://developer.copper.co/guides/copper-network/settlements/find-supported-currencies get /currencies This allows to obtain the list of currencies supported by the Copper platform. In order to get a list of currencies supported for settlements, use the filtering by `show-trading` tag. # Retrieve Network participants Source: https://developer.copper.co/guides/copper-network/settlements/retrieve-network-participants get /organizations/{organizationId}/counterparties Find participant of the Copper Network To initiate a settlement you need to know the `counterpartyId`. You can find it using this API. # Sign a settlement order Source: https://developer.copper.co/guides/copper-network/settlements/sign-settle-order patch /orders/{startSigningOrderId} Start crypto signing for an order In certain cases, a settlement order needs to be signed (making a settlement from a trading-vault). Use the following API to provide the signature for the settlement order. # Approve transfer Source: https://developer.copper.co/guides/copper-network/transfers/approve-transfer-order patch /orders/{coSignOrderId} In certain cases, you may need to approve a transfer order on the Copper Network (Permission engine requires additional approvals). Use the following API to approve it. After approving the transfer order, the transfer will be processed. # Create transfer Source: https://developer.copper.co/guides/copper-network/transfers/create-transfer-order copper-open-api-create-order-create-network-transfer post /orders To create a one-way transfer order on the Copper Network, set the following parameters: # Retrieve Network participants Source: https://developer.copper.co/guides/copper-network/transfers/retrieve-network-participants get /organizations/{organizationId}/counterparties Find participant of the Copper Network Find the `counterpartyId` to initiate a one-way transfer. # Create a withdrawal order Source: https://developer.copper.co/guides/copper-unlimited-online/create-withdraw-order copper-open-api-create-order-generic-withdraw-order post /orders To initiate a withdrawal order from a Copper custody account and send funds, specify the destination of the funds by providing any of the following: # Enabling SSL/TLS Source: https://developer.copper.co/guides/copper-unlimited-online/enabling-ssl-tls To enable SSL/TLS support, add a volume containing your key and certificate to the Copper Unlimited Online container: **1. Generate custom certificates** ```bash theme={"system"} openssl genrsa -out privatekey.key openssl req -new -key privatekey.key -out csr.pem openssl x509 -req -days 9999 -in csr.pem -signkey privatekey.key -out certificate.cert ``` **2. Add the path** Add the path to the folder containing certificates as volumes: `-v ${PWD}/ssl/certificate.cert:/app/ssl/certificate.cert`, as well as `-v ${PWD}/ssl/privatekey.key:/app/ssl/privatekey.key`: ```bash theme={"system"} docker run --rm -ti \ -v ${PWD}/key-backups/:/app/keys/ \ -e APP_ENVIRONMENT='testnet' \ -v ${PWD}/ssl/certificate.cert:/app/ssl/certificate.cert \ -v ${PWD}/ssl/privatekey.key:/app/ssl/privatekey.key \ -p 3010:3010 \ copperexchange/copper-unlimited:latest ``` # Example of the service Source: https://developer.copper.co/guides/copper-unlimited-online/example-of-the-service In order to familiarize yourself with the operation of Copper Unlimited Online, the Copper Team has a ready-made containerized example of the service to deploy on your side. It looks like one more image to deploy together with Copper Unlimited Online and is available on [Copper DockerHub](https://hub.docker.com/r/copperexchange/hot-wallet). The application works as follows: 1. The application pulls orders in the `working` and `awaiting-settlement` statuses using the Copper public API. If there are no orders available, the application enters sleeping mode for 10 seconds. 2. Then, the application takes the first order, and if it is in the `awaiting-settlement` status, moves it to the `working` status. 3. After this, it triggers the order signing request to the Copper Unlimited Server. 4. The application waits until the request is either in the `completed` or `error` status. 5. If the request is in `error` status, it fires an error; if it is in `completed`, it repeats the whole process starting from the first point. To deploy and test the service, perform the following steps: **1. Configure your docker-compose.yml** ```yaml theme={"system"} version: "3.7" services: cu-server: # Copper Unlimited Online service container_name: cu-server image: copperexchange/copper-unlimited:latest ports: - "3010:3010" volumes: - ${PWD}/key-backups/:/app/keys/ # Specify the correct path to your shards before the colon environment: APP_ENVIRONMENT: "testnet" # Specify the environment where you are going to use the service. Possible variants: "testnet", "demo" or "mainnet" APP_NETWORK: "testnet" restart: always healthcheck: test: "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/3010' || exit 1" interval: 30s timeout: 10s retries: 10 start_period: 10s networks: - cu-network hot-wallet: image: copperexchange/hot-wallet:latest depends_on: - cu-server volumes: - ${PWD}/wallets-config.js:/app/wallets-config.js # Specify the correct path to your wallet-config.js file before the colon. environment: APP_ENVIRONMENT: "testnet" # Specify the environment (see above) APP_CUSTODY_DOCKER_URL: "http://cu-server:3010" # Link to the CU Online container APP_API_KEY: "" # Your API key from the desired environment APP_API_SECRET: "" # API secret associated with the API key APP_WITHDRAWAL_PASSWORD: "" # Your Master password restart: always networks: - cu-network networks: cu-network: driver: bridge ``` **2. Provide shards** Backup your wallet shards and place them in the directory specified as an external volume for the `cu-server` container (in the example: `${PWD}/key-backups/`). Do not forget to activate the created wallets in the desired platform environment and request to switch the corresponding vaults to hot if it has not been done before. **3. Configure wallets** The `wallets-config.js` file contains details of the shards. Below, you will find an example of the configuration with comments: ```js theme={"system"} module.exports = [ { portfolioId: 'ckuwfho1y000p3e626z2zmmoy', // Identifier of the portfolio containing the wallet currency: 'SOL', // Wallet currency walletFilename: 'sol-wallet.copper', // Name of the file containing the wallet shard walletPassword: process.env.SOL_WALLET_PASSWORD, // Password }, { portfolioId: 'cd213vvo1y000p3e62dd21dhy', // You may specify as many shards as needed separating details with commas currency: 'ALGO', walletFilename: 'algo-wallet.copper', walletPassword: process.env.ALGO_WALLET_PASSWORD, }, ]; ``` Place this file in the directory specified as an external volume for the `hot-wallet` container (in the example: `${PWD}/wallets-config.js`). As per the example, the resulting file composition on this step looks as follows: ``` /${PWD} ├── key-backups │ ├── sol-wallet.copper │ └── algo-wallet.copper ├── docker-compose.yml └── wallets-config.js ``` **4. Start your service** Start your service with the use of the `docker-compose up --build` command. **5. Create withdrawals and sign** Use the specified environment of the Copper Platform to create withdrawal orders. They will be signed and pushed forward automatically. # Get Copper Unlimited Transaction Source: https://developer.copper.co/guides/copper-unlimited-online/get-cu-transaction copper-unlimited-open-api get /sign-async/{transactionRequestId} Optionally, retrieve the status of your request from Copper Unlimited Online using your `transactionRequestId` # How to launch Source: https://developer.copper.co/guides/copper-unlimited-online/how-to-launch > **Software requirements** > > Copper Unlimited Online is a Docker image based on `debian:10.5-slim` and uses [Docker > Compose](https://docs.docker.com/compose/) and the **NodeJS daemon** for its operation. > > The image is publicly available on [Copper > DockerHub](https://hub.docker.com/r/copperexchange/copper-unlimited). > > Network characteristics of the image: > > * listens to port 3010 for incoming data and 443 for outgoing calls; > * connects with the Copper API, depending on the chosen `APP_ENVIRONMENT`; > * supports SSL/TLS. To enable encryption, see the **Enabling SSL/TLS** section below. **1. Export shards** Export shards of your key from the CU Desktop application via the wallet backup function: click the drop-down menu in the top right corner of the window and choose the **Backup** option. During the export process, CU Desktop will ask for a password to encrypt each shard of the wallet. This will prevent accessing the shard data in case a potential attacker gains access to the filesystem. Choose a preferred folder to save the `*.copper` file containing the wallet shards. **2. Prepare the environment** Before running, specify the following fields: * a path to your folder with the `*.copper` file. * a port that CU Online endpoints will listen to. There is an option to pass the `APP_PORT` environmental variable to specify a port within the container. * the required environment set by the `APP_ENVIRONMENT` environment variable. The choice depends on the platform you are going to operate on. The `APP_NETWORK` variable is determined automatically and can be omitted. However, if `APP_NETWORK` is specified, it must match the table below. The environment is set as follows: | APP\_ENVIRONMENT | APP\_NETWORK | Environment | | :- | :- | :- | | `prod` | `mainnet` | copper.co | | `mainnet` | `mainnet` | copper.co | | `stage` | `mainnet` | demo.copper.co | | `demo` | `mainnet` | demo.copper.co | | `testnet` | `testnet` | testnet.copper.co (default) | **3. Launch the Copper Unlimited Online server** To launch the server, use the command below (for any docker run command reference, see the [official Docker documentation](https://docs.docker.com/engine/reference/run/)). ```shell theme={"system"} docker run --rm -ti \ -v ${PWD}/key-backups/:/app/keys/ \ -e APP_ENVIRONMENT='testnet' \ -p your_port_for_cu_online:3010 \ copperexchange/copper-unlimited:latest # ${PWD}/key-backups/ is the folder containing the wallet backup. # The APP_ENVIRONMENT variable can be 'testnet', 'stage', 'prod', 'demo' or 'mainnet' (see details above). ``` **4. Sign** As everything is set up, you can start signing transactions. The next steps explain how to create a withdrawal order using the Copper Platform API and sign it using Copper Unlimited Online. # Sign transaction Source: https://developer.copper.co/guides/copper-unlimited-online/sign-transaction copper-unlimited-open-api post /sign-async Create a request to Copper Unlimited Online to sign the transaction. After signing, when the transaction is in the completed status, the signed transaction will be uploaded to the Copper Platform automatically. # Start signing Source: https://developer.copper.co/guides/copper-unlimited-online/start-signing-flow patch /orders/{startSigningOrderId} Start crypto signing for an order # Create a multi-smart-call order Source: https://developer.copper.co/guides/defi/create-multi-smart-call-order copper-open-api-create-order-multi-smart-call post /orders Create a multi-smart-call order containing a list of unsigned transactions. To verify whether the currency supports multi-smart-call orders, retrieve the list of currency tags using the [`GET /platform/currencies`](/api-reference/currencies/get-currencies) endpoint and check whether the response contains the `defi-allowed` tag in the [list of currency tags](/enums/CurrencyTag). # Create a smart-call order Source: https://developer.copper.co/guides/defi/create-smart-call-order copper-open-api-create-order-smart-call post /orders To create a smart-call order containing an unsigned transaction, send the following parameters: # How to launch Source: https://developer.copper.co/guides/fees-vaults/how-to-launch > **Software requirements** > > In order to operate the dockerized application, an instance of [Copper Unlimited Online](/guides/copper-unlimited-online) must be configured > with the required wallet shards for the associated fees vault. > > The fees vault service is provided as a Docker image based on `node:lts-alpine` and can be run using [Docker Compose](https://docs.docker.com/compose/). > > The image is publicly available on [Copper DockerHub](https://hub.docker.com/r/copperexchange/hot-wallet). > > Network characteristics of the image: > > * Connects with the Copper API, depending on the chosen `APP_ENVIRONMENT`; > * Connects with Copper Unlimited Online, depending on the given `APP_CUSTODY_DOCKER_URL` configuration; **1. Wallet configuration** Before launching, a wallet configuration file must be created. This is a JavaScript file containing a JSON object that describes the wallets that the application can sign transactions for. The file is in the following format: ```javascript theme={"system"} module.exports = [ { portfolioId: '', currency: 'ETH', walletFilename: 'eth-wallet.copper', walletPassword: process.env.ETH_WALLET_PASSWORD, }, { portfolioId: '', currency: 'TRX', walletFilename: 'trx-wallet.copper', walletPassword: process.env.TRX_WALLET_PASSWORD, }, ]; ``` Any number of wallets can be configured in this file, but each wallet must have the following properties: * `portfolioId` - the ID of the fees vault account that the wallet is associated with * `currency` - the currency that the wallet is associated with * `walletFilename` - the filename of the wallet backup file as used in the Copper Unlimited Online instance * `walletPassword` - the password used to encrypt the wallet backup file (in the example given above, this is an environment variable) **2. Start the app** Configure and run the Copper Unlimited Online instance with shards for the configured MPC wallets in your organization's fees vault. See the examples in the [Copper Unlimited Online guide](/guides/copper-unlimited-online/how-to-launch). To launch the server, use the command below: ```bash theme={"system"} docker run --rm -ti \ -v ${PWD}/wallets-config.js:/app/wallets-config.js \ -e APP_ENVIRONMENT='testnet' \ -e APP_CUSTODY_DOCKER_URL='{url-of-cu-online}:3010' \ -e APP_API_KEY='{copper-platform-api-key}' \ -e APP_API_SECRET='{copper-platform-api-secret}' \ -e APP_WITHDRAWAL_PASSWORD='{withdrawal-password}' \ copperexchange/hot-wallet:latest # ${PWD}/wallets-config.js is the wallet config file described above. # The APP_ENVIRONMENT variable can be 'testnet', 'stage' or 'mainnet' (see details above). # The APP_CUSTODY_DOCKER_URL variable is the URL of the CU Online instance that the application will connect to. # The APP_API_KEY and APP_API_SECRET variables are the API key and secret that the application will use to connect to the Copper API. # The APP_WITHDRAWAL_PASSWORD variable is the withdrawal password of the organization that the application will use to authenticate for withdrawals. ``` After starting the server, it should now be possible to send token transfers from proxy addresses paying the fees from the fees vault account. In this flow, orders will be created automatically to cover the fees amounts and the dockerized application will sign and broadcast the transactions to the blockchain. # What are Fees Vaults Source: https://developer.copper.co/guides/fees-vaults/introduction Fees vaults are a type of MPC vault that are used to pay fees for token transfers from proxy wallets to the destination accounts. In order to sign and broadcast the required transactions, a Dockerized application made by Copper is provided to process transactions along with [Copper Unlimited Online](/guides/copper-unlimited-online). When orders are created by the Copper Platform to pay fees for token transfers from proxy wallets, the Dockerized application will then sign using [Copper Unlimited Online](/guides/copper-unlimited-online) and broadcast the transactions to the blockchain automatically. > [!NOTE] > > If you want to use your own fees wallets to pay fees, contact your account manager to set up a specific fees wallet account in your > organization. # Fetch balances Source: https://developer.copper.co/guides/fetch-balances-and-transactions/fetch-balances get /wallets When you perform a request without specifying any additional filters like `portfolioId` or `currency`, the method returns all wallets which have non-zero balances only. # Fetch orders Source: https://developer.copper.co/guides/fetch-balances-and-transactions/fetch-orders copper-open-api-get-orders-get-orders get /orders To retrieve buy and sell orders, specify the `orderTypes` parameter as demonstrated below. To filter by specific portfolios or subaccounts, set the `porfolioIds` parameter. # Fetch transfers Source: https://developer.copper.co/guides/fetch-balances-and-transactions/fetch-transfers copper-open-api-get-orders-get-transfers get /orders To retrieve transfers (withdrawals and deposits), specify the `orderTypes` parameter as demonstrated below. To filter by a specific portfolios or subaccounts, set the `porfolioIds` parameter. # Fetch updated transfer or orders Source: https://developer.copper.co/guides/fetch-balances-and-transactions/fetch-updated-orders To efficiently get updated orders from the Copper API, you can use `updatedSince` query parameter. This parameter allows you to filter orders by the time they were last updated. **1. Get the Last Update Time** To avoid downloading all orders every time, track the last time you checked for updates. Store this `updated_at` of the last fetched order in a safe place, like a database or a file. This tells your system when you last fetched updates **2. Request Updated Orders** Use the `updated_at` timestamp to ask the Copper API for any orders updated since that time by passing `updatedSince` query parameter. The API also lets you specify a limit on how many orders to fetch in one request, which helps manage data better. **3. Process the Orders** Go through each order you receive and do what's needed — like logging details, updating your system, or triggering other processes. Ensure that your operations can handle repeats without causing issues, in case the same order is fetched again. **4. Update the Last Update Time** After dealing with a batch of orders, update your stored `updated_at` timestamp to the most recent order update time in that batch. This way, your next API request will only fetch newer updates. **5. Handle Pagination Efficiently** To efficiently handle pagination, request one more order than you actually need. For example, if you want to fetch 100 orders, request 101. Use only the first 100 orders for processing. If you receive the 101st order, it indicates there are more orders to fetch. Repeat the process until the number of orders received is less than or equal to the limit you set (100 in this case), which means there are no more updates. ### Example > [!NOTE] > > This is not production-ready code. It's a simple example to help you understand the process. ```python theme={"system"} import hashlib import hmac import json import os import requests import time ApiKey = os.getenv("COPPER_LIVE_API_KEY") ApiSecret = os.getenv("COPPER_LIVE_API_SECRET") def copper_api(method, path, body=None): timestamp = str(round(time.time() * 1000)) body_string = json.dumps(body) if body else "" signature = hmac.new( key=bytes(ApiSecret, 'utf-8'), msg=bytes(timestamp + method + path + body_string, 'utf-8'), digestmod=hashlib.sha256 ).hexdigest() url = 'https://api.copper.co' + path resp = requests.request(method, url, json=body if body else None, headers={ 'Authorization': 'ApiKey ' + ApiKey, 'X-Signature': signature, 'X-Timestamp': timestamp, 'Content-Type': 'application/json' }) print(f"Copper API ~~~> {method} {url} <~~~ {resp.status_code} {resp.reason}") if resp.status_code >= 400: raise Exception(f"Copper API Error: {resp.status_code} {resp.reason} <~~~ {resp.text}") return resp.json() def get_latest_updated_at(): # Retrieve the updated_at value from a database or return 0 return 0 def save_latest_updated_at(updated_at): # Store the updated_at value in a database pass def fetch_updated_orders(last_updated_at): # fetch all orders from Copper that have been updated since updated_at limit = 101 response = copper_api("GET", f"/platform/orders?orderType=deposit&updatedSince={last_updated_at}&limit={limit}") orders = response.get('orders', []) if len(orders) > 0: for order in orders[:limit-1]: # Process each order print(f"{order.get('orderId')} - {order.get('updatedAt')}") pass last_updated_at = orders[-1].get('updatedAt') save_latest_updated_at(last_updated_at) if len(orders) > limit - 1: time.sleep(10) # Wait 10 seconds before fetching the next batch of orders fetch_updated_orders(last_updated_at) if __name__ == "__main__": fetch_updated_orders(get_latest_updated_at()) ``` # Approve (co-sign) an order Source: https://developer.copper.co/guides/funds-transfers/approve-transfer-order patch /orders/{coSignOrderId} In certain cases, the permission engine requires additional approvals for a transfer order. To approve the order, use this endpoint. If the master password is required to approve the order, you can specify `masterPassword`—a SHA-256 encrypted hash of the withdrawal password—in the request. After approval, the transfer will proceed. > [!NOTE] > > If you haven't specified the master password, and the order status `master-password-required` is returned, your approval > still counts, but you or another user must supply the master password for the order, > using the [`PATCH /orders/{orderId}`](/guides/funds-transfers/enter-master-password-order) endpoint, for the transfer to proceed. # Cancel order Source: https://developer.copper.co/guides/funds-transfers/cancel-order patch /orders/{cancelOrderId} # Chain of withdrawals Source: https://developer.copper.co/guides/funds-transfers/chain-of-withdrawals copper-open-api-create-order-chain-of-transfers post /orders To create a chain of withdrawals, send the following parameters: # Enter the master password for an order Source: https://developer.copper.co/guides/funds-transfers/enter-master-password-order patch /orders/{orderId} When the order status is `master-password-required`, you can use this endpoint to enter the master password for the order. `masterPassword` is a SHA-256 encrypted hash of the withdrawal password. Please note that, for convenience, there is an [Approve (co-sign) an order](/guides/funds-transfers/approve-transfer-order) endpoint that allows you to co-sign and enter the master password at the same time. # Move funds between exchanges Source: https://developer.copper.co/guides/funds-transfers/move-funds-between-exchanges There are two methods to move funds between exchanges, based on whether the funds are delegated to the exchange. ### Moving ClearLoop Delegated Funds If your funds are delegated, you first need to undelegate them before transferring to another exchange. Follow the [undelegate funds guide](/guides/clearloop/undelegate-funds) to do this. ### Moving Non-Delegated Funds If your funds are not delegated, you can transfer them directly by making a withdrawal. Specify the destination using `toPortfolioId` of the portfolio you wish to send the funds to. For detailed steps, see the [move funds guide](/guides/funds-transfers/move-funds-between-portfolios). # Move funds between portfolios Source: https://developer.copper.co/guides/funds-transfers/move-funds-between-portfolios copper-open-api-create-order-move-funds-between-portfolios post /orders To create a movement of funds between two portfolios, send the following parameters: # Move funds between exchange subaccounts Source: https://developer.copper.co/guides/funds-transfers/move-funds-between-subaccount copper-open-api-create-order-move-funds-between-portfolios post /orders To create a movement of funds between two subaccounts, send the following parameters: # Sign order Source: https://developer.copper.co/guides/funds-transfers/sign-order patch /orders/{startSigningOrderId} Start crypto signing for an order In certain cases, an order needs to be signed (making a settlement from a trading-vault). Use the following API to provide the signature for the settlement order. # Withdraw to an Address Book address Source: https://developer.copper.co/guides/funds-transfers/withdraw-to-address-book copper-open-api-create-order-move-funds-to-crypto-address post /orders > [!NOTE] > > **Travel Rule** \\ > > Financial regulations require us to collect information under the Travel Rule. > We carry out multiple verifications for owners, addresses, and address ownership, for both deposits and withdrawals. \\ > > All outgoing withdrawal orders are only allowed to be made to addresses from the [Address Book](/api-reference/address-book), > that have passed the Travel Rule checks. > Use the Copper Platform to create a new address and pass the Travel Rule checks before making a withdrawal. To create a withdrawal to an address book address, send the following parameters: # Introduction Source: https://developer.copper.co/guides/introduction ![Copper Developer](https://mintcdn.com/copperco/BAAd9nJriF2rfIHz/images/copper-dev-light.svg?fit=max\&auto=format\&n=BAAd9nJriF2rfIHz\&q=85\&s=741b955efb91ae56cda04a54e1e9e6db) # Copper Developer Portal There are two main sections to guide your integration journey. The first section offers comprehensive guides on specific API integrations to help you seamlessly incorporate our features. The second section provides an OpenAPI-based description of our Platform's API, offering detailed insights into our endpoints and their functionalities. Dive in to discover how our API can empower your projects! > **[Explore Copper Platform API](/api-reference)** ## Main entities structure The diagram below illustrates the main entities structure of the Copper Platform. It provides a visual representation of how different entities are related and interact with each other within the platform. > [!NOTE] > > The term "Account" used on the Copper Web Platform is referred to as "Portfolio" in the Copper API. ```mermaid theme={"system"} erDiagram organization ||--o{ portfolio : has portfolio ||--o{ wallet : has portfolio ||--o{ order : has portfolio ||--o{ loan : has organization ||--o{ crypto-address : has organization ||--o{ organization-member : has organization-member ||--|| user : has user ||--o{ identity : has identity { string email string apikey } wallet ||--o{ deposit-target : has ``` # Create staking order Source: https://developer.copper.co/guides/staking/create-staking-order copper-open-api-create-order-staking-order post /orders The `blockchainTransactionType` sets up the type of performed blockchain operation. Each currency has a set of available staking operations, which is shown in the table below. | Currency | Staking operations | | :- | :- | | ADA | pool-creation, stake-delegation, take-reward | | ALGO | register-offline, register-online | | ATOM | stake-delegation, stake-undelegation, take-reward | | AVAX | complete-withdrawal, stake-nomination, pool-creation, stake-complete-deposit, stake-delegation, stake-undelegation | | AXL | stake-delegation, stake-undelegation, take-reward | | BLD | stake-delegation, stake-undelegation, take-reward | | BNB | pool-creation, stake-delegation, stake-undelegation, unjail | | CCD | pool-creation, stake-delegation, stake-undelegation | | DIVI | stake-delegation | | DOT | chill, complete-withdrawal, stake-nomination, rebond-stake, stake-delegation, stake-undelegation | | ETH | pool-creation, stake-delegation | | HNT | pool-creation, stake-undelegation, transfer-stake | | INJ | stake-delegation, stake-undelegation, take-reward, transfer-stake | | KSM | chill, complete-withdrawal, stake-nomination, rebond-stake, stake-delegation, stake-undelegation | | NEAR | complete-withdrawal, stake-delegation, stake-undelegation | | POKT | stake-delegation, stake-undelegation | | ROSE | stake-delegation, stake-undelegation | | SOL | complete-withdrawal, stake-delegation, stake-undelegation | | ZIL | complete-withdrawal, stake-delegation, stake-undelegation, take-reward | # Get active stakes Source: https://developer.copper.co/guides/staking/get-active-stakes get /staking/active-stakes # Get outstanding stakes Source: https://developer.copper.co/guides/staking/get-outstanding-stakes get /staking/outstanding-stakes # Get pending stakes Source: https://developer.copper.co/guides/staking/get-pending-stakes get /staking/pending-stakes # Get staking reward orders Source: https://developer.copper.co/guides/staking/get-staking-reward-orders copper-open-api-get-orders-get-staking-rewards get /orders # Support Source: https://developer.copper.co/guides/support ## Check our docs Select `Command+I` on a Mac or `Ctrl+I`on Windows to start a chat with the developer portal AI assistant. To view digital assets, blockchains and exchanges supported by Copper in your region, go to [copper.co](https://copper.co). On the top navigation bar, select your region (for example, **Global** for Copper Markets (US) Inc.), and then go to **Ecosystem** > **Platform Connectivity**. ![Select your region](https://mintcdn.com/copperco/KAqbXhNOyX8lC9Q5/images/copperco_select_region.png?fit=max\&auto=format\&n=KAqbXhNOyX8lC9Q5\&q=85\&s=e19101a7fcc27567a65ffe9abb747272) ![Platform connectivity](https://mintcdn.com/copperco/KAqbXhNOyX8lC9Q5/images/copperco_platform_connectivity.png?fit=max\&auto=format\&n=KAqbXhNOyX8lC9Q5\&q=85\&s=c804276d753fe17281cd6b0b4b50ebb0) ## Contact Support If you are an existing Copper client, please contact your Copper Relationship Manager. Considering joining Copper? Email us at [hello@copper.co](mailto:hello@copper.co) or go to [copper.co](https://copper.co/) to book a demo. # How to set up Source: https://developer.copper.co/guides/webhooks/how-to-setup **1. Go to organisation settings** Navigate to Organisation settings > Webhooks. ![Organization Settings](https://mintcdn.com/copperco/8EIpazN_ergWo9kn/images/organization-settings.png?fit=max\&auto=format\&n=8EIpazN_ergWo9kn\&q=85\&s=fa7b207355df39a1c006299dd2271657) **2. Create new webhook** Specify the URL where you want to receive notifications and select the events you want to subscribe to. > [!NOTE] > > The URL must be accessible from the public internet. If you want to use HMAC-SHA256 validation, the Platform will generate a secret for you. If you want to use ECDSA validation, ask your account manager for more information. You can also define from which portfolios you want to receive webhooks. ![New Webhook Form](https://mintcdn.com/copperco/MEHd-R3f5V2xF5ZW/images/webhook-form.svg?fit=max\&auto=format\&n=MEHd-R3f5V2xF5ZW\&q=85\&s=5b5ccf1188f081ca29469fcad117010f) **3. All done!** You can now receive notifications about events occurring in the system. If you missed any events, you can redeliver them using the Copper Platform. # Introduction Source: https://developer.copper.co/guides/webhooks/introduction The Copper Platform has a built-in webhook system to subscribe your service to specific events. This allows you to receive notifications about the events that occur in the system. Requests are sent to the webhook URL that you specify when creating a subscription. The webhook URL must be accessible from the internet and respond with a `200 OK` status code to confirm that the webhook was received. ``` POST https://your-domain.com/webhook/path ``` ### Headers | Header | Description | | :- | :- | | `X-Signature` | Signature of the request | | `X-Timestamp` | Timestamp of the request in Unix Timestamp format (in milliseconds) | | `X-Id` | The identifier of the webhook subscription | ### Body # Validate signature Source: https://developer.copper.co/guides/webhooks/validate-signature To validate the signature, you need to use the `X-Signature` header and the request body. **1. Concatenate the following strings:** * Value of the `X-Timestamp` header * `eventId` from the body of the request * All fields of the request body For example: `1730482675607b17c862a961fbba3a02af42a7de6e643{"eventId": "b17c862a961fbba3a02af42a7de6e643", "event": "deposit-created", "subscriptionId": "61fbba3a02af4", "payload": {"baseCurrency": "BTC"}}` **2. Generate the expected signature** The Platform uses 2 types of signatures depending on your choice when creating a subscription: | HMAC-SHA256 Validation | ECDSA Validation | | :- | :- | | 1. Sign the concatenated string with your API Secret using the HMAC SHA256 method. 2. Encode the generated signature in hexadecimal format. | 1. Compute the SHA-256 hash of the concatenated string. 2. Use the ECDSA Public Key to verify the signature. 3. Encode the generated signature in hexadecimal format. | **3. Compare the generated signature with the X-Signature header** **4. Validate IP Address** You can additionally validate the IP address of the request to ensure that the request is coming from the expected source. The Copper Platform sends webhooks from the following IP addresses: `63.33.117.167`, `99.80.177.29`, `52.215.155.205`. Please be aware that these addresses are only used for the Production environment and can change in the future. # Webhook events Source: https://developer.copper.co/guides/webhooks/webhook-event ### Organization & API Keys | Event-type | Description | Object | | :- | :- | :- | | `member-created` | Team member is added | [OrganizationMember](/guides/webhooks/objects/organization-member) | | `member-deactivated` | Team member is deactivated | [OrganizationMember](/guides/webhooks/objects/organization-member) | | `member-updated` | Team member is updated | [OrganizationMember](/guides/webhooks/objects/organization-member) | | `api-key-generated` | A new API Key was created | [User](/guides/webhooks/objects/user) | ### Address Book | Event-type | Description | Object | | :- | :- | :- | | `crypto-address-created` | A new address added | [CryptoAddressCreated](/guides/webhooks/objects/crypto-address-created) | | `crypto-address-deactivated` | An address deactivated | [CryptoAddressDeactivated](/guides/webhooks/objects/crypto-address-deactivated) | | `crypto-address-approved` | A new address approved | [CryptoAddress](/guides/webhooks/objects/crypto-address) | | `crypto-address-declined` | A new address declined | [CryptoAddress](/guides/webhooks/objects/crypto-address) | | `crypto-address-updated` | An address updated | [CryptoAddressUpdated](/guides/webhooks/objects/crypto-address-updated) | | `crypto-address-travel-rule-info-updated` | Travel Rule info updated | [TravelRuleInfoUpdatedEvent](/guides/webhooks/objects/travel-rule-updated) | ### Deposits & Withdrawals | Event-type | Description | Object | | :- | :- | :- | | `deposit-created` | Deposit order is created | [Order](/guides/webhooks/objects/order) | | `deposit-completed` | Deposit order is completed | [Order](/guides/webhooks/objects/order) | | `withdraw-created` | Withdraw order is created | [Order](/guides/webhooks/objects/order) | | `withdraw-completed` | Withdraw order is completed | [Order](/guides/webhooks/objects/order) | | `withdraw-failed` | Withdraw order failed | [Order](/guides/webhooks/objects/order) | | `withdraw-transaction-sent` | Withdraw order is sent to blockchain | [Order](/guides/webhooks/objects/order) | | `order-master-password-required` | Master password is required | [Order](/guides/webhooks/objects/order) | | `order-completed` | Order is completed (no filtering by order type; all order types (deposits, withdrawals, buy, sell, etc.) are included) | [Order](/guides/webhooks/objects/order) | ### ClearLoop | Event-type | Description | Object | | :- | :- | :- | | `clearloop-delegation-created` | Delegation order is created | [Order](/guides/webhooks/objects/order) | | `clearloop-undelegation-created` | Undelegation order is created | [Order](/guides/webhooks/objects/order) | | `clearloop-delegation-completed` | Delegation order is completed | [Order](/guides/webhooks/objects/order) | | `clearloop-undelegation-completed` | Undelegation order is completed | [Order](/guides/webhooks/objects/order) | | `clearloop-delegation-failed` | Delegation order failed | [Order](/guides/webhooks/objects/order) | | `clearloop-undelegation-failed` | Undelegation order failed | [Order](/guides/webhooks/objects/order) | | `clearloop-undelegation-blocked` | Undelegation order is blocked | [UndelegationRestriction](/guides/webhooks/objects/undelegation-restriction) | | `clearloop-undelegation-unblocked` | Undelegation order is unblocked | [UndelegationRestriction](/guides/webhooks/objects/undelegation-restriction) | | `clearloop-delegation-blocked` | Delegation order is blocked | [DelegationRestriction](/guides/webhooks/objects/undelegation-restriction) | | `clearloop-delegation-unblocked` | Delegation order is unblocked | [DelegationRestriction](/guides/webhooks/objects/delegation-restriction) |