Skip to content
Letterhead Letterhead Letterhead Help Center
Admin Tools

Create a promotion

POST
/api/v3/promotions
curl --request POST \
--url https://api.tryletterhead.com/api/v3/promotions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "api": true, "campaignTitle": "Summer Sale 2026", "channels": [ "an-example-channel" ], "headline": "50% off summer collection", "contentText": "Limited-time offer on all summer items.", "imageUrl": "https://cdn.example.com/summer-sale.png", "imageAlternativeText": "Summer sale banner", "promotionLink": "https://example.com/summer-sale", "promoter": "Example Brand", "dates": [ "2026-07-01", "2026-07-08", "2026-07-15" ], "isActive": true, "isEvergreen": false, "zone": "A", "type": 2 }'

Create a new promotional campaign on the company. The campaign lands ready for the scheduled dates (or evergreen if isEvergreen: true).

v3 endpoints expect a company API key. The Bearer token is auto-detected as an API key when its shape isn’t a JWT, so callers don’t need any extra flag — sending the "api": true field in the body is supported for consistency with the rest of the Letterhead API but optional for this endpoint specifically.

Media type application/json
object
api

true for API-key auth. Auto-detected from the token shape.

boolean
campaignTitle
required

Internal name of the campaign

string
channels

Slugs of channels to scope to. null/omitted means all channels. Required when allChannels: false is sent explicitly.

Array<string>
headline

Display headline of the ad

string
contentText

Body copy

string
imageUrl

Publicly accessible image URL

string
imageAlternativeText

Alt text for accessibility

string
promotionLink

Click-through destination. Must be http(s). Ad-server macros (${GDPR}, ${GDPR_CONSENT_755}) and merge-tag placeholders ({{ profileFieldName }}) are allowed and pass through unmodified.

string
promoter

Display name of the advertiser

string
dates

Y-m-d dates when the promotion runs. Ignored at send time if isEvergreen: true.

Array<string>
isActive
required

true = scheduled/live, false = draft

boolean
isEvergreen

true = always runs, dates are ignored at send time

boolean
zone

Template position. One of A, B, C, D, E, F, G, H, I, J. Defaults to A if omitted.

string
type
required

Template type: 1=Text only, 2=Text & Image, 4=Banner, 7=HTML

integer
Example
{
"api": true,
"campaignTitle": "Summer Sale 2026",
"channels": [
"an-example-channel"
],
"headline": "50% off summer collection",
"contentText": "Limited-time offer on all summer items.",
"imageUrl": "https://cdn.example.com/summer-sale.png",
"imageAlternativeText": "Summer sale banner",
"promotionLink": "https://example.com/summer-sale",
"promoter": "Example Brand",
"dates": [
"2026-07-01",
"2026-07-08",
"2026-07-15"
],
"isActive": true,
"isEvergreen": false,
"zone": "A",
"type": 2
}

201 Created

Media type application/json
object
items
object
promotionCollateralUid
string
campaignTitle
string
channels
Array<string>
allChannels
boolean
headline
string
contentText
string
imageUrl
string
imageAlternativeText
string
imageWidth
integer
imageHeight
integer
promotionLink
string
promoter
string
promotionServiceProviderId
integer
dates
Array<object>
object
isActive
boolean
isInactive
boolean
isEvergreen
boolean
embedClicks
integer
zone
string
type
integer
createdAt
string
updatedAt
string
message
string
total
integer
Example
{
"items": {
"promotionCollateralUid": "b2c3d4e5f6",
"campaignTitle": "Summer Sale 2026",
"channels": [
"news-daily"
],
"allChannels": false,
"headline": "50% off summer collection",
"contentText": "",
"imageUrl": "",
"imageAlternativeText": "",
"imageWidth": 0,
"imageHeight": 0,
"promotionLink": "",
"promoter": "",
"promotionServiceProviderId": 0,
"dates": [],
"isActive": true,
"isInactive": false,
"isEvergreen": false,
"embedClicks": 0,
"zone": "A",
"type": 2,
"createdAt": "2026-06-04 17:30:00",
"updatedAt": "2026-06-04 17:30:00"
},
"message": "Promotion created successfully",
"total": 1
}

400 Validation Error

Media type application/json
object
items
Array<string>
message
string
total
integer
Example
{
"items": [
"The campaign title field is required.",
"The zone field is required."
],
"message": "Invalid request data",
"total": 0
}

Still can’t find what you need? Contact support.