REST API
Apogee REST API
JSON over HTTPS for your code, scripts and internal tools: the same launches, Bridge transfers and actions as the app and the MCP server, with the same plan, recap and confirmation.
Base URL and versions
| Base URL | https://api.apogee.ad/api/v1 |
|---|---|
| Authentication | Authorization: Bearer apk_…, an API key (authentication) |
| OpenAPI 3.1 | https://api.apogee.ad/api/v1/openapi.json, public, built from the same schemas that validate the requests |
| Contract | v1, dated 2026-10-06 in the Apogee-Version header of every answer |
| Plans | Pro and Scale (plans, credits) |
Two routes need no key: GET / (the version and links) and GET /openapi.json (the document), both readable from any page.
curl https://api.apogee.ad/api/v1/ Requests and answers
- Bodies are JSON (UTF-8), 2 MB at most. A field the route does not know is refused (
400 validation_failed): send only the documented ones. Ignore the fields of an answer you do not know. - Every answer carries
X-Request-Id(give it to support),Apogee-Version, and the rate-limit headersRateLimitandRateLimit-Policy; a429addsRetry-After(rate limits). - Errors are
application/problem+jsonwith a stablecodeto switch on (errors). - Writes that create something take an
Idempotency-Key: a retry never runs twice (idempotency). - The API sends no CORS headers (except on its two public routes): call it from a server, never from a browser, so the key stays secret.
- Meta, TikTok and Snapchat numbers are read on each platform, in each ad account's currency and time zone: never add them up across platforms.
Pagination
Lists take limit (1 to 200, default 50) and cursor, and answer { data, has_more, next_cursor }. Pass next_cursor as it is to get the next page; it is null on the last one.
cursor=""
while :; do
page=$(curl -s "https://api.apogee.ad/api/v1/ad-accounts?limit=200${cursor:+&cursor=$cursor}" \
-H "Authorization: Bearer $APOGEE_API_KEY")
echo "$page" | jq -r '.data[] | "\(.id) \(.name)"'
cursor=$(echo "$page" | jq -r '.next_cursor // empty')
[ -z "$cursor" ] && break
done Versioning
/v1 only changes in ways that add: new routes, new optional fields, new error codes. Ignore what you do not know. A deprecation is announced with Deprecation and Sunset headers before anything is removed, and listed in the changelog.
Launching through the API
- Creatives. Files on your machine: Create uploads (
POST /uploads), aPUTof each file to its signed URL, then Confirm uploads (POST /uploads/confirm). A Frame.io, Dropbox or Google Drive link: Create import (POST /imports), then Get import (GET /imports/{id}). A Drive folder: List drive folder (GET /drive-folders). Each file gives aref. - The interview. Get launch questions (
POST /ad-accounts/{acc}/launch-questions) returns the questions the app asks, with the account's choices and a recommended answer. - The plan. Create launch plan (
POST /launch-plans) with the answers:422 missing_answerslists what is still open (nothing saved);201returns the recap and the plan id, valid 24 hours. Show the recap to the person who decides. - The launch. After their yes, Confirm launch plan (
POST /launch-plans/{id}/confirm):202with the launch id. Then Get launch (GET /launches/{id}) untilfinished.
TikTok and Snapchat launch the same way, with platform in the questions and the plan. Changes (pause, budgets, duplicates…) follow the same pattern: Create action (POST /actions), then Confirm action (POST /actions/{id}/confirm) after the yes. So do Bridge transfers: Create bridge transfer (POST /bridge-transfers), then Confirm bridge transfer (POST /bridge-transfers/{id}/confirm).
All the operations
48 operations in 8 groups.
Account
Who am I, the API itself
| Operation | Endpoint | Scope |
|---|---|---|
| Get the account and key | GET /me | any valid key |
Ad accounts
Ad accounts and what a launch picks from
| Operation | Endpoint | Scope |
|---|---|---|
| List ad accounts | GET /ad-accounts | read |
| List pages | GET /ad-accounts/{acc}/pages | read |
| List pixels | GET /ad-accounts/{acc}/pixels | read |
| Get pixel events | GET /ad-accounts/{acc}/pixels/{pixel}/events | read |
| List catalogs | GET /ad-accounts/{acc}/catalogs | read |
| List product sets | GET /catalogs/{id}/product-sets | read |
| List custom audiences | GET /ad-accounts/{acc}/custom-audiences | read |
| List templates | GET /ad-accounts/{acc}/templates | read |
| List naming conventions | GET /ad-accounts/{acc}/naming-conventions | read |
| List instagram accounts | GET /pages/{page}/instagram-accounts | read |
| List lead forms | GET /pages/{page}/lead-forms | read |
| List partnership creators | GET /pages/{page}/partnership-creators | read |
| List ad posts | GET /ad-accounts/{acc}/posts | read |
| List page posts | GET /pages/{page}/posts | read |
| Search targeting | GET /targeting/search | read |
| List targeting options | GET /ad-accounts/{acc}/targeting-options | read |
Structure
Campaigns, ad sets, ads
| Operation | Endpoint | Scope |
|---|---|---|
| List campaigns | GET /ad-accounts/{acc}/campaigns | read |
| List ad sets | GET /ad-accounts/{acc}/adsets | read |
| List ads | GET /ad-accounts/{acc}/ads | read |
| Get latest in campaign | GET /ad-accounts/{acc}/campaigns/{id}/latest | read |
| Get an ad set template | GET /adsets/{id}/template | read |
| Get ad template | GET /ads/{id}/template | read |
Insights
Performance
| Operation | Endpoint | Scope |
|---|---|---|
| Get insights | GET /ad-accounts/{acc}/insights | read |
Creatives
Imports, uploads, Drive folders
| Operation | Endpoint | Scope |
|---|---|---|
| Create import | POST /imports | launch |
| Get import | GET /imports/{id} | read |
| List drive folder | GET /drive-folders | read |
| Create uploads | POST /uploads | launch |
| Confirm uploads | POST /uploads/confirm | launch |
| List TikTok posts | GET /ad-accounts/{acc}/tiktok-posts | read |
| List TikTok music | GET /ad-accounts/{acc}/tiktok-music | read |
| List platform templates | GET /ad-accounts/{acc}/platform-templates | read |
Launches
The interview, launch plans, launches
| Operation | Endpoint | Scope |
|---|---|---|
| Get launch questions | POST /ad-accounts/{acc}/launch-questions | read |
| Create launch plan | POST /launch-plans | launch |
| Get launch plan | GET /launch-plans/{id} | read |
| Confirm launch plan | POST /launch-plans/{id}/confirm | launch |
| Get launch plan status | GET /launch-plans/{id}/status | read |
| List launches | GET /launches | read |
| Get launch | GET /launches/{id} | read |
Actions
Prepared then confirmed changes
| Operation | Endpoint | Scope |
|---|---|---|
| Create action | POST /actions | any valid key |
| Get action | GET /actions/{id} | read |
| Confirm action | POST /actions/{id}/confirm | any valid key |
Bridge
Ads of one platform launched on another, Meta → Meta copies across ad accounts
| Operation | Endpoint | Scope |
|---|---|---|
| Create bridge transfer | POST /bridge-transfers | launch |
| Confirm bridge transfer | POST /bridge-transfers/{id}/confirm | launch |
| Get bridge transfer | GET /bridge-transfers/{id} | read |
| List bridged ads | GET /bridged-ads | read |
| Get bridge stats | GET /bridged-ads/stats | read |
| Get bridge daily stats | GET /bridged-ads/daily-stats | read |