Docs menu

REST API · Launches

Create launch plan

Prepare a launch from the interview's answers, WITHOUT creating anything

POSThttps://api.apogee.ad/api/v1/launch-plans

What it does

Answers 201 with the full recap (show it to the user) and the plan id, valid 24 hours; or 422 missing_answers with the open questions (nothing saved). Only the app's documented defaults are applied, and listed. Files: drive:<id>, or your own files in Apogee storage (each checked present). Advantage+ enhancements: only those in advantage_plus.opt_in are ON. platform tiktok / snapchat: the same answers where they mean the same, their own settings under tiktok / snapchat, groups made by hand under adgroups / adsquads; their files must be in Apogee storage (a Drive file: POST /imports first).

Request

POST /launch-plans on https://api.apogee.ad/api/v1.

Headers

  • Authorization string header required

    Bearer apk_…: an API key with the scope of this route.

  • Idempotency-Key string header required

    A unique key per request, e.g. a UUID, reused when you retry it: the first answer comes back instead of a second write (idempotency).

    1 to 255 visible ASCII characters

  • Content-Type string header required

    application/json

Body

  • ad_account_id string required

    The ad account (list_ad_accounts): Meta act_…, a TikTok advertiser id, a Snapchat ad account id

    Matches ^(act_\d{1,32}|[A-Za-z0-9][A-Za-z0-9-]{0,63})$

  • ads array of objects required

    The confirmed ads (get_launch_questions proposed_ads, corrected by the user), or the existing ads to reuse (each either files or source_ad_id, all the same kind; 50 existing ads max)

    1 to 200 items

    Fields of each item (6)
    • source_ad_id string optional

      An ad of this account to reuse with its post (likes and comments stay). Instead of files (get_launch_questions → creatives.choices.existing_ads)

      Matches ^\d{1,40}$

    • files array of objects optional

      New files: the formats of ONE creative, linked by hand or as proposed (one file per format: 9:16, 4:5, 1:1, 16:9; never a video with an image). Leave out with source_ad_id

      1 to 10 items

      Fields of each item (4)
      • ref string required

        drive:<id> (list_drive_folder), or the Apogee storage URL returned by get_upload_urls / confirm_uploads / import_status (your own files only)

        1 to 2,048 characters

      • name string optional

        up to 255 characters

      • mimeType string optional

        up to 100 characters

      • format string optional

        9:16, 4:5, 1:1, 16:9 or auto

        up to 10 characters

    • concept string optional

      Concept = ad set name in 1 Concept 1 Adset. Files without it: the ad's own (its name), or "Group 1" once other ads have one (the app's Group by hand)

      1 to 255 characters

    • ad_name string optional

      Ad name = ad set name in 1 Adset 1 Ad. Required with files; existing ads: default = the source ad's name + " - Copy with post ID"

      1 to 255 characters

    • copy object optional

      This ad's own texts (question "copy"). Not with source_ad_id: an existing ad keeps its post

      Fields (5)
      • primary_texts array of strings optional

        up to 5 items · each: up to 5,000 characters

      • headlines array of strings optional

        up to 5 items · each: up to 255 characters

      • description string optional

        up to 255 characters

      • website_url string optional

        up to 2,048 characters

      • call_to_action string optional

        up to 40 characters

    • spark_post object optional

      TikTok Spark Ads: an existing TikTok post run as this ad instead of files (its caption is the ad text, its likes and comments stay), as list_tiktok_posts gives it

      Fields (2)
      • tiktok_item_id string required

        The TikTok post (list_tiktok_posts: its spark_post)

        Matches ^\d{1,40}$

      • identity object required
        Fields (3)
        • id string required

          The account that posted it

          Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

        • type string required

          TT_USER / BC_AUTH_TT: one of the brand's TikTok accounts; AUTH_CODE: a creator who authorized the post for this ad account

          One of TT_USER, BC_AUTH_TT, AUTH_CODE

        • bc_id string or null optional

          BC_AUTH_TT: its Business Center

          Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

  • platform string optional

    Default meta. tiktok / snapchat: the same interview and arguments where they mean the same, their own settings under tiktok / snapchat, groups made by hand under adgroups / adsquads

    One of meta, tiktok, snapchat

  • campaign_id string optional

    Question "campaign": an existing campaign

    Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

  • structure string optional

    Question "test_structure": 1 Adset 1 Ad, 1 Concept 1 Adset, All in One, Insert in Adset

    One of one_adset_one_ad, one_concept_one_adset, all_in_one, insert_in_adset

  • all_in_one_name string optional

    All in One: the ad set name (required, unless adset_variants)

    up to 255 characters

  • existing_adset_ids array of strings optional

    Insert: the existing ad sets (Meta), ad groups (TikTok) or ad squads (Snapchat)

    up to 50 items

    Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

  • adset_variants array of objects optional

    all_in_one: the same ads in 1-5 new ad sets, each with its own bid / budget (e.g. two cost caps), or each with its own ads (ads)

    1 to 5 items

    Fields of each item (5)
    • name string required

      The new ad set's name

      1 to 255 characters

    • bid_amount number optional

      Cost cap / bid cap, in the account currency

      > 0

    • roas_floor number optional

      Minimum ROAS strategy, e.g. 2.5

      > 0

    • daily_budget number optional

      ABO only, account currency

      > 0

    • ads array of strings optional

      Existing ads (source_ad_id) only: the ads that go into this new ad set, each by its ad_name or its source_ad_id. Left out on every ad set: every ad in each. Given on one: every ad set needs its own, and every ad must be in one at least

      up to 50 items · each: 1 to 255 characters

  • adsets array of objects optional

    New files: the ads arranged into new ad sets by hand, on top of structure one_adset_one_ad, one_concept_one_adset or all_in_one. Launched as 1 Concept 1 Adset (each ad set = a concept), the ad names unchanged; every ad set takes the plan's ad set settings. Not with insert_in_adset, adset_variants or existing ads

    1 to 200 items

    Fields of each item (2)
    • name string required

      The new ad set's name

      1 to 255 characters

    • ads array of strings required

      The ads that go into it, by their ad_name (each ad in exactly one ad set)

      up to 200 items · each: 1 to 255 characters

  • nomenclature object optional

    Question "nomenclature", when a saved convention reads the names: named in the recap. Files grouped by hand: leave it out

    Fields (3)
    • confirmed constant required

      true = the user validated the parsed concepts / iterations / formats

      Always true

    • config_id string or null optional

      The saved naming convention used, null when none

      up to 64 characters

    • name string optional

      up to 255 characters

  • grouping_confirmed constant optional

    Question "grouping": true = the user validated the ads (their names and files), read by a convention or grouped by hand

    Always true

  • copy_adset_from string optional

    Question "starting_point": the ad set / ad group / ad squad whose settings are copied ("latest" = TikTok: the latest ad group of campaign_id)

    Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

  • adset_template_id string optional

    Question "starting_point": a saved Apogee ad set template

    up to 64 characters

  • adset_settings object optional

    A new ad set (questions "audience", "tracking"), or the changes to a copied ad set / template

    Fields (26)
    • goal string optional

      New ad set only. Default: from the campaign objective

      One of sales, leads_website, leads_instant_form, traffic, engagement, awareness, app_installs

    • countries array of strings optional

      ISO codes, e.g. ["FR"] (a new ad set needs countries, regions or cities)

      up to 250 items

      Matches ^[A-Za-z]{2}$

    • regions array of objects optional

      Region keys from search_targeting(type: locations)

      up to 200 items

      Fields of each item (1)
      • key string required

        1 to 32 characters

    • cities array of objects optional

      City keys from search_targeting(type: locations)

      up to 250 items

      Fields of each item (3)
      • key string required

        1 to 32 characters

      • radius number optional

        1 to 80

      • distance_unit string optional

        One of kilometer, mile

    • age_min integer optional

      13 to 65

    • age_max integer optional

      13 to 65

    • genders string optional

      Default all

      One of all, men, women

    • locales array of integers optional

      Language keys from search_targeting(type: locales)

      up to 50 items · each: ≥ -9,007,199,254,740,991

    • advantage_audience boolean optional

      Default true (broad)

    • custom_audience_ids array of strings optional

      list_custom_audiences

      up to 100 items

      Matches ^\d{1,40}$

    • excluded_audience_ids array of strings optional

      list_custom_audiences

      up to 100 items

      Matches ^\d{1,40}$

    • interests array of objects optional

      search_targeting(type: interests)

      up to 100 items

      Fields of each item (2)
      • id string required

        1 to 64 characters

      • name string optional

        up to 255 characters

    • behaviors array of objects optional

      search_targeting(type: behaviors)

      up to 100 items

      Fields of each item (2)
      • id string required

        1 to 64 characters

      • name string optional

        up to 255 characters

    • life_events array of objects optional

      search_targeting(type: demographics): the app's demographics / life events

      up to 100 items

      Fields of each item (2)
      • id string required

        1 to 64 characters

      • name string optional

        up to 255 characters

    • placements one of optional

      "advantage" (Advantage+ placements, the default) or the platforms to keep

      One of 2 shapes:

      option 1 (0 fields)
      option 2 (1 fields)
      • publisher_platforms array of strings required

        One of facebook, instagram, messenger, audience_network

        at least 1 item

    • pixel_id string optional

      A pixel (list_pixels)

      Matches ^\d{1,40}$

    • event string optional

      Meta enum: PURCHASE, LEAD, CONTENT_VIEW, INITIATED_CHECKOUT, ADD_TO_CART, COMPLETE_REGISTRATION…

      up to 64 characters

    • custom_event_str string optional

      A pixel custom event name (sent as OTHER + this name)

      up to 100 characters

    • custom_conversion_id string optional

      A custom conversion (sent alone)

      Matches ^\d{1,40}$

    • optimization_goal string optional

      New ad set: overrides the default optimization (e.g. LINK_CLICKS for traffic)

      up to 64 characters

    • bid_strategy string optional

      ABO: the new ad sets' strategy (default Lowest cost, the highest volume). CBO: must be the campaign's (or leave it out)

      One of LOWEST_COST_WITHOUT_CAP, COST_CAP, LOWEST_COST_WITH_BID_CAP, LOWEST_COST_WITH_MIN_ROAS

    • bid_amount number optional

      COST_CAP / LOWEST_COST_WITH_BID_CAP: the cost per result goal (cost cap) or bid cap of every new ad set, account currency (adset_variants: one each)

      > 0

    • roas_floor number optional

      LOWEST_COST_WITH_MIN_ROAS: the minimum ROAS of every new ad set, e.g. 2.5 (adset_variants: one each)

      > 0

    • attribution object optional

      Default 7-day click, 1-day view, 1-day engaged view

      Fields (3)
      • click string required

        One of 1_day, 7_days

      • view string optional

        One of none, 1_day, 7_days

      • engaged_view string optional

        One of none, 1_day, 7_days

    • application_id string optional

      app_installs

      Matches ^\d{1,40}$

    • object_store_url string optional

      app_installs: App Store / Play Store link

      up to 2,048 characters

  • copy_ad_from string optional

    Question "starting_point": the ad whose settings are copied ("latest" = TikTok: the latest ad)

    Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

  • ad_template_id string optional

    Question "starting_point": a saved Apogee ad template

    up to 64 characters

  • ad_settings object optional

    A new ad (questions "identity", "destination"), or the changes to a copied ad / template

    Fields (8)
    • page_id string optional

      A Facebook page (list_pages)

      Matches ^\d{1,40}$

    • instagram_id string or null optional

      Default: the page's linked Instagram

      Matches ^\d{1,40}$

    • partnership object or null optional

      A partnership ad with a creator who approved the brand's Instagram account, or whose Facebook Page accepted the brand's Page; null = none (default)

      Fields (7)
      • creator_ig_id string optional

        An Instagram creator (get_launch_questions → identity.choices.partnership_creators, source instagram)

        Matches ^\d{1,40}$

      • creator_username string optional

        up to 100 characters

      • creator_fb_page_id string or null optional

        An Instagram creator's Page (default: read from the approved creators; null: none), or alone a Facebook creator (source facebook)

        Matches ^\d{1,40}$

      • creator_name string optional

        A Facebook creator's Page name (as listed)

        up to 200 characters

      • ad_code string optional

        Not used: a partnership ad code boosts the creator's own post, Apogee launches your files. Use creator_ig_id

        up to 200 characters

      • identity_mode string optional

        advertiser_primary = your brand first (default); creator_primary = the creator first (on Instagram only when the creator has no Facebook Page)

        One of advertiser_primary, creator_primary

      • header_display string optional

        dynamic (default, Meta picks; optimizes on Instagram only), both identities, or the first identity only

        One of dynamic, both, primary_only

    • website_url string optional

      Required except for instant forms

      up to 2,048 characters

    • url_parameters string optional

      UTM parameters, "" = none (required for a new ad)

      up to 1,000 characters

    • call_to_action string optional

      Required for a new ad, e.g. SHOP_NOW, LEARN_MORE, SIGN_UP

      up to 40 characters

    • lead_form_id string optional

      Instant form leads (list_lead_forms)

      Matches ^\d{1,40}$

    • display_link string optional

      up to 255 characters

  • advantage_plus object optional

    Question "advantage_plus" (required)

    Fields (1)
    • opt_in array of strings required

      The enhancements the user turned ON; every other one is sent OFF. [] = all off

      One of enhance_cta, inline_comment, reveal_details_over_time, show_destination_blurbs, show_summary, text_optimizations, product_tags, optimize_website_destination, shop, product_browsing, browser_addons, image_brightness_and_contrast, image_templates, image_touchups, video_auto_crop, video_filtering

  • products object optional

    Question "products" (required when the account has a catalog)

    Fields (3)
    • show boolean required

      "Show relevant products" from the catalog

    • catalog_id string optional

      A catalog (get_launch_questions → products)

      Matches ^\d{1,40}$

    • product_set_id string optional

      A product set of that catalog

      Matches ^\d{1,40}$

  • daily_budget number optional

    ABO: daily budget of each new ad set, account currency (required)

    > 0

  • launch_status string optional

    Created Paused (default), Live Now, Scheduled & Paused, Scheduled & Live

    One of CREATED_PAUSED, LIVE_NOW, SCHEDULED_PAUSED, SCHEDULED_LIVE

  • schedule object optional

    Scheduled & Paused / Scheduled & Live

    Fields (2)
    • date string required

      YYYY-MM-DD

      Matches ^\d{4}-\d{2}-\d{2}$

    • time string required

      HH:MM, account time zone

      Matches ^\d{2}:\d{2}$

  • ad_overrides object optional

    Advanced: raw ad template fields (description, display_link, url_parameters, website_url, call_to_action, instagram_account_id, lead_gen_form_id, primary_texts, headlines)

    Fields (9)
    • description any optional
    • display_link any optional
    • url_parameters any optional
    • website_url any optional
    • call_to_action any optional
    • instagram_account_id any optional
    • lead_gen_form_id any optional
    • primary_texts any optional
    • headlines any optional
  • adset_overrides object optional

    Advanced: raw ad set template fields (name, billing_event, optimization_goal, destination_type, daily_min_spend_target, daily_spend_cap, start_time, end_time, bid_strategy, bid_amount, bid_constraints, attribution_spec, attribution_setting, targeting), Meta's units

    Fields (14)
    • name any optional
    • billing_event any optional
    • optimization_goal any optional
    • destination_type any optional
    • daily_min_spend_target any optional
    • daily_spend_cap any optional
    • start_time any optional
    • end_time any optional
    • bid_strategy any optional
    • bid_amount any optional
    • bid_constraints any optional
    • attribution_spec any optional
    • attribution_setting any optional
    • targeting any optional
  • adgroups array of objects optional

    TikTok: ad groups made by hand, instead of structure

    1 to 100 items

    Fields of each item (5)
    • ads array of strings required

      The ad_name of each ad in it (every ad in exactly one group)

      1 to 200 items · each: 1 to 255 characters

    • name string optional

      A new ad group's name

      1 to 255 characters

    • existing_adgroup_id string optional

      An existing ad group to fill instead (all groups existing, or all new)

      Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

    • settings object optional

      This ad group's own settings, over the shared ones

      Fields (15)
      • pixel_id string optional

        A pixel (get_launch_questions → tracking.choices.pixels)

        Matches ^\d{1,40}$

      • optimization_event string optional

        TikTok's optimization_event: SHOPPING (purchase), INITIATE_ORDER, ON_WEB_CART, ON_WEB_DETAIL, ON_WEB_REGISTER, FORM…

        up to 64 characters

      • bid_type string optional

        Default BID_TYPE_NO_BID (maximum delivery); BID_TYPE_CUSTOM = cost cap (bid)

        One of BID_TYPE_NO_BID, BID_TYPE_CUSTOM

      • bid number optional

        Cost cap per conversion (BID_TYPE_CUSTOM), account currency

        > 0

      • pacing string optional

        One of PACING_MODE_SMOOTH, PACING_MODE_FAST

      • countries array of strings optional

        ISO codes, read into TikTok location ids (or location_ids)

        up to 250 items

        Matches ^[A-Za-z]{2}$

      • location_ids array of strings optional

        up to 500 items

        Matches ^\d{1,40}$

      • age_groups array of strings optional

        [] or absent = every age

        One of AGE_13_17, AGE_18_24, AGE_25_34, AGE_35_44, AGE_45_54, AGE_55_100

        up to 6 items

      • gender string optional

        One of GENDER_UNLIMITED, GENDER_MALE, GENDER_FEMALE

      • languages array of strings optional

        up to 50 items · each: up to 16 characters

      • interest_category_ids array of strings optional

        up to 200 items

        Matches ^\d{1,40}$

      • action_category_ids array of strings optional

        up to 200 items

        Matches ^\d{1,40}$

      • audience_ids array of strings optional

        up to 100 items

        Matches ^\d{1,40}$

      • excluded_audience_ids array of strings optional

        up to 100 items

        Matches ^\d{1,40}$

      • placements array of strings optional

        Default TikTok only

        One of PLACEMENT_TIKTOK, PLACEMENT_PANGLE, PLACEMENT_GLOBAL_APP_BUNDLE

        1 to 3 items

    • daily_budget number optional

      ABO: this one's budget (default daily_budget)

      > 0

  • adsquads array of objects optional

    Snapchat: ad squads made by hand, instead of structure

    1 to 100 items

    Fields of each item (5)
    • ads array of strings required

      The ad_name of each ad in it (every ad in exactly one group)

      1 to 200 items · each: 1 to 255 characters

    • name string optional

      A new ad squad's name

      1 to 255 characters

    • existing_adsquad_id string optional

      An existing ad squad to fill instead (all groups existing, or all new)

      Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

    • settings object optional

      This ad squad's own settings, over the shared ones

      Fields (15)
      • optimization_goal string optional

        Default PIXEL_PURCHASE. The PIXEL_ goals need pixel_id (and enough of that event on the pixel lately: get_launch_questions tracking.choices.optimization_goals); SWIPES and LANDING_PAGE_VIEW need none

        One of PIXEL_PURCHASE, PIXEL_ADD_TO_CART, PIXEL_SIGNUP, PIXEL_PAGE_VIEW, SWIPES, LANDING_PAGE_VIEW

      • pixel_id string optional

        A Snap pixel (get_launch_questions → tracking.choices.pixels)

        Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

      • bid_strategy string optional

        Default AUTO_BID

        One of AUTO_BID, LOWEST_COST_WITH_MAX_BID, TARGET_COST

      • bid number optional

        LOWEST_COST_WITH_MAX_BID / TARGET_COST: the bid, account currency

        > 0

      • pacing_type string optional

        Default STANDARD

        One of STANDARD, ACCELERATED

      • conversion_window string optional

        Default Snapchat's SWIPE_28DAY_VIEW_1DAY

        One of SWIPE_28DAY_VIEW_1DAY, SWIPE_7DAY

      • countries array of strings optional

        ISO codes (at least one for a new ad squad)

        1 to 250 items

        Matches ^[A-Za-z]{2}$

      • region_ids array of strings optional

        up to 200 items · each: up to 32 characters

      • min_age integer optional

        Default 18 for a new ad squad: Snapchat refuses its goal for under-18s in the EU, the EEA, Switzerland and the UK

        13 to 65

      • max_age integer optional

        13 to 65

      • genders string optional

        One of all, men, women

      • languages array of strings optional

        up to 50 items · each: up to 16 characters

      • interest_ids array of strings optional

        up to 200 items · each: up to 64 characters

      • segment_ids array of strings optional

        up to 100 items

        Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

      • excluded_segment_ids array of strings optional

        up to 100 items

        Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

    • daily_budget number optional

      ABO: this one's budget (default daily_budget)

      > 0

  • tiktok object optional

    TikTok's own settings (platform tiktok)

    Fields (9)
    • new_campaign object optional

      A new Sales campaign (website conversions; Standard, or Upgraded Smart+), created by the launch (instead of campaign_id)

      Fields (5)
      • name string required

        1 to 255 characters

      • budget_type string required

        abo = a budget per ad group (daily_budget); cbo = the campaign's budget

        One of abo, cbo

      • budget number optional

        CBO: the campaign budget, account currency

        > 0

      • budget_mode string optional

        Default daily

        One of daily, lifetime

      • smart_plus boolean optional

        true = an Upgraded Smart+ campaign (website Sales), as the app's Create Campaign: up to 30 ad groups of 30 ads, one ad per creative (its texts rotate inside), TikTok's dynamic CTA (ad_settings.cta_language / cta_texts), no Spark post. Default: a Standard campaign

    • adgroup_settings object optional

      A new ad group's settings, or the changes to a copied one (copy_adset_from)

      Fields (15)
      • pixel_id string optional

        A pixel (get_launch_questions → tracking.choices.pixels)

        Matches ^\d{1,40}$

      • optimization_event string optional

        TikTok's optimization_event: SHOPPING (purchase), INITIATE_ORDER, ON_WEB_CART, ON_WEB_DETAIL, ON_WEB_REGISTER, FORM…

        up to 64 characters

      • bid_type string optional

        Default BID_TYPE_NO_BID (maximum delivery); BID_TYPE_CUSTOM = cost cap (bid)

        One of BID_TYPE_NO_BID, BID_TYPE_CUSTOM

      • bid number optional

        Cost cap per conversion (BID_TYPE_CUSTOM), account currency

        > 0

      • pacing string optional

        One of PACING_MODE_SMOOTH, PACING_MODE_FAST

      • countries array of strings optional

        ISO codes, read into TikTok location ids (or location_ids)

        up to 250 items

        Matches ^[A-Za-z]{2}$

      • location_ids array of strings optional

        up to 500 items

        Matches ^\d{1,40}$

      • age_groups array of strings optional

        [] or absent = every age

        One of AGE_13_17, AGE_18_24, AGE_25_34, AGE_35_44, AGE_45_54, AGE_55_100

        up to 6 items

      • gender string optional

        One of GENDER_UNLIMITED, GENDER_MALE, GENDER_FEMALE

      • languages array of strings optional

        up to 50 items · each: up to 16 characters

      • interest_category_ids array of strings optional

        up to 200 items

        Matches ^\d{1,40}$

      • action_category_ids array of strings optional

        up to 200 items

        Matches ^\d{1,40}$

      • audience_ids array of strings optional

        up to 100 items

        Matches ^\d{1,40}$

      • excluded_audience_ids array of strings optional

        up to 100 items

        Matches ^\d{1,40}$

      • placements array of strings optional

        Default TikTok only

        One of PLACEMENT_TIKTOK, PLACEMENT_PANGLE, PLACEMENT_GLOBAL_APP_BUNDLE

        1 to 3 items

    • ad_settings object optional

      The ads' TikTok account (and whether their videos show on its profile), destination and CTA (new, or the changes to a copied ad); Smart+ and carousel settings

      Fields (8)
      • identity object optional
        Fields (3)
        • id string required

          The identity id (get_launch_questions → identity.choices.identities)

          Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

        • type string required

          One of the brand's TikTok accounts: TT_USER, or BC_AUTH_TT through its Business Center (TikTok refuses a custom identity on these ads)

          One of TT_USER, BC_AUTH_TT

        • bc_id string or null optional

          BC_AUTH_TT: the Business Center

          Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

      • show_on_profile boolean optional

        The app's "Also show the video on the TikTok profile": true = the video is also posted on the TikTok account's profile; default: it only runs as an ad (TikTok's default). Not where TikTok keeps the videos ads-only (get_launch_questions identity.show_on_profile)

      • website_url string optional

        Apogee's TikTok tracking replaces its own utm_ parameters (no UTM option on TikTok: the app's final URL)

        up to 2,048 characters

      • call_to_action string optional

        Default SHOP_NOW (a Standard ad's; a Smart+ ad runs TikTok's dynamic CTA: cta_language, cta_texts)

        One of SHOP_NOW, BUY_NOW, ORDER_NOW, LEARN_MORE, SIGN_UP, DOWNLOAD_NOW, CONTACT_US, BOOK_NOW

      • cta_language string optional

        Smart+: the language of TikTok's dynamic call to action when the ad group lends none (default en)

        One of en, fr, de, es, it, nl, pt, pl, sv

      • cta_texts array of strings optional

        Smart+: the calls to action kept among the ones TikTok offers in cta_language (default: TikTok's whole list)

        up to 20 items · each: 1 to 40 characters

      • automations object optional

        Smart+: TikTok's automations of the ads (as Meta's Advantage+ creative enhancements), each off unless turned on

        Fields (2)
        • auto_add boolean optional

          TikTok adds assets of its own

        • enhancements array of strings optional

          One of TRANSLATE_AND_DUB, MUSIC_REFRESH, VIDEO_QUALITY, IMAGE_QUALITY, IMAGE_RESIZE

          up to 5 items

      • music_id string optional

        Carousels (image ads): the music, one of list_tiktok_music; default TikTok's pick at the launch

        Matches ^\d{1,40}$

    • carousel_mode string optional

      Images run as carousels (TikTok's image ads), as the app's Configure switch: single (default) = each image ad a carousel of its image; by_concept = a concept's images one carousel ad named after the concept (35 images at most, its first ad's settings and texts)

      One of single, by_concept

    • adgroup_template_id string (uuid) optional

      Quick Bulk Edit: a saved ad group template (list_platform_templates level adgroup), the base of the new ad groups' settings (instead of copy_adset_from); adgroup_settings over it

      Matches ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$

    • ad_template_id string (uuid) optional

      Quick Bulk Edit: a saved ad template (list_platform_templates level ad), the base of the ads' settings (instead of copy_ad_from); ad_settings over it

      Matches ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$

    • time_zone string optional

      The IANA zone of schedule (only when the advertiser's time zone is unknown)

      up to 64 characters

    • end_date string optional

      A lifetime campaign budget (CBO, budget_mode lifetime, a new campaign or an existing one): the date it runs to, YYYY-MM-DD in the schedule's time zone, after the launch (a scheduled launch: TikTok spreads the budget until then). Ignored for a daily budget

      Matches ^\d{4}-\d{2}-\d{2}$

    • end_time string optional

      HH:MM of end_date, default the start's time

      Matches ^\d{2}:\d{2}$

  • snapchat object optional

    Snapchat's own settings (platform snapchat)

    Fields (6)
    • new_campaign object optional

      A new Sales campaign, created by the launch (instead of campaign_id)

      Fields (3)
      • name string required

        1 to 255 characters

      • budget_type string required

        abo = a budget per ad squad (daily_budget, 5 minimum); cbo = the campaign's (20 minimum per day), Snapchat's Smart Budget: its ad squads share their optimisation goal, pixel, bid strategy and conversion window (get_launch_questions tracking.choices); a lower budget is raised to it

        One of abo, cbo

      • budget number optional

        CBO: the campaign budget per day, account currency

        > 0

    • adsquad_settings object optional

      A new ad squad's settings, or the changes to a copied one (copy_adset_from)

      Fields (15)
      • optimization_goal string optional

        Default PIXEL_PURCHASE. The PIXEL_ goals need pixel_id (and enough of that event on the pixel lately: get_launch_questions tracking.choices.optimization_goals); SWIPES and LANDING_PAGE_VIEW need none

        One of PIXEL_PURCHASE, PIXEL_ADD_TO_CART, PIXEL_SIGNUP, PIXEL_PAGE_VIEW, SWIPES, LANDING_PAGE_VIEW

      • pixel_id string optional

        A Snap pixel (get_launch_questions → tracking.choices.pixels)

        Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

      • bid_strategy string optional

        Default AUTO_BID

        One of AUTO_BID, LOWEST_COST_WITH_MAX_BID, TARGET_COST

      • bid number optional

        LOWEST_COST_WITH_MAX_BID / TARGET_COST: the bid, account currency

        > 0

      • pacing_type string optional

        Default STANDARD

        One of STANDARD, ACCELERATED

      • conversion_window string optional

        Default Snapchat's SWIPE_28DAY_VIEW_1DAY

        One of SWIPE_28DAY_VIEW_1DAY, SWIPE_7DAY

      • countries array of strings optional

        ISO codes (at least one for a new ad squad)

        1 to 250 items

        Matches ^[A-Za-z]{2}$

      • region_ids array of strings optional

        up to 200 items · each: up to 32 characters

      • min_age integer optional

        Default 18 for a new ad squad: Snapchat refuses its goal for under-18s in the EU, the EEA, Switzerland and the UK

        13 to 65

      • max_age integer optional

        13 to 65

      • genders string optional

        One of all, men, women

      • languages array of strings optional

        up to 50 items · each: up to 16 characters

      • interest_ids array of strings optional

        up to 200 items · each: up to 64 characters

      • segment_ids array of strings optional

        up to 100 items

        Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

      • excluded_segment_ids array of strings optional

        up to 100 items

        Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

    • ad_settings object optional

      The ads' profile, destination and CTA (new, or the changes to a copied ad)

      Fields (5)
      • profile_id string optional

        A public profile (get_launch_questions → identity.choices.profiles)

        Matches ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$

      • website_url string optional

        https only

        up to 2,048 characters

      • utm object optional

        UTM parameters appended to the URL (the app's UTM toggle): given = on, the app's defaults for the fields left out

        Fields (5)
        • source string optional

          up to 200 characters

        • medium string optional

          up to 200 characters

        • campaign string optional

          up to 200 characters

        • id string optional

          up to 200 characters

        • content string optional

          up to 200 characters

      • call_to_action string optional

        Default SHOP_NOW

        One of SHOP_NOW, ORDER_NOW, SIGN_UP, GET_NOW, BOOK_NOW, VIEW, MORE, READ, WATCH, DOWNLOAD, APPLY_NOW, BUY_TICKETS, PLAY_GAME, LISTEN

      • brand_name string optional

        up to 32 characters

    • adsquad_template_id string (uuid) optional

      Quick Bulk Edit: a saved ad squad template (list_platform_templates level adgroup), the base of the new ad squads' settings (instead of copy_adset_from); adsquad_settings over it

      Matches ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$

    • ad_template_id string (uuid) optional

      Quick Bulk Edit: a saved ad template (list_platform_templates level ad), the base of the ads' settings (instead of copy_ad_from); ad_settings over it

      Matches ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$

    • time_zone string optional

      The IANA zone of schedule (only when the ad account's time zone is unknown)

      up to 64 characters

Response

201.

  • id string
  • status string

    One of prepared, launched, expired

  • recap object
  • defaults_applied array of strings
  • warnings array of strings
  • created_at string or null
  • expires_at string (date-time)
  • launched_at string or null
  • launch_id string or null

Every answer carries X-Request-Id (give it to support), Apogee-Version: 2026-10-06, and the RateLimit and RateLimit-Policy headers; a replayed answer also carries Idempotent-Replayed: true.

Errors

Errors are application/problem+json with a stable code to switch on (all the codes).

Example

With your key in APOGEE_API_KEY (create one):

Request
curl -X POST 'https://api.apogee.ad/api/v1/launch-plans' \
  -H "Authorization: Bearer $APOGEE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "ad_account_id": "act_1234567890",
  "campaign_id": "120200000000000001",
  "structure": "one_concept_one_adset",
  "copy_adset_from": "120200000000000002",
  "copy_ad_from": "120200000000000003",
  "ads": [
    {
      "ad_name": "NORDLICHT_RAIN_HOOK1",
      "concept": "Rain test",
      "files": [
        {
          "ref": "drive:EXAMPLE_FILE_916",
          "name": "NORDLICHT_RAIN_HOOK1_9x16.mp4",
          "format": "9:16"
        },
        {
          "ref": "drive:EXAMPLE_FILE_45",
          "name": "NORDLICHT_RAIN_HOOK1_4x5.mp4",
          "format": "4:5"
        }
      ],
      "copy": {
        "primary_texts": [
          "Rain-proof, wind-proof, and light enough to forget you are wearing it."
        ],
        "headlines": [
          "The Nordlicht shell jacket"
        ],
        "description": "Free returns within 30 days"
      }
    }
  ],
  "grouping_confirmed": true,
  "advantage_plus": {
    "opt_in": []
  },
  "daily_budget": 50,
  "launch_status": "CREATED_PAUSED"
}'
Response 201 (shape)
{
  "id": "120200000000000001",
  "status": "prepared",
  "recap": {},
  "defaults_applied": [
    "120200000000000001"
  ],
  "warnings": [
    "120200000000000001"
  ],
  "created_at": "2026-10-23T09:00:00.000Z",
  "expires_at": "2026-10-23T09:00:00.000Z",
  "launched_at": "2026-10-23T09:00:00.000Z",
  "launch_id": "9a4c1e7d-2f58-4b3a-8e60-1d5b7c9e3f20"
}

Access and cost

PlansPro and Scale.
Scopelaunch (scopes).
CreditsFree up to the daily free reads (5,000 a day on Pro, 10,000 on Scale), then 1 credit per read. A request that fails costs nothing, a replayed one neither (credits).
Rate limitWrite: 120 per 15 minutes on Pro, 240 on Scale (rate limits).
Meta budgetReads Meta: spends 15 units of the account's Meta budget (1,800 per 15 minutes, 900 per ad account).
Daily capCounts 10 units toward the 2,000 units one API key can use in 24 hours.

In the MCP

An AI assistant does the same with this tool of the MCP server:

Last updated on . The parameters, limits, credits and error codes of these pages are generated from the code of the Apogee API (contract 2026-10-06).

A question, something missing? Write to hello@apogee.ad.

Book a demo

Pick the time that suits you.

Open in a new tab

Loading the calendar…

Talk to Founder