Skip to main content
POST
/
ad_campaigns
Create an Ad Campaign
curl --request POST \
  --url https://api.whop.com/api/v1/ad_campaigns \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "platform": "meta",
  "title": "<string>",
  "account_id": "<string>",
  "budget_amount": 123,
  "desired_cost_per_result": 123,
  "ends_at": "<string>",
  "special_ad_categories": [],
  "starts_at": "<string>"
}
'
import requests

url = "https://api.whop.com/api/v1/ad_campaigns"

payload = {
"platform": "meta",
"title": "<string>",
"account_id": "<string>",
"budget_amount": 123,
"desired_cost_per_result": 123,
"ends_at": "<string>",
"special_ad_categories": [],
"starts_at": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
platform: 'meta',
title: '<string>',
account_id: '<string>',
budget_amount: 123,
desired_cost_per_result: 123,
ends_at: '<string>',
special_ad_categories: [],
starts_at: '<string>'
})
};

fetch('https://api.whop.com/api/v1/ad_campaigns', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.whop.com/api/v1/ad_campaigns",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'platform' => 'meta',
'title' => '<string>',
'account_id' => '<string>',
'budget_amount' => 123,
'desired_cost_per_result' => 123,
'ends_at' => '<string>',
'special_ad_categories' => [

],
'starts_at' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.whop.com/api/v1/ad_campaigns"

payload := strings.NewReader("{\n \"platform\": \"meta\",\n \"title\": \"<string>\",\n \"account_id\": \"<string>\",\n \"budget_amount\": 123,\n \"desired_cost_per_result\": 123,\n \"ends_at\": \"<string>\",\n \"special_ad_categories\": [],\n \"starts_at\": \"<string>\"\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.whop.com/api/v1/ad_campaigns")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"platform\": \"meta\",\n \"title\": \"<string>\",\n \"account_id\": \"<string>\",\n \"budget_amount\": 123,\n \"desired_cost_per_result\": 123,\n \"ends_at\": \"<string>\",\n \"special_ad_categories\": [],\n \"starts_at\": \"<string>\"\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.whop.com/api/v1/ad_campaigns")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"platform\": \"meta\",\n \"title\": \"<string>\",\n \"account_id\": \"<string>\",\n \"budget_amount\": 123,\n \"desired_cost_per_result\": 123,\n \"ends_at\": \"<string>\",\n \"special_ad_categories\": [],\n \"starts_at\": \"<string>\"\n}"

response = http.request(request)
puts response.read_body
{
  "added_to_carts": 123,
  "bid_type": "minimum_cost",
  "budget_amount": 123,
  "budget_optimization": "ad_campaign",
  "budget_type": "daily",
  "click_through_rate": 123,
  "clicks": 123,
  "completed_registrations": 123,
  "contacts": 123,
  "cost_per_added_to_cart": 123,
  "cost_per_click": 123,
  "cost_per_completed_registration": 123,
  "cost_per_contact": 123,
  "cost_per_lead": 123,
  "cost_per_mille": 123,
  "cost_per_purchase": 123,
  "cost_per_result": 123,
  "cost_per_schedule": 123,
  "cost_per_submitted_application": 123,
  "cost_per_viewed_content": 123,
  "created_at": "<string>",
  "custom_conversions": 123,
  "delivery_status": "payment_failed",
  "frequency": 123,
  "id": "<string>",
  "impressions": 123,
  "issues": [
    {
      "id": "<string>",
      "message": "<string>",
      "resource_id": "<string>",
      "resource_type": "ad_campaign"
    }
  ],
  "leads": 123,
  "objective": "awareness",
  "optimization_goal": "<string>",
  "platform": "meta",
  "purchase_value": 123,
  "purchases": 123,
  "reach": 123,
  "result_event": "purchase",
  "result_event_name": "<string>",
  "return_on_ad_spend": 123,
  "schedules": 123,
  "special_ad_categories": [
    "housing"
  ],
  "spend": 123,
  "spend_currency": "<string>",
  "status": "active",
  "submitted_applications": 123,
  "title": "<string>",
  "unique_click_through_rate": 123,
  "unique_clicks": 123,
  "updated_at": "<string>",
  "viewed_contents": 123
}
{
"error": {
"message": "<string>",
"type": "<string>"
}
}

Authorizations

Authorization
string
header
required

A company API key, company scoped JWT, app API key, or user OAuth token. You must prepend your key/token with the word 'Bearer', which will look like Bearer ***************************

Headers

Api-Version-Date
string

Pins the request to a dated API version.

Example:

"2026-07-08-1"

Body

application/json
objective
enum<string>
required

The goal the campaign optimizes toward.

Available options:
awareness,
traffic,
engagement,
leads,
sales
platform
enum<string>
required

The ad network the campaign runs on.

Available options:
meta
title
string
required

The title of the campaign.

account_id
string

The account to create the campaign under. Defaults to the account-scoped key's own account.

bid_type
enum<string>

CBO bid strategy: minimum_cost (lowest cost), average_target (cost cap), or maximum_target (bid cap). CBO only.

Available options:
minimum_cost,
average_target,
maximum_target
budget_amount
number

The campaign budget, in USD. Required for CBO (budget_optimization: ad_campaign); omit for ABO.

budget_optimization
enum<string>

Which level owns the budget — the campaign (CBO) or each ad group (ABO). Defaults to ad_group.

Available options:
ad_campaign,
ad_group
budget_type
enum<string>

Whether the budget is spent per day or over the campaign's lifetime. Defaults to daily.

Available options:
daily,
lifetime
desired_cost_per_result
number

Target/cap cost per result in USD for average_target / maximum_target bidding. CBO only.

ends_at
string

Campaign schedule end (ISO 8601). CBO only.

special_ad_categories
enum<string>[]

Regulated categories the campaign falls under. Ads in these categories are subject to extra targeting restrictions.

Available options:
housing,
employment,
financial_products,
politics
starts_at
string

Campaign schedule start (ISO 8601). CBO only.

Response

ad campaign created

added_to_carts
number
required

Whop pixel-attributed add-to-cart events, last-click.

bid_type
enum<string> | null
required

The bidding strategy the campaign uses.

Available options:
minimum_cost,
average_target,
maximum_target,
null
Example:

"minimum_cost"

budget_amount
number | null
required

The campaign budget in USD. Null when budget is set at the ad group level (ABO).

budget_optimization
enum<string> | null
required

Which level owns the budget — the campaign (CBO) or each ad group (ABO).

Available options:
ad_campaign,
ad_group,
null
Example:

"ad_campaign"

budget_type
enum<string> | null
required

Whether the budget is spent per day or over the campaign's lifetime.

Available options:
daily,
lifetime,
null
Example:

"daily"

click_through_rate
number
required

Clicks divided by impressions, between 0 and 1.

clicks
number
required

The number of clicks.

completed_registrations
number
required

Whop pixel-attributed complete-registration events, last-click.

contacts
number
required

Whop pixel-attributed contact events, last-click.

cost_per_added_to_cart
number | null
required

Spend divided by attributed add-to-cart events; null when they are not the goal and none are attributed.

cost_per_click
number
required

Spend divided by clicks; 0 when there are no clicks.

cost_per_completed_registration
number | null
required

Spend divided by attributed complete-registration events; null when they are not the goal and none are attributed.

cost_per_contact
number | null
required

Spend divided by attributed contact events; null when contacts are not the goal and none are attributed.

cost_per_lead
number | null
required

Spend divided by attributed leads; null when leads are not a goal and none are attributed.

cost_per_mille
number
required

Spend per 1,000 impressions; 0 when there are no impressions.

cost_per_purchase
number | null
required

Spend divided by attributed purchases; null when purchases are not a goal and none are attributed.

cost_per_result
number | null
required

Spend divided by Whop pixel-attributed results; null when nothing Whop-attributable is being optimized for.

cost_per_schedule
number | null
required

Spend divided by attributed schedule events; null when schedules are not the goal and none are attributed.

cost_per_submitted_application
number | null
required

Spend divided by attributed submit-application events; null when they are not the goal and none are attributed.

cost_per_viewed_content
number | null
required

Spend divided by attributed view-content events; null when they are not the goal and none are attributed.

created_at
string
required

When the campaign was created, as an ISO 8601 timestamp.

custom_conversions
number
required

Whop pixel-attributed custom (merchant-defined) conversion events, last-click, across all custom event names.

delivery_status
enum<string>
required

The current delivery state, mirroring the Delivery column in the ads dashboard. When several states apply at once, the highest-precedence one is returned.

Available options:
payment_failed,
all_ads_rejected,
draft,
no_ad_groups,
no_ads,
paused,
processing,
issues,
scheduled,
completed,
ad_groups_off,
active
Example:

"payment_failed"

frequency
number | null
required

Platform-reported impressions divided by reach.

id
string
required

Unique identifier for the ad campaign.

impressions
number
required

The number of impressions.

issues
object[]
required
leads
number
required

Whop pixel-attributed leads, last-click.

objective
enum<string> | null
required

The goal the campaign optimizes toward.

Available options:
awareness,
traffic,
engagement,
leads,
sales,
null
Example:

"awareness"

optimization_goal
string | null
required

The specific event the campaign optimizes for. If the campaign is CBO, then all ad groups will have the same optimization goal, which will be returned here.

platform
enum<string>
required

The ad network the campaign runs on.

Available options:
meta
Example:

"meta"

purchase_value
number
required

USD value of pixel-attributed purchases.

purchases
number
required

Whop pixel-attributed purchases, last-click.

reach
number
required

The number of unique people who saw this.

result_event
enum<string> | null
required

The Whop pixel conversion event whose attributed count represents results — the optimization goal, or the highest-volume attributed event for campaigns that budget per ad group. Null when the goal isn't a Whop-attributed event.

Available options:
purchase,
lead,
schedule,
submit_application,
contact,
complete_registration,
view_content,
add_to_cart,
custom,
null
Example:

"purchase"

result_event_name
string | null
required

The merchant-defined event name when result_event is custom; null for the standard events.

return_on_ad_spend
number
required

Purchase value divided by spend, both in USD (a currency-neutral ratio); 0 when there is no spend.

schedules
number
required

Whop pixel-attributed schedule events, last-click.

special_ad_categories
enum<string>[]
required

Regulated categories the campaign is declared under. Ads in these categories are subject to extra targeting restrictions. Empty when none apply.

Available options:
housing,
employment,
financial_products,
politics
spend
number
required

The amount charged, in spend_currency.

spend_currency
string | null
required

The ISO 4217 currency code of all monetary metrics.

status
enum<string>
required

The lifecycle status of the ad campaign.

Available options:
active,
paused,
inactive,
stale,
pending_refund,
payment_failed,
draft,
in_review,
flagged,
importing,
imported
Example:

"active"

submitted_applications
number
required

Whop pixel-attributed submit-application events, last-click.

title
string
required

The title of the ad campaign.

unique_click_through_rate
number | null
required

Unique clicks divided by impressions, between 0 and 1.

unique_clicks
number
required

The number of unique clicks.

updated_at
string
required

When the campaign was last updated, as an ISO 8601 timestamp.

viewed_contents
number
required

Whop pixel-attributed view-content events, last-click.