Skip to Content
RestStrategies

Strategies

Base: /api/v1

Request bodies that include userId expect your external user id—the id your client uses to identify that user in your own system (for example client-user-001). See Users — Identity model.

Create strategies

  • POST /strategies/createStrategyDcaBuy
  • POST /strategies/createStrategyDcaSell
  • POST /strategies/createStrategyVolumeBuy
  • POST /strategies/createStrategyVolumeSell

These endpoints require integration 2FA setup and can return 403.

Token fields such as inputToken and outputToken should be token addresses for the selected chain.

  • EVM example: 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913
  • Solana example: So11111111111111111111111111111111111111112

balanceUsed is raw amount in the token’s smallest unit, not human-formatted amount.

  • Example for 6-decimal token (USDC): 1 USDC = "1000000"
  • Example for 9-decimal token (SOL-like): 1 token = "1000000000"

Strategy create — shared options

All four create routes share a base body shape. Sell routes may include poolDepositId (the user’s pool deposit on that chain); OpenAPI marks it optional, but sell flows typically need an existing deposit. See endpoint examples below for curl / Node / SDK; each example includes a few optional fields beyond the minimum.

Required fields by route

RouteAlways requiredSell-only (recommended)
createStrategyDcaBuyuserId, chainId, inputToken, outputToken, tokenAddress, balanceUsed, orders, dcaFrequency
createStrategyDcaSellSame as DCA buypoolDepositId
createStrategyVolumeBuyuserId, chainId, inputToken, outputToken, tokenAddress, balanceUsed, percentage
createStrategyVolumeSellSame as volume buypoolDepositId

Shared optional fields (all four creates)

FieldTypeNotes
isSmartGasOnbooleanDefault false
gasThresholdnumberDefault 50 when smart gas is on
autoClaimbooleanWhen true, set receiverAddress
receiverAddressstringClaim destination when autoClaim is enabled
routeProtectionbooleanReject swaps that deviate beyond the configured oracle threshold (default 10% for strategies)
triggerMarketCapstringDefault "1" when using market-cap triggers
triggerPricestringPrice trigger (use with triggerType)
triggerType"marketCap" or "price"Trigger mode
scheduledStartAtnumberUnix seconds UTC; omit to start immediately

Solana routing (optional)

FieldWhenValues
swapKindSolana chains"jupiter", "titan", or "pool"
poolKindswapKind === "pool""raydium", "meteora", "pumpswap"
poolAddressswapKind === "pool"On-chain pool address

DCA-only optional fields

FieldNotes
variableDcaAmountVary order size between rounds
variableDcaAmountValueInteger 20–80 (percent spread)
variableDcaFrequencyRequires dcaFrequency >= 2 and orders > 1
variableDcaFrequencyValueInteger 20–80

Volume-only optional fields

FieldNotes
maxTransactionValueCap per swap (raw units or numeric string)
minTransactionValueUSD floor; must be less than or equal to max when both set
volumeAccumulatorSizeBatch 2–10 volume events into one swap
volumeExclusionAddressesUp to ~150 wallet addresses to ignore as volume
skipMevLikeTradesFilter suspicious volume patterns
excludeSonarExecutorsExclude Sonar executor wallets from triggers

Update strategies

  • POST /strategies/setStrategyBuyDCA
  • POST /strategies/setStrategySellDCA
  • POST /strategies/setStrategyBuyVolume
  • POST /strategies/setStrategySellVolume

All four routes require integration 2FA and return 403 when 2FA is not enabled. They update an existing strategy — use the route that matches the strategy type and side (buy vs sell). Returns 200 with the updated strategy (not 201).

Unlike create, update bodies identify the strategy with strategyId, poolId, and poolDepositId. Token addresses are not sent again. There is no autoClaim, receiverAddress, or Solana swapKind routing on set routes.

Use GET /strategies/{strategyId} or POST /strategies/getStrategies to read current poolId, poolDepositId, and sizing fields before calling set.

Required fields by route

RouteAlways required
setStrategyBuyDCAuserId, poolDepositId, poolId, strategyId, chainId, balanceUsed
setStrategySellDCASame as buy DCA
setStrategyBuyVolumeuserId, poolDepositId, poolId, strategyId, chainId, balanceUsed
setStrategySellVolumeSame as buy volume

Sizing fields (orders, dcaFrequency for DCA; percentage for volume) are optional — omit to leave unchanged.

Shared optional fields (all four updates)

FieldTypeNotes
ordersnumberDCA only; omit unchanged
dcaFrequencynumberDCA only; omit unchanged
percentagenumberVolume only; omit unchanged
isSmartGasOnbooleanDefault false
gasThresholdnumberDefault 50 when smart gas is on
routeProtectionbooleanReject swaps that deviate beyond the configured oracle threshold (default 10% for strategies)
triggerMarketCapstringDefault "1" when using market-cap triggers
triggerPricestringPrice trigger (use with triggerType)
triggerType"marketCap" or "price"Trigger mode
scheduledStartAtnumber or nullUnix seconds UTC; omit to leave unchanged, null clears schedule

DCA-only optional fields

Same as create: variableDcaAmount, variableDcaAmountValue, variableDcaFrequency, variableDcaFrequencyValue.

Volume-only optional fields

FieldNotes
maxTransactionValueCap per swap; omit unchanged
minTransactionValueUSD floor; must be less than or equal to max when both set
volumeAccumulatorSizeInteger 2–10; omit unchanged, null removes batching

Typical errors: 400 if the strategy type does not match the route, sizing fields are invalid, or the strategy cannot be updated; 404 if the user or strategy is not found.

Read strategies

  • POST /strategies/getDashBoardStats
    • Returns users count and strategies count.
  • GET /strategies
    • List all strategies for the integration with filters and pagination.
    • Query filters: chainId, status (active | suspended | paused | completed), category (buy | sell | range), strategyMethod (dca | volume), page (default 1), pageSize (default 50, max 100), sortBy (latest | oldest).
  • POST /strategies/getStrategies
    • List strategies for one user with the same filters as GET /strategies, plus required userId in the body.
  • POST /strategies/getFilteredStrategies
    • Filtered response including totals and gained amount.
    • Body filters: category (buy | sell | range | all), status (active | completed | paused), strategyMethod (dca | volume | all), optional search, value (highest | lowest), pagination.
  • GET /strategies/{strategyId}
    • Get one strategy by id.

Lifecycle actions

URL routes identify the strategy in the path (strategyId is the numeric database id as a string). Body routes require userId (your external user id) plus strategyId (number), except bulk/async routes that only need userId.

Routes marked 2FA require at least one portal user on the integration to have two-factor authentication enabled; otherwise the API returns 403.

Which lifecycle route to use

Route2FAEffect
POST /strategies/{strategyId}/haltNoPause execution (paused); strategy balances stay allocated
POST /strategies/{strategyId}/archiveNoArchive strategy, zero strategy balances, clear volume accumulator
POST /strategies/removeStrategyNoSame as archive — body { userId, strategyId }
POST /strategies/disableStrategyNoPause and zero strategy balances (integration-scoped ownership check)
POST /strategies/suspendStrategyYesSet status suspended; active strategies only
POST /strategies/resumeStrategyYesSet status active; suspended strategies only
POST /strategies/stopStrategyYesMark completed (terminal), zero strategy balances
POST /strategies/changeBalanceYesAdd buy- or sell-side balance on volume strategies; requires idempotencyKey
POST /strategies/duplicateStrategyYesClone settings into a new strategy; returns new strategy id
POST /strategies/removeStrategiesYesBulk archive by numeric ids; returns per-id results
POST /strategies/disableAllStrategiesYesAsync — pause all active strategies for the user ({ started: true })
POST /strategies/removeAllStrategiesYesAsync — complete and archive all non-archived strategies for the user

Typical status codes

  • 200 or 201: success
  • 400: invalid request or invalid strategy transition
  • 401: invalid or missing API key/secret
  • 403: 2FA required (create, update, and lifecycle routes in tables above) or ownership restriction on some routes
  • 404: user, pool, or strategy not found
  • 409: idempotency conflict on changeBalance

Endpoint Examples

Examples below show realistic payloads with a few optional fields. Omit any option you do not need; only the required fields are mandatory.

POST /strategies/createStrategyDcaBuy

curl -X POST "https://partners.sonar.trade/api/v1/strategies/createStrategyDcaBuy" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","tokenAddress":"0x4200000000000000000000000000000000000006","balanceUsed":"100000000","orders":5,"dcaFrequency":60,"chainId":8453,"inputToken":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","outputToken":"0x4200000000000000000000000000000000000006","routeProtection":true,"variableDcaAmount":true,"variableDcaAmountValue":20}'

POST /strategies/createStrategyDcaSell

curl -X POST "https://partners.sonar.trade/api/v1/strategies/createStrategyDcaSell" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","poolDepositId":12345,"tokenAddress":"0x4200000000000000000000000000000000000006","balanceUsed":"50000000","orders":4,"dcaFrequency":60,"chainId":8453,"inputToken":"0x4200000000000000000000000000000000000006","outputToken":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","routeProtection":true,"scheduledStartAt":1735689600}'

POST /strategies/createStrategyVolumeBuy

curl -X POST "https://partners.sonar.trade/api/v1/strategies/createStrategyVolumeBuy" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","tokenAddress":"So11111111111111111111111111111111111111112","balanceUsed":"1000000000","percentage":20,"chainId":1399811149,"inputToken":"Es9vMFrzaCERmJfrF4H2TUN324j6nU5zThTcACLqx4pX","outputToken":"So11111111111111111111111111111111111111112","swapKind":"jupiter","maxTransactionValue":"50000000","skipMevLikeTrades":true}'

POST /strategies/createStrategyVolumeSell

curl -X POST "https://partners.sonar.trade/api/v1/strategies/createStrategyVolumeSell" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","poolDepositId":67890,"tokenAddress":"So11111111111111111111111111111111111111112","balanceUsed":"1000000000","percentage":15,"chainId":1399811149,"inputToken":"So11111111111111111111111111111111111111112","outputToken":"Es9vMFrzaCERmJfrF4H2TUN324j6nU5zThTcACLqx4pX","routeProtection":true,"volumeAccumulatorSize":5,"excludeSonarExecutors":true}'

POST /strategies/setStrategyBuyDCA

Requires 2FA. Body includes strategyId, poolId, and poolDepositId from the existing strategy. See Update strategies.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/setStrategyBuyDCA" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","poolDepositId":12345,"poolId":100,"strategyId":67890,"chainId":8453,"balanceUsed":"100000000","orders":5,"dcaFrequency":60,"routeProtection":true,"variableDcaAmount":true,"variableDcaAmountValue":20}'

POST /strategies/setStrategySellDCA

Requires 2FA. Same body shape as buy DCA update; use the sell strategy’s strategyId, poolId, and poolDepositId.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/setStrategySellDCA" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","poolDepositId":12345,"poolId":100,"strategyId":67890,"chainId":8453,"balanceUsed":"50000000","orders":4,"dcaFrequency":60,"routeProtection":true,"scheduledStartAt":1735689600}'

POST /strategies/setStrategyBuyVolume

Requires 2FA. Body includes strategyId, poolId, and poolDepositId. Pass scheduledStartAt: null to clear a scheduled start.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/setStrategyBuyVolume" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","poolDepositId":67890,"poolId":200,"strategyId":11111,"chainId":1399811149,"balanceUsed":"1000000000","percentage":20,"maxTransactionValue":"50000000","volumeAccumulatorSize":5}'

POST /strategies/setStrategySellVolume

Requires 2FA. Same body shape as buy volume update.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/setStrategySellVolume" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","poolDepositId":67890,"poolId":200,"strategyId":11111,"chainId":1399811149,"balanceUsed":"1000000000","percentage":15,"routeProtection":true,"volumeAccumulatorSize":null}'

POST /strategies/getStrategies

Response shape matches GET /strategies pagination: StrategiesPaginatedResponse (strategies, totalCount, page, pageSize, numberOfPages).

Example response (StrategiesPaginatedResponse)
{
  "strategies": [
    {
      "id": 1,
      "strategyId": "strat_abc123",
      "chainId": 8453,
      "status": "active",
      "category": "buy",
      "type": "dca",
      "poolDepositId": 101,
      "orders": 5,
      "dcaFrequency": 60,
      "pool": {
        "id": 1,
        "name": "USDC",
        "symbol": "USDC",
        "tokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
        "decimals": 6,
        "tokenPrice": "1.00"
      }
    }
  ],
  "totalCount": 1,
  "page": 1,
  "pageSize": 20,
  "numberOfPages": 1
}
curl -X POST "https://partners.sonar.trade/api/v1/strategies/getStrategies" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","chainId":8453,"page":1,"pageSize":20,"status":"active","strategyMethod":"dca"}'

POST /strategies/getDashBoardStats

Example response (DashboardStats)
{
  "usersCount": 42,
  "strategiesCount": 156
}
curl -X POST "https://partners.sonar.trade/api/v1/strategies/getDashBoardStats" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{}'

POST /strategies/getFilteredStrategies

Response is FilteredStrategiesResponse: optional top-level totals, optional stats (FilteredStrategiesEmptyStats — counts when filters yield no rows), strategies as FilteredStrategyItem[] (strategy fields plus optional gainedAmountInUSD, progress, and transactions as FilteredStrategyTransaction[], not full StrategyTransaction), gainedAmountByChain, and pagination (includes hasNextPage / hasPreviousPage).

Example response (FilteredStrategiesResponse)
{
  "totalUserStrategies": 10,
  "activeStrategiesCount": 4,
  "stats": {
    "totalUserStrategies": 10,
    "activeStrategiesCount": 4,
    "filteredStrategiesCount": 3
  },
  "strategies": [
    {
      "id": 1,
      "strategyId": "strat_abc123",
      "chainId": 8453,
      "status": "active",
      "category": "buy",
      "type": "dca",
      "poolDepositId": 101,
      "gainedAmountInUSD": "95.00",
      "progress": 0.42,
      "pool": {
        "id": 1,
        "name": "USDC",
        "symbol": "USDC",
        "tokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
        "decimals": 6,
        "tokenPrice": "1.00"
      },
      "transactions": [
        {
          "id": 9001,
          "amount": "1000000",
          "type": "buy",
          "strategyId": 1,
          "amountInUSD": "1.00",
          "gainedAmountInUSD": "0.50",
          "chainId": 8453,
          "createdAt": "2026-03-20T10:00:00.000Z",
          "txHash": "0xabc123def456",
          "pool": {
            "id": 1,
            "name": "USDC",
            "symbol": "USDC",
            "tokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
            "decimals": 6
          },
          "Transaction": {
            "hash": "0xabc123def456"
          }
        }
      ]
    }
  ],
  "gainedAmountByChain": {
    "8453": {
      "gainedNative": "0.05",
      "gainedNativeValue": "120.50",
      "gainedTokens": "1000000000",
      "gainedTokensValue": "95.00",
      "soldTokens": "0",
      "soldTokensValue": "0",
      "soldNative": "0",
      "soldNativeValue": "0"
    }
  },
  "pagination": {
    "totalItems": 3,
    "totalPages": 1,
    "currentPage": 1,
    "pageSize": 20,
    "hasNextPage": false,
    "hasPreviousPage": false
  }
}
curl -X POST "https://partners.sonar.trade/api/v1/strategies/getFilteredStrategies" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","page":1,"pageSize":20,"category":"all","status":"active","strategyMethod":"all"}'

GET /strategies

Example response (StrategiesPaginatedResponse)
{
  "strategies": [
    {
      "id": 1,
      "strategyId": "strat_abc123",
      "chainId": 8453,
      "status": "active",
      "category": "buy",
      "type": "dca",
      "poolDepositId": 101,
      "orders": 5,
      "dcaFrequency": 60,
      "pool": {
        "id": 1,
        "name": "USDC",
        "symbol": "USDC",
        "tokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
        "decimals": 6,
        "tokenPrice": "1.00"
      }
    }
  ],
  "totalCount": 1,
  "page": 1,
  "pageSize": 20,
  "numberOfPages": 1
}
curl -X GET "https://partners.sonar.trade/api/v1/strategies?page=1&pageSize=20&chainId=8453" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>"

GET /strategies/:strategyId

Example response (Strategy)
{
  "id": 1,
  "strategyId": "strat_abc123",
  "chainId": 8453,
  "status": "active",
  "category": "buy",
  "type": "dca",
  "poolDepositId": 101,
  "orders": 5,
  "dcaFrequency": 60,
  "pool": {
    "id": 1,
    "name": "USDC",
    "symbol": "USDC",
    "tokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
    "decimals": 6
  }
}
curl -X GET "https://partners.sonar.trade/api/v1/strategies/strategy-id" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>"

POST /strategies/:strategyId/halt

curl -X POST "https://partners.sonar.trade/api/v1/strategies/strategy-id/halt" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>"

POST /strategies/:strategyId/archive

curl -X POST "https://partners.sonar.trade/api/v1/strategies/strategy-id/archive" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>"

POST /strategies/removeStrategy

Archives the strategy (same outcome as POST /strategies/{strategyId}/archive). Body: userId, strategyId (number).

curl -X POST "https://partners.sonar.trade/api/v1/strategies/removeStrategy" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","strategyId":12345}'

POST /strategies/disableStrategy

Pauses the strategy and zeros strategy-side balances. Body: userId, strategyId.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/disableStrategy" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","strategyId":12345}'

POST /strategies/suspendStrategy

Requires 2FA. Only active strategies can be suspended. Body: userId, strategyId.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/suspendStrategy" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","strategyId":12345}'

POST /strategies/resumeStrategy

Requires 2FA. Only suspended strategies can be resumed. Body: userId, strategyId.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/resumeStrategy" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","strategyId":12345}'

POST /strategies/stopStrategy

Requires 2FA. Marks the strategy completed (terminal). Body: userId, strategyId.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/stopStrategy" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","strategyId":12345}'

POST /strategies/changeBalance

Requires 2FA. Volume strategies only — not supported for DCA. Provide at least one of balanceBuyUsed or balanceSellUsed (raw units to add) and a unique idempotencyKey. Buy strategies accept buy-side only; sell strategies accept sell-side only.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/changeBalance" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","strategyId":12345,"balanceBuyUsed":"50000000","idempotencyKey":"top-up-2025-06-23-001"}'

POST /strategies/duplicateStrategy

Requires 2FA. Creates a new strategy with the same settings as the source. Returns the new strategy id. Body: userId, strategyId.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/duplicateStrategy" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","strategyId":12345}'

POST /strategies/removeStrategies

Requires 2FA. Bulk archive by numeric strategy ids. Response includes removed, failed, skippedArchived, and a summary message.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/removeStrategies" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","ids":[12345,12346,12347]}'

POST /strategies/disableAllStrategies

Requires 2FA. Starts a background job that pauses all active strategies for the user. Returns { started: true } immediately — poll strategy lists to confirm completion.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/disableAllStrategies" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001"}'

POST /strategies/removeAllStrategies

Requires 2FA. Starts a background job that completes and archives all non-archived strategies for the user. Returns { started: true } immediately.

curl -X POST "https://partners.sonar.trade/api/v1/strategies/removeAllStrategies" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001"}'