Loading…
Loading…
Developer Platform · v1
Programmatic access to Adscod's ad network — advertisers create and manage CPC/CPA/CPM campaigns, and publishers fetch matched native ads with a single Serve call or a one-line script embed. No SDK install required for either side.
https://api.adscod.com/api/v1Adscod has two independent key types, one per side of the network. Use the one that matches your account — they are not interchangeable.
Advertiser key — adc_adv_…
For creating and managing campaigns. Generate one from Advertiser dashboard → Settings → API keys.
curl "https://api.adscod.com/api/v1/external/campaigns" \ -H "Authorization: Bearer adc_adv_YOUR_KEY_HERE"
Publisher key — adc_pub_…
For requesting ads to serve on your site. Generate one from Publisher dashboard → API keys.
curl "https://engine.adscod.com/api/v1/serve?source=publisher&publisherKey=adc_pub_YOUR_KEY"
Never expose keys in client-side code. The Publisher SDK script tag is the one exception — it's designed to carry your adc_pub_… key publicly, the same way an analytics snippet does.
There is no creator key. Creators don't integrate programmatically — campaigns are activated on a bio page from the in-app Creator Hub, and the engine matches and serves ads to that page automatically. If you're building a creator-side integration, there's currently no API for it.
Manage CPC, CPA, or CPM campaigns for the advertiser account linked to your API key. Campaigns are created as DRAFT and start serving once you fund your ad wallet (dashboard-only — there is no funding endpoint on this API) and set action: "publish".
https://api.adscod.com/api/v1/external/campaignsadc_adv_Create a new campaign. Always starts as DRAFT — publish it with a separate PATCH once your wallet is funded.
Request Body
namestringrequiredInternal campaign nameadTitlestringrequiredHeadline shown to viewersadBodystringrequiredAd copy shown to viewersctaUrlstringrequiredLanding page the click redirects toctaLabelstringButton text. Default "Learn More"adImageUrlstringCreative image URLbudgetUsdnumberrequiredTotal campaign budgetpricingModelenumCPC | CPA | CPM. Default CPCcpcBidUsdnumberCost per click — required if pricingModel is CPCcpaBidUsdnumberCost per conversion — required if pricingModel is CPA. Charged at conversion postback, not at clickcpmRateUsdnumberRate per 1000 impressions — required if pricingModel is CPM. Charged per impression at serve time, not per clickactionTypeenumINSTALL | SIGNUP | PURCHASE | LEAD | CUSTOM. CPA conversion type, defaults to CUSTOMpostbackUrlstringYour URL to receive a copy of each conversion (HTTPS only)dailyCapUsdnumberMax daily spend. Minimum $0.01 if setcategorystringUsed for intent matching at serve timekeywordsstring[]Used for intent matching at serve timetargetCountriesstring[]ISO country codes. Omitted = all countriestargetDevicesstring[]MOBILE | DESKTOP | TABLET. Omitted = all devicesscheduleDaysnumber[]0–6 (Sun–Sat) dayparting. Omitted = every dayscheduleHoursnumber[]0–23 dayparting. Omitted = all hoursfrequencyCapnumberMax impressions per viewer per window. Omitted = uncappedExample Request
curl -X POST https://api.adscod.com/api/v1/external/campaigns \
-H "Authorization: Bearer adc_adv_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"name": "Summer Launch",
"adTitle": "Shop the new collection",
"adBody": "Up to 40% off this week only.",
"ctaUrl": "https://example.com/deals",
"budgetUsd": 50,
"cpcBidUsd": 0.12,
"targetCountries": ["NG", "KE"]
}'Response
{
"success": true,
"campaign": {
"id": "cmp_abc123",
"name": "Summer Launch",
"adTitle": "Shop the new collection",
"pricingModel": "CPC",
"budgetUsd": 50,
"cpcBidUsd": 0.12,
"status": "DRAFT",
"createdAt": "2026-06-30T10:00:00Z"
}
}https://api.adscod.com/api/v1/external/campaignsadc_adv_List all campaigns for your advertiser account with live stats.
Example Request
curl "https://api.adscod.com/api/v1/external/campaigns" \ -H "Authorization: Bearer adc_adv_YOUR_KEY_HERE"
Response
{
"success": true,
"campaigns": [ { "id": "cmp_abc123", "name": "Summer Launch", "status": "ACTIVE", "budgetUsd": 50, "cpcBidUsd": 0.12 } ],
"stats": { "totalImpressions": 18400, "totalClicks": 340, "totalConversions": 12, "totalSpent": 40.80, "totalBudget": 50, "ctr": 1.85, "conversionRate": 3.53 }
}https://api.adscod.com/api/v1/external/campaigns/:idadc_adv_Get a single campaign you own, plus its 14-day click/spend timeseries.
Parameters
idstringrequiredCampaign IDExample Request
curl "https://api.adscod.com/api/v1/external/campaigns/cmp_abc123" \ -H "Authorization: Bearer adc_adv_YOUR_KEY_HERE"
Response
{
"success": true,
"campaign": { "id": "cmp_abc123", "name": "Summer Launch", "status": "ACTIVE", "budgetUsd": 50, "cpcBidUsd": 0.12, "targetCountries": ["NG", "KE"] },
"timeseries": [ { "date": "2026-06-29", "clicks": 24, "spend": 2.88 } ]
}https://api.adscod.com/api/v1/external/campaigns/:idadc_adv_Update budget, bid, targeting, or copy — or pass action to change lifecycle status. Publishing or resuming requires a funded ad wallet.
Request Body
actionenumpublish | pause | resume | archivenamestringadTitlestringadBodystringbudgetUsdnumbercpcBidUsdnumberdailyCapUsdnumbertargetCountriesstring[]keywordsstring[]Example Request
curl -X PATCH https://api.adscod.com/api/v1/external/campaigns/cmp_abc123 \
-H "Authorization: Bearer adc_adv_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{ "action": "publish" }'Response
{ "success": true, "id": "cmp_abc123", "status": "ACTIVE" }https://api.adscod.com/api/v1/external/campaigns/conversionsadc_adv_Server-to-server: report a conversion for a CPA campaign once your backend has confirmed it. Pass back the clickId your landing page received as the aff_click_id query param. Idempotent — reporting the same clickId twice is a no-op the second time.
Request Body
clickIdstringrequiredThe aff_click_id your landing page received on the click-through URLtypestringConversion type. Defaults to the campaign's actionTypevaluenumberConversion value, for analyticsExample Request
curl -X POST https://api.adscod.com/api/v1/external/campaigns/conversions \
-H "Authorization: Bearer adc_adv_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{ "clickId": "clk_9f2a", "type": "PURCHASE", "value": 24.99 }'Response
{ "success": true, "alreadyRecorded": false, "charged": true }Read-only. Creators choose which campaigns to activate themselves from the Creator Hub — there is no endpoint to assign or invite a creator to a campaign.
https://api.adscod.com/api/v1/external/campaigns/:id/creatorsadc_adv_List creators who have activated this campaign on their bio page, with each creator's clicks and earnings.
Parameters
idstringrequiredCampaign IDExample Request
curl "https://api.adscod.com/api/v1/external/campaigns/cmp_abc123/creators" \ -H "Authorization: Bearer adc_adv_YOUR_KEY_HERE"
Response
{
"success": true,
"campaignId": "cmp_abc123",
"total": 1,
"creators": [
{
"creatorId": "crt_1",
"username": "janedoe",
"displayName": "Jane Doe",
"verified": true,
"country": "NG",
"niche": "fashion",
"followers": 1000000,
"isActive": true,
"clicks": 340,
"earnedUsd": 26.52,
"activatedAt": "2026-06-20T09:00:00Z"
}
]
}https://api.adscod.com/api/v1/external/creatorsadc_adv_Browse the public creator pool — gauge available inventory by niche, follower count, or country before launching a campaign.
Parameters
qstringSearch by name or @usernamenichestringe.g. fashion, fintech, gamingcountrystringISO country codeminFollowersnumberMinimum follower countpagenumberDefault 1limitnumberDefault 20, max 50Example Request
curl "https://api.adscod.com/api/v1/external/creators?niche=fashion&country=NG&minFollowers=100000" \ -H "Authorization: Bearer adc_adv_YOUR_KEY_HERE"
Response
{
"success": true,
"creators": [
{ "id": "crt_1", "username": "janedoe", "displayName": "Jane Doe", "verified": true, "country": "NG", "niche": "fashion", "followers": 1000000 }
],
"total": 1, "page": 1, "totalPages": 1
}The serving hot path is a separate Go service at https://engine.adscod.com — not the https://api.adscod.com/api/v1 host used above. It matches active campaigns to a context and returns a short-lived clickUrl; the matching is always a CPC-bid auction boosted by intent/category overlap, not a hard filter, so empty inventory never blocks a response.
Pricing models & payouts
CPC — billed atomically at /click/:token: your cpcBidUsd is debited from the advertiser wallet the instant a click is billed, 65% credited to the creator/publisher wallet, 35% to Adscod.
CPA — the click itself is free: /click/:token records a zero-value attribution row and redirects, no money moves. The charge (and the same 65/35 payout split, applied to cpaBidUsd) happens when the conversion is reported — either POST /api/v1/conversion below, or POST /external/campaigns/conversions from your backend.
CPM — billed per impression, inside /api/v1/serve itself: each matched ad debits cpmRateUsd / 1000 before it's returned, same 65/35 split. An impression that can't be afforded (budget just exhausted, wallet ran dry) is dropped from the response rather than served for free — so a CPM request can return fewer ads than limit asked for.
The auction itself always ranks on one number per campaign: cpcBidUsd for CPC/CPA campaigns, cpmRateUsd / 1000 (its per-impression value) for CPM — so campaigns on any pricing model compete for the same inventory on a comparable basis.
https://engine.adscod.com/api/v1/serveadc_pub_Match active campaigns to a context and return the best ad(s) plus a one-time clickUrl. This is what the Publisher SDK calls under the hood — call it directly only if you need server-side rendering or custom UI.
Parameters
sourceenumrequiredpublisher (creators use the bio-page flow, not this key)publisherKeystringrequiredadc_pub_… key. Prefer the X-Adscod-Key header over this query paramplacementIdstringYour AdPlacement ID, if you've created onecountrystringISO-3166 alpha-2. Falls back to geo headerdevicestringMOBILE | DESKTOP | TABLETcategorystringSoft filter — boosts matching campaigns, doesn't exclude othersqstringRaw search/page-context string, e.g. "cheap bus nairobi mombasa"limitnumberDefault 1, max 10Example Request
curl "https://engine.adscod.com/api/v1/serve?source=publisher&placementId=plc_789&country=NG&device=MOBILE&limit=1" \ -H "X-Adscod-Key: adc_pub_YOUR_KEY_HERE"
Response
{
"success": true,
"ads": [
{
"campaignId": "cmp_abc123",
"title": "Shop the new collection",
"body": "Up to 40% off this week only.",
"imageUrl": "https://…",
"ctaLabel": "Shop now",
"clickUrl": "https://adscod.com/click/<clickToken>",
"cpcUsd": "0.045000"
}
]
}https://adscod.adscod.com/click/:tokenThe clickUrl from /serve. Bills the click (65% to you, 35% platform), then 302-redirects the viewer to the advertiser's ctaUrl. No JSON response — never call this from your backend, only link/redirect viewers to it. Billing failures degrade to a plain redirect, so a viewer never sees an error.
Parameters
tokenstringrequiredThe clickToken embedded in the clickUrl returned by /serveExample Request
# Not called directly — render clickUrl as a normal <a href> from the /serve response
Response
302 Found
Location: https://example.com/dealshttps://engine.adscod.com/api/v1/conversionadc_adv_Idempotent conversion postback for the hot-path engine. Fired server-to-server from the advertiser's backend with their secret API key (X-Adscod-Key) and the click token from the click-through. The key must never be exposed in browser code. A conversion only matches clicks on your own campaigns. Distinct from /external/campaigns/conversions — use that one for batch S2S CPA reporting instead.
Request Body
clickTokenstringrequiredThe token from the original clickvaluenumberConversion valuecurrencystringDefault USDExample Request
curl -X POST https://engine.adscod.com/api/v1/conversion \
-H "Content-Type: application/json" \
-H "X-Adscod-Key: <YOUR_ADSCOD_API_KEY>" \
-d '{ "clickToken": "<token>", "value": 12.50 }'Response
{ "success": true, "converted": true, "duplicate": false }For most publishers, the script tag is simpler than calling /api/v1/servedirectly — it auto-detects page category/intent from your page's own meta tags and renders a styled native ad card with no layout work on your side.
<script src="https://api.adscod.com/sdk/v1/publisher.js" data-key="adc_pub_YOUR_KEY_HERE" data-placement="banner" async ></script>
Script attributes
data-keyRequired. Your adc_pub_… publisher key.data-placementbanner | sidebar | inline | native. Default banner.data-categoryPage category. Auto-detected from <meta name="category"> if omitted.data-themelight | dark. Default light.data-limitHow many ads to render, 1–3. Default 1.data-engineEngine base URL override. Default https://engine.adscod.com.HTTP Status Codes
200/201Success400Validation error — check the response body for details401Invalid or missing API key403Key is revoked, or the resource doesn't belong to your account404Resource not found429Rate limit exceeded — back off and retry500Server error — contact support@adscod.comRate Limits
adc_adv_…) are limited to 300 requests/minute. Exceeded requests return HTTP 429.Error Shape
{
"statusCode": 403,
"message": "API key has been revoked",
"error": "Forbidden"
}