
| Promotion level | Supported campaign objectives | Scope | Use case |
|---|---|---|---|
| Ad group | CONSIDERATIONCONVERSIONCATALOG_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. |
CATALOG_SALESSALESCATALOG_SALESSALES| Parameter | Description |
|---|---|
external_idstring Optional | Provide an identifier from the platform or system that originated the promotion. |
promotion_custom_idstring 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_typestring Optional | Indicate which integration platform is creating the promotion or is considered its source. If your app is integrated with Shopify, pass SHOPIFYDEFAULT |
promotion_titlestring 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_codestring Optional | Provide a code that users can enter to redeem a promotion. |
start_timeinteger 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_timeinteger 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_typestring Required | Set to determine the displayed promotion text along with what parameters (if any) are needed to complete the template. |
promotion_typestring Required | Set to determine the displayed promotion text along with what parameters (if any) are needed to complete the template. |
template_valuesstring Optional but necessary for certain promotion_type | Provide quantities, monetary values, or percentages for certain promotion_type |
discount_statusstring Optional | Indicates current lifecycle state of a promotion's discount, computed from the current time and the discount's configured start_timeend_timeIt helps you determine whether the discount should be considered in effect right now. Enums:
OTHERACTIVEPAUSEDSCHEDULEDEXPIRED |
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" } ]'
id{ "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 } ] }
| Parameter | Description |
|---|---|
promotion_idsarray 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_levelstring, nullable Optional but necessary for this use case | Set to AD_GROUP |
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"] } } ]'
{ "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" } } ] }
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"] } } ]'
{ "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" } } ] }
| Parameter | Description |
|---|---|
item_idstring 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_idstring 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. |
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" } } ] } ]'
{ "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" } ] } } ] }
| Parameter | Description |
|---|---|
promotion_idstring 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_levelstring, nullable Optional but necessary for this use case | Set to ITEM |
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"] } } ]'
{ "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" } } ] }
template_valuetemplate_value| Template value object | Description | Examples |
|---|---|---|
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 | $ € |
promotion_type| Parameter | Description | Required template values |
|---|---|---|
BONUS | Earn a $X bonus. | amountcurrency_code |
BUY_X_GET_ONE_FREE | Buy X, get one free. | amount |
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. | amountcurrency_code |
CASH_BACK | Earn X% cash back. | percent |
CHECKOUT | X off at checkout. | amountcurrency_code |
EXTRA_PERCENT_OFF | Extra X% off sale. | percent |
FIXED | X off. | amountpercentcurrency_code |
FREE_SHIPPING | Free shipping. | None |
FREE_SHIPPING_MINIMUM | Free shipping on $X+. | amountcurrency_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+. | amountcurrency_code |
PERCENT_OFF_CLEARANCE | Extra X% off clearance. | percent |
POINTS_ON_ALL_PURCHASES | Extra X points on all purchases. | amount |
POINTS_WITH_PURCHASES | Get X points with purchases. | amount |
SAVE_X_ON_Y | Save X on Y. | amountcurrency_code |
SITE_WIDE | X off sitewide. | amountpercentcurrency_code |
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. | amountcurrency_code |
VARIABLE | Up to X off. | amountcurrency_code |
X_OFF_Y | X off Y. | amountcurrency_code |