API for developers
Campaigns endpoint
List campaigns with live status and progress, or launch a package against a pair. Launching is irreversible.
GET /campaigns
GET https://www.dextrending.net/api/v1/campaigns Your campaigns, newest first, up to 100. Status and progress are recalculated on every request, so the values are current rather than cached.
{
"campaigns": [
{
"order_no": "CMP-TK4LPJDC84",
"package": "12 Hour Window",
"chain": "solana",
"token": {
"address": "Ai66LHZG9MCzg1WKdawwqduVAXpNDUuV8M3uyq5ppump",
"symbol": "CATE",
"name": "Catecoin",
"logo_url": "https://cdn.dexscreener.com/cms/images/...",
"pair_url": "https://dexscreener.com/solana/hmzvseemtzhhvznw9uwbag85hctmfnkbhzux16cy7ca3"
},
"hours": 12,
"status": "running",
"progress": 23,
"seconds_remaining": 33167,
"starts_at": "2026-08-21T15:29:43+00:00",
"ends_at": "2026-08-22T03:29:43+00:00"
}
],
"count": 1
} | Field | Type | Notes |
|---|---|---|
order_no | string | Public reference, use it in support tickets |
status | string | scheduled, running, completed or cancelled |
progress | integer | 0 to 100. Share of the paid window elapsed, not performance. |
seconds_remaining | integer | Until the window closes. 0 once completed. |
token.logo_url | string or null | Null when the token publishes no logo |
token.pair_url | string or null | The pair on Dexscreener |
POST /campaigns
POST https://www.dextrending.net/api/v1/campaigns Spends one available package against a pair.
This is irreversible. The package is consumed at the moment the campaign is created, including for a scheduled start. Validate the address with GET /token first.
Request body
{
"credit_id": 20,
"chain": "solana",
"address": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
"start_at": "asap",
"notes": "listing at 14:00 UTC"
} | Field | Required | Notes |
|---|---|---|
credit_id | Yes | From /packages, must be available |
chain | Yes | Must match the package chain_group |
address | Yes | Token contract address on that chain |
start_at | No | asap or ISO 8601 UTC. Max 30 days ahead. Defaults to now. |
notes | No | Free text, up to 1000 characters, visible to support |
201 Created
{
"campaign": {
"order_no": "CMP-TK48JX43",
"package": "24 Hour Window",
"chain": "solana",
"token": {
"address": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
"symbol": "Bonk",
"name": "Bonk"
},
"hours": 24,
"status": "scheduled",
"starts_at": "2026-08-21T10:45:33+00:00",
"ends_at": "2026-08-22T10:45:33+00:00"
}
} A complete launch
Validating with GET /token and picking from GET /packages before spending anything:
const BASE = "https://www.dextrending.net/api/v1";
const KEY = process.env.DT_KEY;
async function dt(path, options = {}) {
const res = await fetch(BASE + path, {
...options,
headers: { "X-API-Key": KEY, "Content-Type": "application/json", ...(options.headers || {}) }
});
const body = await res.json();
if (!res.ok) throw new Error(body.error || res.status);
return body;
}
const chain = "solana";
const address = "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263";
// 1. confirm the pair reads before spending anything
await dt(`/token?chain=${chain}&address=${address}`);
// 2. find a package that matches
const { packages } = await dt("/packages");
const ready = packages.find(p => p.status === "available" && p.chain_group === chain);
if (!ready) throw new Error("No package available for " + chain);
// 3. launch
const { campaign } = await dt("/campaigns", {
method: "POST",
body: JSON.stringify({ credit_id: ready.credit_id, chain, address, start_at: "asap" })
});
console.log(campaign.order_no, campaign.status); Polling while it runs
Campaign state changes on the scale of hours, so poll GET /campaigns every few minutes at most. seconds_remaining tells you exactly how long is left, so you can sleep for that long rather than polling until it closes.