Banners (creatives) via API
API endpoints, curl examples and corner cases for banners: every placementType and bannerType, uploading or linking the creative file, files by URL and bulk landing-URL rewrites.
Banners — creatives — live inside a campaign. This page covers the banner endpoints, the placementType and bannerType values that decide what a banner is, which parameters carry each kind of creative, how to upload the creative file or hand it over by URL, and how to rewrite landing URLs in bulk. Examples append $AUTH, the hash-authentication parameters (an X-Api-Key header works the same), and send parameters form-encoded unless noted — see the API overview for authentication and Entities via API for the corner cases every entity shares.
Who this is for
Network managers and advertisers who create or update creatives from a script, and admins. Each banner type is gated by its own role permission, and several banner settings apply only with theirs — see the corner cases below.
Banners (creatives)
| Method | Path | Purpose |
|---|---|---|
| GET | /rest-api/banners.do | Paginated list (offset/limit, filters: campaignId, bannerName (part of the name, case-insensitive), approvalStatuses, labels, active, advertisingCategories, templateIds, placementTypes, bannerTypes, filter[…]; fields) |
| GET | /rest-api/banners/urls.do | Landing URL of each banner (bannerIds, optional advertisingCategories) as id / type / url — see Add a macro to every landing URL |
| POST | /rest-api/banners/urls.do | Set landing URLs banner by banner: JSON body [{"id":…,"url":"…"}]; answers updated and failures |
| GET | /rest-api/banner/{bannerId}.do | Get one banner |
| GET | /rest-api/campaign/{campaignId}/banners.do | Banners of one campaign |
| GET | /rest-api/campaign/banners/batch.do | Banners for multiple campaigns |
| POST | /rest-api/banner/create.do | Create — campaignId, bannerType and placementType are required |
| POST | /rest-api/banner/{bannerId}/update.do | Update |
| DELETE | /rest-api/banner/{bannerId}/delete.do | Delete |
| POST | /rest-api/banner/{bannerId}/{operation}/{campaignId}.do | Copy or move to another campaign (COPY / MOVE, plus copyCount, keepBannersLinked; COPY takes an optional name, see the campaign copy note) |
| POST | /rest-api/banner/{bannerId}/{operation}/bulk.do | Bulk copy/move to campaignIds |
Around them:
| Method | Path | Purpose |
|---|---|---|
| POST | /rest-api/banners/labels.do | Add, replace or remove labels on many banners — see Bulk labels |
| GET | /rest-api/banner/{bannerId}/video-compliance.do | For an uploaded video banner: the facts read from its file (size, duration, bitrate, codecs, loudness…) and, with the site video-requirements permission, whether it meets each linked site’s spec — see Video banners |
| GET | /rest-api/ad-units.do | Every ad unit with its size and the placement types it applies to (placementType filters). With placementType, width and height it answers the one unit a placement of that type and size is made in — the unit of exactly that size, else the type’s custom unit, else none |
| GET | /rest-api/banner/adunit/values.do, /rest-api/banners/{bannerType}/adunit/values.do | Valid ad-unit sizes |
| GET/POST | /rest-api/banners/urls.do | Read or batch-rewrite landing URLs — see below |
| POST | /rest-api/banner/{bannerId}/custom/parameters.do | Replace the banner’s custom key/value parameters (JSON body) |
| GET | /rest-api/banner/dspPartners.do | DSP partners available for OPENRTB_DSP creatives |
Create an externally-hosted image banner for standard web placements:
curl -X POST "https://<your-network-domain>/rest-api/banner/create.do?$AUTH" \
-d "campaignId=2001" \
-d "placementType=SITE_PLACEMENT" \
-d "bannerType=EXTERNAL_FILE" \
-d "name=Northwind Leaderboard 728x90" \
-d "imageBannerLink=https://cdn.northwind.example/leaderboard.png" \
-d "adUnitId=3" \
-d "url=https://www.northwind.example/landing" \
-d "target=_BLANK" \
-d "allowNewPlacementsAutoLinking=true" \
-d "linkToPlacements=true"
linkToPlacements=true links the banner to every placement its auto-linking rules match —
the banner’s own when allowNewPlacementsAutoLinking is on (narrowed by autolinkCategories
/ autoLinkLabels), otherwise its campaign’s. With auto-linking off on both, or without the
Link Placements to Banners or Auto-Linking Settings permission, the rest of the save goes
through, nothing is linked and linkToPlacements is listed in ignoredFields with the reason.
The size comes from adUnitId (ids from GET /rest-api/ad-units.do). Without it, as
above, adUnitWidth + adUnitHeight pick the ad unit of exactly that size for the
placementType, or its Custom unit sized to them when no unit matches. The same holds on
POST /rest-api/banner/{bannerId}/update.do; an update that sends none of the three keeps the
stored size, and a banner stored with a width and height but no ad unit gets the unit of that
size on its next update instead of failing with adUnitId: Required.
All fields, with descriptions and an example request:
POST /rest-api/banner/create.do and
POST /rest-api/banner/{bannerId}/update.do.
placementType — all eight values
| Value | Control-panel name |
|---|---|
SITE_PLACEMENT | Site Placement |
NON_STANDARD_SITE_PLACEMENT | Non-standard Placement |
MOBILE_SITE_PLACEMENT | Mobile Site Placement |
VIDEO_PLACEMENT | Video Placement |
APPLICATION_PLACEMENT | Application Placement |
EMAIL_PLACEMENT | Email Placement |
CLICK_THROUGH_PLACEMENT | Click-through Placement |
NATIVE_PLACEMENT | Native Placement (the label is white-label configurable) |
That is the complete enum; there is no ninth value.
bannerType — all twelve values
| Value | Control-panel name | Notes |
|---|---|---|
LOCAL_FILE | Local File | Uploaded image/HTML5 — see Uploading the creative file below |
EXTERNAL_FILE | External File | Creative hosted on your own CDN (imageBannerLink) |
CODE | HTML Code | Raw third-party tag (code) |
TEMPLATE | Template | Requires templateId |
OPENRTB_DSP | OpenRTB | Requires dspPartnerId |
LOCAL_NATIVE | Local Native | Native asset set, images uploaded |
EXTERNAL_NATIVE | External Native | Native asset set, images by URL |
LOCAL_VIDEO | Local Video | Video placements (and e-mail) |
EXTERNAL_VIDEO | External Video | Video placements (and e-mail) |
ADVANCED_LOCAL_VIDEOS | Advanced Local Video(s) (Beta) | Video placements |
VAST_2_0_TAG_URL | Third Party VAST/VPAID Tag URL | Video placements |
VPAID_FRAMEWORK | VPAID Framework | Requires vpaidFrameworkId |
That is the complete enum. Each type is also gated by its own role permission, so a type your role cannot use is rejected even though the API accepts the name.
Corner case: the API enum names differ from the labels in the control panel — an “Image banner” you upload in the UI is
LOCAL_FILE; one hosted on your CDN isEXTERNAL_FILE.
Corner case: a banner’s
weightis 1–32767, itsnameis never blank and at most 512 characters, andtargetTemplateNameat most 50; outside those an update is a400naming the field.custom/parameters.doapplies to native banners (EXTERNAL_NATIVE,LOCAL_NATIVE) only — on any other type it is a400rather than parameters nothing reads.
Corner case:
thirdTrackingCode[*]=<code>sets the banner’s third-party tracking code for every country andthirdTrackingCode[US]=<code>for one; an empty value removes it. The key is*or two letters, in any case — a country key is stored upper-case,GBasUK, as the tracking-code endpoints store it, sothirdTrackingCode[us]andthirdTrackingCode[US]are the same setting. Two letters is the whole check — unliketracking-code/banner/add.do, the key is not looked up in the country list. Any other key (thirdTrackingCode[usa],thirdTrackingCode[1]) is not applied and is listed inignoredFieldsasthirdTrackingCode[<key>]with the reason; the rest of the create or update is saved. The code needs the Banner Third-Party Tracking Code permission, as the console card andtracking-code/banner/add.dodo; without it every sent key is listed inignoredFieldsasnot permitted. External-video banners do not carry the code.
Uploading the creative file
create.do and update.do also accept the creative file itself, as a multipart
request — so LOCAL_* types can be created over the API, not only in the control panel:
| Multipart field | Used by |
|---|---|
imageFile | LOCAL_FILE image and HTML5 creatives |
videoFile | LOCAL_VIDEO and ADVANCED_LOCAL_VIDEOS |
nativeIconFile | LOCAL_NATIVE icon asset |
nativeImageFile | LOCAL_NATIVE main image asset |
nativeVideoFile | LOCAL_NATIVE video asset |
curl -X POST "https://<your-network-domain>/rest-api/banner/create.do?$AUTH" \
-F "campaignId=2001" -F "placementType=SITE_PLACEMENT" \
-F "bannerType=LOCAL_FILE" -F "name=Northwind Leaderboard 728x90" \
-F "adUnitId=3" -F "url=https://www.northwind.example/landing" \
-F "imageFile=@leaderboard-728x90.png"
Note: the generated reference lists these five fields as the endpoint’s
multipart/form-datarequest body, not among its query parameters. Send them as multipart parts, as in the example; every other parameter can travel in the same multipart request or in the query string.
Corner case:
bannerTypeandplacementTypeare not marked required in the spec, because of one exception, but a create without them is refused —400 {"success":false,"errors":{"error":"bannerType is required parameter"}}. The exception is a creative built from a self-serve prototype, which supplies both throughselfServeCampaignType.
Corner case: size comes from
adUnitIdfirst. Without it,adUnitWidth+adUnitHeightpick the unit of exactly that size (or the type’s Custom unit). When the unit is a Custom one — chosen by id or by size — both are required and set the banner’s size:400 adUnitWidth and adUnitHeight are required for Custom Ad Unit. AnadUnitIdthat is not an ad unit, or not one offered for the banner’s placement type, is a400naming it.
Creating each creative type without a file upload
Every type below is created with plain form parameters — no multipart. The types the console
builds from an uploaded file take the file by URL instead: the server downloads it once and
stores it exactly as the upload would have been stored (see Files by URL). The
EXTERNAL_* twins are different: they keep pointing at your hosted file at serve time.
| Creative | bannerType | placementType | Parameters that carry it |
|---|---|---|---|
| Image by URL | EXTERNAL_FILE | SITE_PLACEMENT, MOBILE_SITE_PLACEMENT, APPLICATION_PLACEMENT… | imageBannerLink (the image, hot-linked at serve time), url (the click), adUnitId or adUnitWidth + adUnitHeight |
| HTML / JavaScript | CODE | display types | code; adUnitId (or width + height) on site and video placements |
| VAST / VPAID tag | VAST_2_0_TAG_URL | VIDEO_PLACEMENT | vastTagUrl (older clients send the same value as url, which still works). No ad unit needed: video placements take the tag whatever its size; adUnitWidth + adUnitHeight are stored when you give them |
| Hosted video | EXTERNAL_VIDEO | VIDEO_PLACEMENT | videoFileLink, url |
| Template (rich media) | TEMPLATE | the template’s placement type | templateId, then one parameter per template property, named by its key — e.g. $$LANDING_URL$$=https://…. List templates with GET /rest-api/template/list.do and a template’s keys, types and required flags with GET /rest-api/template/{id}/properties.do. Text, URL, number, select and boolean properties need nothing else |
| HTML5 package | TEMPLATE | the template’s placement type | templateId plus html5ZipUrl — the URL of the creative’s ZIP archive, for a template with an HTML5 ZIP property (html5ZipUrl[<property key>] when it has several) |
| Template file (image, video) | TEMPLATE | the template’s placement type | templateId plus fileUrl — the URL of the file for the template’s FILE property (fileUrl[<property key>] when it has several); the file’s type must be one the property allows |
| Stored image | LOCAL_FILE | display types | imageFileUrl (downloaded and stored as the banner’s own file — the multipart-free imageFile), url (the click), adUnitId or adUnitWidth + adUnitHeight |
| Stored video | LOCAL_VIDEO | VIDEO_PLACEMENT | videoFileUrl (MP4 or FLV, up to the network’s video size limit — the multipart-free videoFile), url |
| Native by URL | EXTERNAL_NATIVE | NATIVE_PLACEMENT | iconUrl / imageUrl / videoUrl (hot-linked), title, description, callToAction, clickUrl |
| Stored native | LOCAL_NATIVE | NATIVE_PLACEMENT | nativeIconFileUrl / nativeImageFileUrl / nativeVideoFileUrl (downloaded and stored — the multipart-free nativeIconFile / nativeImageFile / nativeVideoFile), title, description, callToAction, clickUrl; iconWidth/iconHeight, imageWidth/imageHeight, videoWidth/videoHeight when you may set sizes |
| DSP | OPENRTB_DSP | any | dspPartnerId (from GET /rest-api/banner/dspPartners.do) |
# VAST tag
curl -X POST "https://<your-network-domain>/rest-api/banner/create.do?$AUTH" \
-d "campaignId=2001" -d "placementType=VIDEO_PLACEMENT" -d "bannerType=VAST_2_0_TAG_URL" \
-d "name=Summer Sale pre-roll" \
--data-urlencode "vastTagUrl=https://vast.example.net/vast?id=123"
# HTML5 creative from a hosted ZIP
curl -X POST "https://<your-network-domain>/rest-api/banner/create.do?$AUTH" \
-d "campaignId=2001" -d "placementType=SITE_PLACEMENT" -d "bannerType=TEMPLATE" \
-d "templateId=224" -d "name=Summer Sale HTML5 300x250" \
--data-urlencode "html5ZipUrl=https://cdn.example.com/creatives/summer-sale-300x250.zip"
# Image stored on the ad server (not hot-linked)
curl -X POST "https://<your-network-domain>/rest-api/banner/create.do?$AUTH" \
-d "campaignId=2001" -d "placementType=SITE_PLACEMENT" -d "bannerType=LOCAL_FILE" \
-d "adUnitWidth=300" -d "adUnitHeight=250" -d "name=Summer Sale 300x250" \
--data-urlencode "url=https://northwind.example.com/summer" \
--data-urlencode "imageFileUrl=https://cdn.example.com/creatives/summer-sale-300x250.png"
# Native with a stored icon and main image
curl -X POST "https://<your-network-domain>/rest-api/banner/create.do?$AUTH" \
-d "campaignId=2001" -d "placementType=NATIVE_PLACEMENT" -d "bannerType=LOCAL_NATIVE" \
-d "name=Northwind app install" -d "title=Northwind Notes" -d "callToAction=Install" \
--data-urlencode "clickUrl=https://northwind.example.com/app" \
--data-urlencode "nativeIconFileUrl=https://cdn.example.com/creatives/app-icon-128.png" \
--data-urlencode "nativeImageFileUrl=https://cdn.example.com/creatives/hero-1200x627.jpg"
Corner case: an
EXTERNAL_VIDEObanner’svideoFileLinkis read when the banner is saved: the host must answer with a video content type, and the video’s facts — the ones the banner’s Video info shows — are taken from the file. Anupdate.dothat keeps the link of a banner that already is an External Video, with those facts stored, does not read it again, so an unrelated update does not depend on the video’s host being up. A new link, a change of banner type, a banner with no stored facts orrefreshHostedFiles=truereads the link again, and a link that cannot be read is refused with Cannot get video by link.
Files by URL
| Parameter | Banner type | Stands in for the upload | Must be |
|---|---|---|---|
imageFileUrl | LOCAL_FILE | imageFile | an image (GIF, JPEG, PNG, SVG) within the network’s image size limit for the ad unit |
videoFileUrl | LOCAL_VIDEO | videoFile | a video (MP4, FLV) within the network’s video size limit (20 MB by default) |
nativeIconFileUrl / nativeImageFileUrl | LOCAL_NATIVE | nativeIconFile / nativeImageFile | GIF, JPEG, PNG or SVG; an animated GIF must match the icon/image size |
nativeVideoFileUrl | LOCAL_NATIVE | nativeVideoFile | MP4, at least videoWidth × videoHeight in the same orientation |
html5ZipUrl, html5ZipUrl[<key>] | TEMPLATE | the HTML5 ZIP property’s upload | a ZIP of at most 10 MB that unpacks within the archive limits |
fileUrl, fileUrl[<key>] | TEMPLATE | the FILE property’s upload | a content type the property allows |
Each file is downloaded once, when you create or update the banner, and then kept exactly as
the uploaded file would be — the same type, size and dimension checks, the same SVG sanitising,
the same storage and CDN — so the URL does not need to stay up afterwards. The type is read from
the file’s own bytes, not from the server’s Content-Type (the URL’s file name only settles bytes
that could be several things), and the stored file gets
the extension its content really has (an image named banner.png that is a JPEG is stored as
banner.jpg). The download is guarded: only http and https, only hosts that resolve to
public internet addresses (private, loopback, link-local and similar ranges are refused,
redirects included), a 10-second connect/stall timeout, 30 seconds in all and at most 3
redirects. The size cap is per kind: a video may be as large as the network’s video size limit
and never more than 100 MB; a template fileUrl file the larger of 10 MB and that limit (100 MB
at most); an HTML5 ZIP 10 MB; an image the console’s size limit for the ad unit.
On POST /rest-api/banner/{bannerId}/update.do the same parameters replace the stored file.
imageFileUrl replaces the image without deleteImage (the console’s delete-then-upload in one
step); the old file is removed after the save.
A refused file is a 400 whose errors names the parameter you sent — e.g.
{"success":false,"errors":{"imageFileUrl":"https://… is not an image: its content is text/html."}}.
The reasons: not an http/https URL, not a public host, larger than the limit, an HTTP error,
unreachable or too slow, not the kind of file the parameter takes, a URL on a banner type it does
not apply to (imageFileUrl applies to LOCAL_FILE banners only.), the URL together with an upload
of the same file, or a template property the template does not have. A check the upload path
itself makes (an image over the size limit, a GIF of the wrong size) is reported under the URL
parameter too. A template file of a type the property does not allow is reported under the
property’s key, as for an upload.
A placement’s native adapter template takes its FILE properties the same way:
fileUrl / fileUrl[<property key>] next to nativeAdapterTemplateId on
POST /rest-api/placements/update/*.do.
Corner case: a VAST banner created in the console stores no size at all. Over the API it now does the same unless you pass a size — earlier API-created VAST banners report
width/height0.
Corner case: native banners carry their assets and click in fields of their own (the Native rows of the table above) instead of
imageBannerLinkandurl. TheiconWidth/iconHeight,imageWidth/imageHeightandvideoWidth/videoHeightpairs are silently discarded for roles without the Native Banner Sizes permission.
Rewriting landing URLs in bulk
GET /rest-api/banners/urls.do returns the landing URL of every banner you can reach,
filterable by bannerIds and advertisingCategories. The POST on the same path takes a
JSON body — an array of {id, url} objects — and validates each URL before saving:
curl -X POST "https://<your-network-domain>/rest-api/banners/urls.do?$AUTH" \
-H "Content-Type: application/json" \
-d '[{"id":5001,"url":"https://www.northwind.example/landing?cid=$$CAMPAIGN_ID$$"}]'
Warning: this is the one endpoint on this page that takes JSON rather than form parameters. Sending it form-encoded produces
400 {"success":false,"message":"Request body is missing or not readable"}. The response reports per-banner errors, so a partial success is normal — read it, don’t assume every id in your array was written.
Corner case:
enableViewTrackingneeds Banner View Tracking;allowNewPlacementsAutoLinkingandautolinkCategoriesneed Auto-linking settings, andautoLinkLabelsneeds it plus Placement Labels. Without the permission the setting is left as stored, the rest of the create or update is saved, and the parameter is listed inignoredFieldsasnot permitted.
Corner case: a parameter that does not suit the banner’s type is not stored and comes back in
ignoredFieldswith the reason does not apply to a<bannerType>banner on a<placementType>: the DSP settings (dspPartnerId,usePlacementSize,always2ndPrice,advertisingNetworkParameters[…]) on anything butOPENRTB_DSP,vastTagUrland thevast40Wrapper*flags on anything butVAST_2_0_TAG_URL,imageBannerLinkon anything butEXTERNAL_FILE,customParameterson a non-native banner,clickUrlon a banner that is neither native nor on a native placement,titleon a type that has none,returnAsIframeoff a video placement,thirdTrackingCode[…]onEXTERNAL_VIDEOanddirectFileDownloadoff an Android application banner. The rest of the save goes through.