Creatives are uploaded to a campaign using POST /campaigns/{campaignId}/creatives. The API supports four upload methods depending on your content type.
Using the TypeScript SDK?
The SDK handles uploads automatically. Pass url, tag, file (local path), or data (Buffer/Uint8Array) and the SDK picks the right method. See the SDK docs .
All upload methods require these headers:
Header Description X-API-KeyYour API key Acceptapplication/jsonContent-TypeVaries by method (see below) X-FilenameOptional. Sets the display name in the Advalidation UI. Defaults to a timestamp-based name if omitted.
Content-Type: application/json
Best for: URLs, HTML tags, VAST tags, and other text-based content.
Send the content in a payload field:
curl -X POST https://app.advalidation.io/v2/campaigns/CAMPAIGN_ID/creatives \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key-here" \
-H "X-Filename: Interactive.html" \
-d '{"payload": "<iframe src=\"https://labs.advalidation.net/animation/10s/\" style=\"border:0; width:300px; height:250px;\" scrolling=\"no\"></iframe>"}' const response = await fetch (
` ${ BASE_URL } /campaigns/ ${ campaignId } /creatives` ,
{
method : "POST" ,
headers : {
... headers,
"Content-Type" : "application/json" ,
"X-Filename" : "Interactive.html" ,
},
body : JSON . stringify ({
payload :
'<iframe src="https://labs.advalidation.net/animation/10s/" style="border:0; width:300px; height:250px;" scrolling="no"></iframe>' ,
}),
}
);
const { data } = await response. json ();
const creativeId = data[ 0 ]. id ;
Content-Type: application/json
Best for: Binary files (images, videos, ZIP archives) when you need to use JSON.
Encode the file as a base64 string and send it in the payload field:
BASE64 = $( base64 < ./creative.mov )
curl -X POST https://app.advalidation.io/v2/campaigns/CAMPAIGN_ID/creatives \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key-here" \
-H "X-Filename: creative.mov" \
-d "{ \" payload \" : \" $BASE64 \" }" import { readFile } from "node:fs/promises" ;
const file = await readFile ( "./creative.mov" );
const base64 = file. toString ( "base64" );
const response = await fetch (
` ${ BASE_URL } /campaigns/ ${ campaignId } /creatives` ,
{
method : "POST" ,
headers : {
... headers,
"Content-Type" : "application/json" ,
"X-Filename" : "creative.mov" ,
},
body : JSON . stringify ({ payload : base64 }),
}
);
Content-Type: text/plain
Best for: Raw HTML files or plain text content.
Send the file content directly as the request body:
curl -X POST https://app.advalidation.io/v2/campaigns/CAMPAIGN_ID/creatives \
-H "Accept: application/json" \
-H "Content-Type: text/plain" \
-H "X-API-Key: your-api-key-here" \
-H "X-Filename: creative.html" \
--data-binary @./creative.html import { readFile } from "node:fs/promises" ;
const content = await readFile ( "./creative.html" , "utf8" );
const response = await fetch (
` ${ BASE_URL } /campaigns/ ${ campaignId } /creatives` ,
{
method : "POST" ,
headers : {
... headers,
"Content-Type" : "text/plain" ,
"X-Filename" : "creative.html" ,
},
body : content,
}
);
Content-Type: application/octet-stream
Best for: ZIP archives, images, videos, and other binary files. Most efficient for large files since there is no encoding overhead.
Send the raw file bytes as the request body:
curl -X POST https://app.advalidation.io/v2/campaigns/CAMPAIGN_ID/creatives \
-H "Accept: application/json" \
-H "Content-Type: application/octet-stream" \
-H "X-API-Key: your-api-key-here" \
-H "X-Filename: creative.zip" \
--data-binary @./creative.zip import { readFile } from "node:fs/promises" ;
const file = await readFile ( "./creative.zip" );
const response = await fetch (
` ${ BASE_URL } /campaigns/ ${ campaignId } /creatives` ,
{
method : "POST" ,
headers : {
... headers,
"Content-Type" : "application/octet-stream" ,
"X-Filename" : "creative.zip" ,
},
body : file,
}
);
Method Content-Type Encoding overhead Best for JSON payload application/jsonNone (text) URLs, HTML tags, VAST tags JSON base64 application/json~30% larger Binary files when JSON is required Plain text text/plainNone Raw HTML files Binary application/octet-streamNone ZIP, images, videos (most efficient)