Skip to content

Developer Platform

Search docs & API
Log in
Sign up

Create promotions

You can set up promotions within ad campaigns to alert customers about sales, discounts and other offers.
Each promotion has a type that defines its consumer incentive, such as:
  • Free shipping
  • Gift with purchase
  • X off at checkout
  • Earn X points on all purchases
Deal ad
You can apply promotions to ad groups or individual catalog items, depending on your needs:
Ad group and item promo use cases
Promotion levelSupported campaign objectivesScopeUse case
Ad group
CONSIDERATION

CONVERSION

CATALOG_SALES
*
Appears in ads across entire ad group
General promotions like seasonal sales, brand-level discounts, or offers that apply broadly across a group of products or services.
Item
CATALOG_SALES
*
Appears in an individual catalog item.
Highly granular, product-focused offers such as moving clearance on specific items, or promoting best-sellers with a unique discount.
*As part of objective simplification, the
CATALOG_SALES
objective is being deprecated, to be replaced by the
SALES
objective. See the details and timeline for objective simplification.
*As part of objective simplification, the
CATALOG_SALES
objective is being deprecated, to be replaced by the
SALES
objective. See the details and timeline for objective simplification.
Promotions are supported for the following creative types…
  • Regular
  • Video
  • Shopping
  • Carousel
  • Collection
  • Idea ads

Set up an ad group promotion

After you set up an ad group promotion, any ad in the assigned ad group displays the promotional text.

Step 1: Create the ad group promotion

POST
Create promotions
The endpoint allows up to 30 entries per request.
Any parameters and code examples that appear in this section support this use case, but may not represent the full endpoint specification. See the endpoint reference page for the comprehensive spec.
Any parameters and code examples that appear in this section support this use case, but may not represent the full endpoint specification. See the endpoint reference page for the comprehensive spec.

Request parameters to keep in mind

Create promotion parameters
ParameterDescription
external_id

string
Optional
Provide an identifier from the platform or system that originated the promotion.
promotion_custom_id

string
Optional
Provide a custom identifier for the promotion to use for your own tracking, naming conventions, or mapping across systems.
If you do not provide it, Pinterest populates it automatically by copying the Pinterest-generated promotion ID.
Use it when you want a stable ID that matches your internal IDs or campaign taxonomy.
platform_type

string
Optional
Indicate which integration platform is creating the promotion or is considered its source.
If your app is integrated with Shopify, pass
SHOPIFY
. Otherwise, pass
DEFAULT
or omit.
promotion_title

string
Required
Provide human-readable internal name for the promotion for organization and management in Ads Manager or the API).
Primarily for internal identification in reporting and UI lists.
Not the ad's “headline” shown to users.
promotion_code

string
Optional
Provide a code that users can enter to redeem a promotion.
start_time

integer
Optional
Set a Unix time stamp for when the promotion starts.
If you omit it, the promotion starts after its creation if its associated campaign and ad group are active.
Different from campaign start time.
end_time

integer
Optional
Set a Unix time stamp for when the promotion ends.
If you omit it, the promotion runs indefinitely as long as its associated campaign and ad group are active.
Different from campaign end time.
promotion_type

string
Required
Set to determine the displayed promotion text along with what parameters (if any) are needed to complete the template.
See Using promotion types with template values.
promotion_type

string
Required
Set to determine the displayed promotion text along with what parameters (if any) are needed to complete the template.
See Using promotion types with template values.
template_values

string
Optional but necessary for certain
promotion_type
enums
Provide quantities, monetary values, or percentages for certain
promotion_type
enums.
See Using promotion types with template values.
discount_status

string
Optional
Indicates current lifecycle state of a promotion's discount, computed from the current time and the discount's configured
start_time
/
end_time
and any manual pause.
It helps you determine whether the discount should be considered in effect right now.
Enums:
OTHER
ACTIVE
PAUSED
SCHEDULED
EXPIRED

Example request

curl -X POST \ "https://api.pinterest.com/v5/ad_accounts/{ad_account_id}/promotions" \ -H "Authorization: Bearer pina_ABCD1234..." \ -H "Content-Type: application/json" \ -d '[ { "id": "7834020368389", "external_id": "abc", "promotion_custom_id": "freeshipping_2025", "platform_type": "DEFAULT", "promotion_title": "Black Friday 10% off", "promotion_code": "blackfriday10", "start_time": 1677003860, "end_time": 1678003860, "promotion_type": "CUSTOM", "template_values": [ { "amount": 100, "percent": 10, "currency_code": "USD", "custom_text": "some custom text of the promotion" } ], "discount_status": "ACTIVE" } ]'

Returned promotion ID field

A successful request returns an
id
value, which identifies the promotion. You will need this identifier when assigning the promotion to an ad group.

Example response

{ "promotions": [ { "data": { "id": "7834020368389", "ad_account_id": "123456789012", "external_id": "abc", "platform_type": "DEFAULT", "promotion_title": "Black Friday 10% off", "promotion_custom_id": "freeshipping_2025", "promotion_code": "blackfriday10", "promotion_type": "CUSTOM", "start_time": 1677003860, "ext_features": { "enabled": [] }, "end_time": 1678003860, "template_values": [ { "amount": 100, "currency_code": "USD", "custom_text": "some custom text of the promotion", "percent": 10 } ], "discount_status": "ACTIVE", "status": "ACTIVE" }, "exception": null } ] }

Step 2: Assign the promotion to an ad group

You can assign a promotion to multiple ad groups.
POST
Create ad groups
PATCH
Update ad groups
Any parameters and code examples that appear in this section support this use case, but may not represent the full endpoint specification. See the endpoint reference page for the comprehensive spec.
Any parameters and code examples that appear in this section support this use case, but may not represent the full endpoint specification. See the endpoint reference page for the comprehensive spec.
Add promo to ad group parameters
ParameterDescription
promotion_ids

array
Optional but necessary for this use case
Attach up to five promotions to the ad group, so Pinterest can choose which promotion to show based on timing and eligibility.
Example:
["7834020372300", "7834020372301"]
To remove all promotions from the ad group, send an empty array:
[]
.
If multiple attached promotions are eligible at the same time because of overlapping dates, Pinterest serves the promotion with the latest start date.
The referenced promotions must exist and be accessible under the same ad account.
promotion_application_level

string, nullable
Optional but necessary for this use case
Set to
AD_GROUP
for this use case.

Example request with multiple promotions

curl -X POST \ "https://api.pinterest.com/v5/ad_accounts/123456789012/ad_groups" \ -H "Authorization: Bearer pina_ABCD1234..." \ -H "Content-Type: application/json" \ -d '[ { "campaign_id": "626756081487", "id": "2680086898355", "billable_event": "CLICKTHROUGH", "name": "update test ag 3-1", "promotion_ids": [ "7834020372301", "7834020372303" ], "bid_in_micro_currency": 1000000, "targeting_spec": { "LOCATION": ["US"], "APPTYPE": ["web", "ipad", "web_mobile", "iphone", "android_mobile", "android_tablet"], "GENDER": ["female", "male", "unknown"] } } ]'

Example response for multiple promotions

{ "items": [ { "data": { "id": "2680086898355", "created_time": 1754627687, "updated_time": 1771885845, "start_time": null, "end_time": null, "bid_in_micro_currency": null, "budget_in_micro_currency": null, "campaign_id": "626756081487", "ad_account_id": "549757102439", "auto_targeting_enabled": true, "type": "adgroup", "budget_type": "CBO_ADGROUP", "billable_event": "CLICKTHROUGH", "status": "ACTIVE", "lifetime_frequency_cap": -1, "targeting_spec": { "APPTYPE": ["web", "ipad", "web_mobile", "iphone", "android_mobile", "android_tablet"], "GENDER": ["female", "male", "unknown"], "LOCATION": ["US"] }, "name": "update test ag 3-1", "placement_group": "ALL", "pacing_delivery_type": "STANDARD", "tracking_urls": null, "conversion_learning_mode_type": null, "summary_status": "RUNNING", "feed_profile_id": "0", "placement_traffic_type": null, "optimization_goal_metadata": {}, "targeting_template_ids": null, "is_creative_optimization": null, "promotion_id": null, "promotion_ids": ["7834020372301", "7834020372303"], "promotion_application_level": "AD_GROUP", "bid_multiplier": null, "ext_features": null, "bid_strategy_type": "AUTOMATIC_BID" } } ] }

Example request with one promotion

curl -X POST \ "https://api.pinterest.com/v5/ad_accounts/123456789012/ad_groups" \ -H "Authorization: Bearer pina_ABCD1234..." \ -H "Content-Type: application/json" \ -d '[ { "campaign_id": "626756081487", "id": "2680086898355", "billable_event": "CLICKTHROUGH", "name": "update test ag 3-1", "promotion_ids": [ "7834020372301" ], "promotion_application_level": "AD_GROUP", "bid_in_micro_currency": 1000000, "targeting_spec": { "LOCATION": ["US"], "APPTYPE": ["web", "ipad", "web_mobile", "iphone", "android_mobile", "android_tablet"], "GENDER": ["female", "male", "unknown"] } } ]'

Example response with one promotion

{ "items": [ { "data": { "id": "2680086898355", "created_time": 1754627687, "updated_time": 1771886766, "start_time": null, "end_time": null, "bid_in_micro_currency": null, "budget_in_micro_currency": null, "campaign_id": "626756081487", "ad_account_id": "549757102439", "auto_targeting_enabled": true, "type": "adgroup", "budget_type": "CBO_ADGROUP", "billable_event": "CLICKTHROUGH", "status": "ACTIVE", "lifetime_frequency_cap": -1, "targeting_spec": { "LOCATION": ["US"], "APPTYPE": ["web", "ipad", "web_mobile", "iphone", "android_mobile", "android_tablet"], "GENDER": ["female", "male", "unknown"] }, "name": "update test ag 3-1", "placement_group": "ALL", "pacing_delivery_type": "STANDARD", "tracking_urls": null, "conversion_learning_mode_type": null, "summary_status": "RUNNING", "feed_profile_id": "0", "placement_traffic_type": null, "optimization_goal_metadata": {}, "targeting_template_ids": null, "is_creative_optimization": null, "promotion_id": null, "promotion_ids": ["7834020372301"], "promotion_application_level": "AD_GROUP", "bid_multiplier": null, "ext_features": null, "bid_strategy_type": "AUTOMATIC_BID" } } ] }

Set up an item promotion

After you set up an item promotion, the assigned catalog item displays the promotional text.

Step 1: Create the item promotion

The endpoint, request, and response schema are identical to those for creating an ad group promotion.

Step 2: Assign the promotion to a catalog item

POST
Operate on item batch
Any parameters and code examples that appear in this section support this use case, but may not represent the full endpoint specification. See the endpoint reference page for the comprehensive spec.
Any parameters and code examples that appear in this section support this use case, but may not represent the full endpoint specification. See the endpoint reference page for the comprehensive spec.

Request parameters to keep in mind

Assign promo to item parameters
ParameterDescription
item_id

string
Required
Provide the unique identifier of the catalog item within your merchant's catalog namespace (the item's ID as it exists in your Pinterest catalog/merchant feed).
Pinterest uses this value to locate the exact product/item record you want to create/update in the batch request.
It should match the item's identifier used in your catalog ingestion.
It is not a Pinterest ad ID.
attributes.promotion_custom_id

string
Optional
Provide a custom identifier for the promotion to use for your own tracking, naming conventions, or mapping across systems.
If you do not provide it, Pinterest populates it automatically by copying the Pinterest-generated promotion ID.
Use it when you want a stable ID that matches your internal IDs or campaign taxonomy.

Example request

curl -X POST \ "https://api.pinterest.com/v5/catalogs/items/batch" \ -H "Authorization: Bearer pina_ABCD1234..." \ -H "Content-Type: application/json" \ -d '[ { "catalog_type": "RETAIL", "country": "US", "language": "en-US", "items": [ { "item_id": "8892825849758208664", "operation": "UPDATE", "attributes": { "promotion_id": "7834020368389" } } ] } ]'

Example response

{ "items": [ { "data": { "name": "Ad Group For Pin: 687195905986", "status": "ACTIVE", "budget_in_micro_currency": 5000000, "bid_in_micro_currency": 5000000, "optimization_goal_metadata": { "conversion_tag_v3_goal_metadata": { "attribution_windows": { "click_window_days": 0, "engagement_window_days": 0, "view_window_days": 0 }, "conversion_event": "PAGE_VISIT", "conversion_tag_id": "string", "cpa_goal_value_in_micro_currency": "string", "is_roas_optimized": false, "reporting_event": "string" }, "frequency_goal_metadata": { "frequency": 0, "timerange": "THIRTY_DAY" }, "scrollup_goal_metadata": { "scrollup_goal_value_in_micro_currency": "string" } }, "budget_type": "DAILY", "start_time": 5686848000, "end_time": 5705424000, "targeting_spec": { "AGE_BUCKET": ["18-24"], "APPTYPE": ["android_mobile"], "AUDIENCE_EXCLUDE": ["string"], "AUDIENCE_INCLUDE": ["string"], "GENDER": ["unknown"], "GEO": ["string"], "GEO_EXCLUDE": ["string"], "INTEREST": ["string"], "LOCALE": ["string"], "LOCATION": ["string"], "LOCATION_EXCLUDE": ["string"], "MAXIMUM_AGE": "string", "MINIMUM_AGE": "string", "SHOPPING_RETARGETING": [ { "lookback_window": 30, "exclusion_window": 14, "tag_types": [0, 6] } ], "TARGETING_STRATEGY": ["CHOOSE_YOUR_OWN"] }, "lifetime_frequency_cap": 100, "tracking_urls": { "audience_verification": ["string"], "buyable_button": ["string"], "click": ["string"], "engagement": ["string"], "impression": ["string"] }, "auto_targeting_enabled": true, "placement_group": "ALL", "pacing_delivery_type": "STANDARD", "campaign_id": "626736533506", "billable_event": "CLICKTHROUGH", "bid_strategy_type": "AUTOMATIC_BID", "placement_traffic_type": "ALL", "targeting_template_ids": ["643"], "is_creative_optimization": true, "promotion_id": "7834020347906", "promotion_ids": ["78340 (edited) [3:42 PM]20347906", "7834020347907"], "promotion_application_level": "ITEM", "ext_features": { "enabled": ["TRENDS"] }, "id": "2680060704746", "ad_account_id": "549755885175", "created_time": 1476477189, "updated_time": 1476477189, "type": "string", "conversion_learning_mode_type": "ACTIVE", "summary_status": "RUNNING", "feed_profile_id": "626736533506", "dca_assets": null, "bid_multiplier": 1, "exceptions": [ { "code": 0, "message": "string" } ] } } ] }

Step 3: Assign the item promotion to an ad group

POST
Create ad groups
PATCH
Update ad groups
Any parameters and code examples that appear in this section support this use case, but may not represent the full endpoint specification. See the endpoint reference page for the comprehensive spec.
Any parameters and code examples that appear in this section support this use case, but may not represent the full endpoint specification. See the endpoint reference page for the comprehensive spec.

Request parameters to keep in mind

Add item promo to ad group parameters
ParameterDescription
promotion_id

string
Optional but necessary for this use case
Identify the item promotion you want to assign to the ad group.
To clear this field, send an empty array:
[]
.
promotion_application_level

string, nullable
Optional but necessary for this use case
Set to
ITEM
for this use case.

Example request

curl -X POST \ "https://api.pinterest.com/v5/ad_accounts/123456789012/ad_groups" \ -H "Authorization: Bearer pina_ABCD1234..." \ -H "Content-Type: application/json" \ -d '[ { "campaign_id": "626756081487", "id": "2680086898355", "billable_event": "CLICKTHROUGH", "name": "update test ag 3-1", "promotion_id": "7834020347906", "promotion_application_level": "ITEM", "bid_in_micro_currency": 1000000, "targeting_spec": { "LOCATION": ["US"], "APPTYPE": ["web", "ipad", "web_mobile", "iphone", "android_mobile", "android_tablet"], "GENDER": ["female", "male", "unknown"] } } ]'

Example response

{ "items": [ { "data": { "id": "2680086898355", "created_time": 1754627687, "updated_time": 1771886766, "start_time": null, "end_time": null, "bid_in_micro_currency": null, "budget_in_micro_currency": null, "campaign_id": "626756081487", "ad_account_id": "549757102439", "auto_targeting_enabled": true, "type": "adgroup", "budget_type": "CBO_ADGROUP", "billable_event": "CLICKTHROUGH", "status": "ACTIVE", "lifetime_frequency_cap": -1, "targeting_spec": { "LOCATION": ["US"], "APPTYPE": ["web", "ipad", "web_mobile", "iphone", "android_mobile", "android_tablet"], "GENDER": ["female", "male", "unknown"] }, "name": "update test ag 3-1", "placement_group": "ALL", "pacing_delivery_type": "STANDARD", "tracking_urls": null, "conversion_learning_mode_type": null, "summary_status": "RUNNING", "feed_profile_id": "0", "placement_traffic_type": null, "optimization_goal_metadata": {}, "targeting_template_ids": null, "is_creative_optimization": null, "promotion_id": "7834020347906", "promotion_application_level": "ITEM", "bid_multiplier": null, "ext_features": null, "bid_strategy_type": "AUTOMATIC_BID" } } ] }

Using promotion types with template values

Structurally, some promotion types include placeholders for template values, which can be quantities, monetary values, or percentages, as in the following examples:
  • Buy 4, get 1 free
  • Spend $50, get $5
  • Up to 10% off plus free shipping
If you select a promotion type that requires a template value:
  1. Include the
    template_value
    parameter in your request.
  2. Within the
    template_value
    array, insert one or more of the following objects, depending on the requirements of the promotion type:
Template values table
Template value objectDescriptionExamples
number
Quantity or monetary incentive.
Buy 4...
...get $5
percent
Percentage incentive.
Up to 10% off plus free shipping
currency_code
Currency codes from ISO 4217.
Required for
number
values, where X or Y is money.
$
€
See the following table for
promotion_type
enums that require template values.
Promotions parameters table
ParameterDescriptionRequired template values
BONUS
Earn a $X bonus.
amount
(X=money)
currency_code
BUY_X_GET_ONE_FREE
Buy X, get one free.
amount
(X=quanity)
BUY_X_GET_Y
Buy X, get Y.
You cannot create this promotion in Ads Manager, but if you create it in the API, it will appear in Ads Manager.
amount
(X = money; Y=money or percent)
currency_code
CASH_BACK
Earn X% cash back.
percent
CHECKOUT
X off at checkout.
amount
(X = money or percent)
currency_code
(only for money amount)
EXTRA_PERCENT_OFF
Extra X% off sale.
percent
FIXED
X off.
amount
(if X=money)
percent
(if X=percent)
currency_code
(only for money amount)
FREE_SHIPPING
Free shipping.
None
FREE_SHIPPING_MINIMUM
Free shipping on $X+.
amount
(X=money)
currency_code
FREE_SHIPPING_WITH_DISCOUNT
Up to X% off plus free shipping.
percent
GIFT_WITH_FIRST_PURCHASE
Gift with first purchase.
None
GIFT_WITH_PURCHASE
Gift with purchase.
None
GIFT_WITH_PURCHASE_MINIMUM
Gift with purchase of $X+.
amount
(X=money)
currency_code
PERCENT_OFF_CLEARANCE
Extra X% off clearance.
percent
POINTS_ON_ALL_PURCHASES
Extra X points on all purchases.
amount
(X=quantity)
POINTS_WITH_PURCHASES
Get X points with purchases.
amount
(X=quantity)
SAVE_X_ON_Y
Save X on Y.
amount
(X=money or percent; Y=money)
currency_code
SITE_WIDE
X off sitewide.
amount
(if X=money)
percent
(if X=percent)
currency_code
(only for money amount)
SITE_WIDE_IN_STORES
Up to X% off plus free shipping.
percent
SPEND_X_SAVE_Y
Spend $X, save Y.
You cannot create this promotion in Ads Manager, but if you create it in the API, it will appear in Ads Manager.
amount
(X=money; Y=money or percent)
currency_code
VARIABLE
Up to X off.
amount
(X=money or percent)
currency_code
(only for money amount)
X_OFF_Y
X off Y.
amount
(X=money or percent; Y=money)
currency_code
Was this page helpful?