Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

DSL Reference

The Conditions DSL (Domain-Specific Language) is how you express what tokens to find and what conditions they must match. It's a JSON format that gets validated and compiled to safe, parameterized SQL.

Overview

A DSL condition is a JSON object with these properties:

{
  "target": "tokens",          // Required: what to query (only "tokens" for now)
  "select": [...],             // Optional: which fields to return
  "joins": [...],              // Optional: additional data to join
  "derived_joins": [...],      // Optional: computed metrics from trades
  "where": {...},              // Optional: filter conditions
  "order_by": [...],           // Optional: sort order
  "limit": 100                 // Optional: max results (capped at 500)
}

Queryable Data

tokens
Base token data: mint address, symbol, metadata URL, creation time, creator, platform type.
Example: tokens.symbol, tokens.mint_address
token_metrics
Computed metrics: price, market cap, holder count, ATH values, graduation status.
Example: token_metrics.holder_count, token_metrics.mc_lamports
trades
Trade events. Used with 'exists' to check if certain trades occurred.
Example: exists check for large buys
derived
Aggregated values computed from trades over a time window.
Example: derived.min_price_sol, derived.max_price_sol, derived.trade_count

Available Fields

Token Fields (tokens.*)

FieldTypeDescription
tokens.mint_addressstringUnique token identifier
tokens.symbolstringToken symbol (e.g., PEPE)
tokens.meta_urlstringMetadata URL
tokens.created_timestampnumberUnix timestamp of creation
tokens.created_blocknumberBlock number of creation
tokens.creator_addressstringCreator's wallet address
tokens.bonding_curve_addressstringBonding curve address
tokens.platform_typestringPlatform type

Token Metrics Fields (token_metrics.*)

Requires joins: ["token_metrics"].

FieldTypeDescription
token_metrics.price_lamportsnumberCurrent price in lamports
token_metrics.mc_lamportsnumberMarket cap in lamports
token_metrics.holder_countnumberNumber of holders
token_metrics.ath_price_lamportsnumberAll-time high price
token_metrics.ath_mc_lamportsnumberAll-time high market cap
token_metrics.ath_timestampnumberWhen ATH was reached
token_metrics.graduate_timestampnumberWhen token graduated (null if not)
token_metrics.updated_timestampnumberLast metrics update

Derived Fields (derived.*)

Requires a derived_joins entry.

FieldDescription
derived.pct_rangePrice range % (from trade_price_range_1h)
derived.min_price_solMinimum price in SOL (from trade_price_window)
derived.max_price_solMaximum price in SOL (from trade_price_window)
derived.volume_solTrading volume in SOL (from trade_price_window)
derived.trade_countNumber of trades (from trade_price_window)

Trade Fields (trades.*)

Only available inside exists conditions.

FieldTypeDescription
trades.sidestring"buy" or "sell"
trades.sol_amount_lamportsnumberTrade amount in lamports
trades.token_amountnumberToken amount traded
trades.price_lamportsnumberPrice at time of trade
trades.block_timestampnumberWhen trade occurred
trades.wallet_addressstringTrader's wallet

Joins

Regular Joins

{
  "target": "tokens",
  "joins": ["token_metrics"]
}

Currently only token_metrics is supported.

Derived Joins

Derived joins compute aggregated values from trade data. The on clause is required and must be exactly as shown:

Price Range (1h)
Compute the price range percentage over the last hour
{
  "target": "tokens",
  "derived_joins": [
    {
      "derived": "trade_price_range_1h",
      "on": {
        "left": "tokens.mint_address",
        "right": "derived.mint_address"
      }
    }
  ]
}
Price Window
Get min/max price and volume for a time window
{
  "target": "tokens",
  "derived_joins": [
    {
      "derived": "trade_price_window",
      "window": "1h",
      "on": {
        "left": "tokens.mint_address",
        "right": "derived.mint_address"
      }
    }
  ]
}

Available windows: 5m, 15m, 1h (default), 4h, 24h

Where Operators

Comparison: cmp

Compare a field to a literal value.

Holder count threshold
Find tokens with at least 100 holders
{
  "op": "cmp",
  "cmp": ">=",
  "left": {
    "type": "field",
    "field": "token_metrics.holder_count"
  },
  "right": 100
}

Comparison operators: <, <=, >, >=, =, !=

Comparison: cmp_field

Compare two fields directly.

Price below ATH
Find tokens where current price is below ATH
{
  "op": "cmp_field",
  "cmp": "<",
  "left": {
    "type": "field",
    "field": "token_metrics.price_lamports"
  },
  "right": {
    "type": "field",
    "field": "token_metrics.ath_price_lamports"
  }
}

Comparison: cmp_scaled_field

Compare a field to another field multiplied by a scale factor.

Dropped 70% from ATH
Find tokens at 30% or less of their ATH market cap
{
  "op": "cmp_scaled_field",
  "cmp": "<=",
  "left": {
    "type": "field",
    "field": "token_metrics.mc_lamports"
  },
  "right": {
    "type": "field",
    "field": "token_metrics.ath_mc_lamports"
  },
  "scale": 0.3
}

Range Sugar: min and max

Shorthand for common >= and <= comparisons.

Minimum market cap
Market cap must be at least 1000 lamports
{
  "op": "min",
  "ref": {
    "type": "field",
    "field": "token_metrics.mc_lamports"
  },
  "value": 1000
}
Maximum holder count
Holder count must be at most 500
{
  "op": "max",
  "ref": {
    "type": "field",
    "field": "token_metrics.holder_count"
  },
  "value": 500
}

String Matching: ilike and like

Case-insensitive pattern matching.

Symbol contains 'wif'
Find tokens with 'wif' anywhere in the symbol
{
  "op": "ilike",
  "ref": {
    "type": "field",
    "field": "tokens.symbol"
  },
  "pattern": "%wif%"
}

Pattern syntax:

  • % matches any sequence of characters
  • _ matches any single character

NULL Checks: is_null and is_not_null

Not graduated
Find tokens that haven't graduated yet
{
  "op": "is_null",
  "ref": {
    "type": "field",
    "field": "token_metrics.graduate_timestamp"
  }
}
Has graduated
Find tokens that have graduated
{
  "op": "is_not_null",
  "ref": {
    "type": "field",
    "field": "token_metrics.graduate_timestamp"
  }
}

Time Comparison: now_minus_seconds_cmp

Compare a timestamp field to "now minus X seconds".

Created in last 2 hours
Find tokens created within the last 7200 seconds
{
  "op": "now_minus_seconds_cmp",
  "ref": {
    "type": "field",
    "field": "tokens.created_timestamp"
  },
  "cmp": ">=",
  "seconds": 7200
}

Existence Check: exists

Check if related records exist in trades.

Large buy detected
Find tokens with at least one buy over 10 SOL in the last 30 minutes
{
  "op": "exists",
  "source": "trades",
  "join_on": {
    "left": "tokens.mint_address",
    "right": "trades.mint_address"
  },
  "where": {
    "op": "and",
    "args": [
      {
        "op": "cmp",
        "cmp": "=",
        "left": {
          "type": "field",
          "field": "trades.side"
        },
        "right": "buy"
      },
      {
        "op": "cmp",
        "cmp": ">=",
        "left": {
          "type": "field",
          "field": "trades.sol_amount_lamports"
        },
        "right": 10000000000
      },
      {
        "op": "now_minus_seconds_cmp",
        "ref": {
          "type": "field",
          "field": "trades.block_timestamp"
        },
        "cmp": ">=",
        "seconds": 1800
      }
    ]
  }
}

Logical Operators: and, or, not

Combine multiple conditions.

Multiple conditions
Find new tokens with growing holders
{
  "op": "and",
  "args": [
    {
      "op": "now_minus_seconds_cmp",
      "ref": {
        "type": "field",
        "field": "tokens.created_timestamp"
      },
      "cmp": ">=",
      "seconds": 3600
    },
    {
      "op": "cmp",
      "cmp": ">=",
      "left": {
        "type": "field",
        "field": "token_metrics.holder_count"
      },
      "right": 50
    }
  ]
}

Complete Examples

New Token Discovery

Find tokens created in the last hour with at least 50 holders:

New tokens with traction
{
  "target": "tokens",
  "joins": [
    "token_metrics"
  ],
  "where": {
    "op": "and",
    "args": [
      {
        "op": "now_minus_seconds_cmp",
        "ref": {
          "type": "field",
          "field": "tokens.created_timestamp"
        },
        "cmp": ">=",
        "seconds": 3600
      },
      {
        "op": "cmp",
        "cmp": ">=",
        "left": {
          "type": "field",
          "field": "token_metrics.holder_count"
        },
        "right": 50
      }
    ]
  },
  "order_by": [
    {
      "field": "token_metrics.holder_count",
      "dir": "desc"
    }
  ],
  "limit": 20
}

Sideways Detection

Find tokens trading in a tight range (max price within 1.2x of min):

Sideways tokens
{
  "target": "tokens",
  "derived_joins": [
    {
      "derived": "trade_price_window",
      "window": "1h",
      "on": {
        "left": "tokens.mint_address",
        "right": "derived.mint_address"
      }
    }
  ],
  "where": {
    "op": "cmp_scaled_field",
    "cmp": "<=",
    "left": {
      "type": "field",
      "field": "derived.max_price_sol"
    },
    "right": {
      "type": "field",
      "field": "derived.min_price_sol"
    },
    "scale": 1.2
  },
  "limit": 50
}

Dip from ATH

Find graduated tokens that dropped to 30% of their ATH:

Dip buying opportunity
{
  "target": "tokens",
  "joins": [
    "token_metrics"
  ],
  "where": {
    "op": "and",
    "args": [
      {
        "op": "is_not_null",
        "ref": {
          "type": "field",
          "field": "token_metrics.graduate_timestamp"
        }
      },
      {
        "op": "cmp_scaled_field",
        "cmp": "<=",
        "left": {
          "type": "field",
          "field": "token_metrics.mc_lamports"
        },
        "right": {
          "type": "field",
          "field": "token_metrics.ath_mc_lamports"
        },
        "scale": 0.3
      }
    ]
  },
  "limit": 100
}

Limitations

AspectLimitation
TargetOnly "tokens" is supported
JoinsOnly ["token_metrics"]
Derived joinsMaximum 1 per condition
ResultsCapped at 500 per evaluation
TablesCannot query arbitrary tables

Security

Your conditions are safe because:

  • Validated: Every field and operator is checked against a whitelist
  • Parameterized: All values become SQL parameters, not string concatenation
  • No raw SQL: You write JSON, the system compiles it safely

For details on evaluation behavior, see How It Works.