Understanding campaign configs

Discover the schemas that describe valid inputs for every Merkl campaign type

Every Merkl campaign is created from a configuration: a single JSON object that fully describes it. Before you can craft a campaign, you need to know what goes into that object and how to fill it in — this page walks through its structure and the schemas that tell you exactly what each part expects.

For a higher-level overview of what a configuration is, see the campaign configuration guide.

Configuration structure

A configuration combines a set of standard fields — the same on every campaign — with a few structured inputs whose shape depends on the choices you make.

Standard fields

These fields are present on most campaigns and take simple values:

  • creator: The address managing the campaign
  • rewardToken: The address of the token distributed as rewards
  • distributionChainId: The chain ID where rewards are distributed
  • computeChainId: The chain ID where user activity is tracked (can differ from distributionChainId for cross-chain campaigns)
  • startTimestamp: The start date of the campaign (Unix timestamp)
  • endTimestamp: The end date of the campaign (Unix timestamp)
  • amount: The total amount of rewards to be distributed
  • blacklist: A list of addresses excluded from receiving rewards
  • whitelist: A list of addresses allowed to receive rewards (if set, all others are excluded)

You can use this converter to convert dates to Unix timestamps.

computeChainId is the chain whose state Merkl reads to compute rewards. distributionChainId is the chain on which rewards are distributed (and therefore where the createCampaign transaction is sent). They are often the same, but can differ for cross-chain incentive programs.

Structured inputs

The remaining fields are objects rather than simple values, and their accepted shape changes with the type you pick:

  • campaignType: the campaign type, together with the campaignTypeParameters specific to it
  • computeScoreParameters: the scoring method that turns user activity into reward shares
  • distributionMethodParameters: the distribution method that controls how the budget is spent over time

A concentrated-liquidity campaign expects different parameters than a token-holding one, and a fixed-APR distribution expects different settings than a Dutch auction. To know exactly what each one accepts, you read its schema.

Working with schemas

For every campaign type, distribution method, scoring method, hook, and processor, Merkl publishes a JSON Schema: a precise, machine-readable description of one input — which fields are required, what type each field is, and which values are accepted. The schemas are generated from the engine itself, so they always reflect exactly what is currently supported.

Reach for them whenever you want to:

  • Discover the campaign types your integration can use
  • Generate a UI that builds configurations dynamically
  • Validate a configuration locally before submitting it to the API

The easiest way to explore them is the schema explorer, which lets you browse and search every type visually. Programmatically, they live under the schemas tag of the API reference — the endpoints you'll reach for most when crafting a campaign are:

  • GET /v4/schemas/campaignType — every supported campaignType (e.g. 60 for ERC20, others for CLAMM, point programs, etc.), each with a short description and the chain it can run on.
  • GET /v4/schemas/campaignType/{campaignType} — the schema of the inputs expected for a given campaignType. Fields such as targetToken and campaign-type-specific parameters are documented here.
  • GET /v4/schemas/distributionMethod — the supported distributionMethod values (e.g. MAX_APR, FIX_REWARDS, etc.) and the settings each one accepts.
  • GET /v4/schemas/computeScoreMethod — the available scoring methods and the parameters they take.
  • GET /v4/schemas/processorType — the processors (boost, lock, vault wrappers, etc.) that can be plugged into a campaign.

A typical flow is:

  1. Pick a campaignType from /v4/schemas/campaignType.
  2. Read its schema to learn the shape of its campaignTypeParameters (or, for simple campaigns, top-level fields like targetToken).
  3. Pick a distributionMethod from /v4/schemas/distributionMethod and read the settings it expects.
  4. Assemble everything into a configuration — the complete example below shows the result.

The schemas are the source of truth: they evolve with the engine and always reflect what is currently supported. If a field is missing from the schema it is not (yet) supported; if a new field appears, it is safe to start using it.

Schema breakdown

Some fields appear across many campaign types and deserve a closer look. The sections below walk through the ones that most often need explaining.

Distribution methods

The distributionMethodParameters field defines how rewards are distributed over time.

Variable Reward Rate (Dutch Auction):

{
  "distributionMethod": "DUTCH_AUCTION"
}

Fixed APR:

{
  "distributionMethod": "FIX_APR",
  "distributionSettings": {
      "apr": "0.08",
      "targetToken": "0x...",
      "rewardTokenPricing": true,
      "targetTokenPricing": true
  }
}

Capped APR:

{
  "distributionMethod": "MAX_APR",
  "distributionSettings": {
      "apr": "1",
      "targetToken": "0x...",
      "rewardTokenPricing": true,
      "targetTokenPricing": true
  }
}

Understanding distribution settings parameters

rewardTokenPricing:

  • false: The campaign distributes a fixed amount of reward tokens per unit (or dollar) of liquidity provided
  • true: The campaign distributes a fixed dollar value of rewards per unit (or dollar) of liquidity provided

targetTokenPricing:

  • false: Rewards are calculated per unit of liquidity provided
  • true: Rewards are calculated per dollar of liquidity provided

We recommend using targetTokenPricing = true for most campaigns to ensure consistent reward distribution regardless of liquidity value fluctuations.

When both rewardTokenPricing = true and targetTokenPricing = true, the campaign pays a fixed APR.

For most campaign types (such as token holding campaigns), the targetToken address is automatically derived from the campaign configuration and doesn't need to be specified manually within the distributionSettings.

Understanding the APR value format

The apr value in distributionSettings represents different metrics depending on your pricing configuration:

Fixed APR (targetTokenPricing = true and rewardTokenPricing = true):

  • The value represents the target APR as a decimal
  • Example: "apr": "0.01" = 1% APR, "apr": "0.08" = 8% APR

Token-per-Dollar Rate (targetTokenPricing = true and rewardTokenPricing = false):

  • The value represents the number of reward tokens earned per dollar of liquidity per year
  • Example: "apr": "1" = 1 reward token per year per $1 of liquidity provided
    • For $1,000 in liquidity: ~2.74 tokens per day (1,000 ÷ 365)
  • To reward 1 token per day per $1,000 provided, use: "apr": "0.365"
    • Calculation: 1 token/day × 365 days = 365 tokens/year ÷ 1,000 dollars = 0.365 tokens per year per dollar

A complete example

Putting the standard fields and structured inputs together, here's a full configuration for an ERC20 token-holding campaign that pays a capped 8% APR:

{
  "campaignType": 60,
  "targetToken": "0xBdb9300b7CDE636d9cD4AFF00f6F009fFBBc8EE6",
  "computeChainId": 8453,
  "distributionChainId": 8453,
  "creator": "0xA9DdD91249DFdd450E81E1c56Ab60E1A62651701",
  "rewardToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  "startTimestamp": 1778259600,
  "endTimestamp": 1778864400,
  "amount": "1000000000",
  "distributionMethodParameters": {
    "distributionMethod": "MAX_APR",
    "distributionSettings": {
      "apr": "0.08",
      "rewardTokenPricing": true,
      "targetTokenPricing": true
    }
  }
}

This example is specific to an ERC20 campaign type (campaignType: 60). Other campaign types expect different campaignTypeParameters — always check the schema for the type you're targeting to know which fields are required.

With your configuration ready, the next step is to encode it into the payloads Merkl needs to preview and create your campaign — see Creating the payloads.