Create a promotion
const url = 'https://api.tryletterhead.com/api/v3/promotions';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"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}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
true for API-key auth. Auto-detected from the token shape.
Internal name of the campaign
Slugs of channels to scope to. null/omitted means all channels. Required when allChannels: false is sent explicitly.
Display headline of the ad
Body copy
Publicly accessible image URL
Alt text for accessibility
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.
Display name of the advertiser
Y-m-d dates when the promotion runs. Ignored at send time if isEvergreen: true.
true = scheduled/live, false = draft
true = always runs, dates are ignored at send time
Template position. One of A, B, C, D, E, F, G, H, I, J. Defaults to A if omitted.
Template type: 1=Text only, 2=Text & Image, 4=Banner, 7=HTML
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}Responses
Section titled “ Responses ”201 Created
object
object
object
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
object
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.