Upload a Creative
Upload your first Creative using IQM's API in this step-by-step Quickstart Guide.
The following endpoints will be used to upload a Creative:
POSTGET
POST
GET
About IQM Creatives
The IQM APIs provide access to upload a Creative in Image, Video, Audio, HTML, XLSX, or CSV formats. The APIs can be used to connect to the desired applications.
More Resources
- Creatives and Specifications Help Center Article
- Creative API Guidelines
Before You Begin
To upload a Creative and create a Campaign, the following are required:
- An Account On the IQM Platform
- See Getting Started section to create an account and request a Client ID and Client Secret
- Image, Video, Audio, HTML, VAST, DAAST, CSV, or XLSX File to Upload Creative
File requirements for Creative file:
- 2MB for JPG, JPEG, PNG
- 750KB for GIF
- 400MB for MOV, MP4
- 100MB for MP3, WAV, OGG, MPEG
For more information on VAST and DAAST XML format specifications, please see IAB Tech Lab's Documentation.
Sample CSV file: https://app.iqm.com/creatives/example-files/sample_html_creatives.csv
Authentication
Use the following header parameters for all requests after logging in:
| Headers | |
|---|---|
Authentication string required | Authentication bearer token See Authentication Guide |
X-IAA-OW-ID integer required | Organization Workspace ID Header |
Upload a Creative Using the IQM API
This Quickstart Guide will cover how to create a Campaign and upload a Creative.
The minimum requirements to perform this task are: logging in with authentication credentials, uploading a Creative, and creating a Campaign. Once these steps are accomplished, more can be learned about IQM's API through the Guidelines pages.
- Log In
- Optional if you have already logged in and have a token
- Request Creative Types
- Optional if you already know supported/desired types
- Upload Creative File
- Check Creative Status
Step 1: Log In
POSTTo log in, the Authentication: Basic header is required. The Login API returns an OAuth-compliant response with an Organization Workspace ID (owId), a unique identifier for each Organization. This ID will be used for any further API communications.
For further information see the complete OAuth API Documentation.
| Headers | |
|---|---|
Authentication string required | Authentication bearer token See Authentication Guide |
| Request Schema | |
|---|---|
grantType string required | OAuth Grant Types |
email string required | User account email |
password string required | User account password |
- JSON
- TypeScript
{
"grantType": "password",
"email": "pratik.t+ihp@iqm.com",
"password": "123456"
}
{
"success": true,
"data":
{
"access_token": "106adb25-37b0-4cab-8381-d682fe7cc3c8",
"refresh_token": "eac4c1f6-781e-4b04-baff-9c2e415d1f64",
"scope": "read write",
"token_type": "bearer",
"expires_in": 35999,
"owId": 200001
}
}
More Responses
{
"success": false,
"data":
{
"status": "On Hold",
"reason": "The particular account is kept on hold due to missed payment dates for last 3 months.",
"supportEmail": "support@iqm.com"
},
"errorObjects":
[
{
"error": "User is not allowed to access provided customer",
"reason": "User is not associated with any active organization."
}
]
}
{
"success": false,
"errorObjects":
[
{
"error": "User doesn't exist or user is not allowed to provided workspace."
}
]
}
See TypeScript Prerequisites page for usage.
import {
getInstance
} from "prerequisites"
const axios = getInstance();
interface Responses {
200: {
content: {
"application/json": {
success: boolean;
data: {
access_token: string;
refresh_token: string;
scope: string;
token_type: string;
expires_in: number;
owId: number;
};
};
};
};
400: {
content: {
"application/json": {
success: boolean;
data: {
status: string;
reason: string;
supportEmail: string;
};
errorObjects: {
error: string;
reason: string;
}[];
};
};
};
403: {
content: {
"application/json": {
success: boolean;
errorObjects: {
error: string;
}[];
};
};
};
};
function Login(): Promise < Responses > {
const options = {
method: 'POST',
url: 'https://api.iqm.com/api/v3/ua/login',
requestBody: {
content: {
"application/json": {
email: `string`,
password: `string`,
}
}
}
};
return axios.request(options).then(({ data }: { data: Responses }) => data);
}
Step 2: Request Creative Types
GETTo upload a Creative, a Creative Type must be provided. Use the Creative Type list endpoint to request a full list of allowed Creative Types.
For further information see the complete Creative Types API Documentation.
- JSON
- TypeScript
{
"success": true,
"data": {
"data": [
{
"id": 17,
"name": "Audio",
"rtbTypeId": 2
},
{
"id": 15,
"name": "Native",
"rtbTypeId": 4
},
{
"id": 14,
"name": "Video",
"rtbTypeId": 3
},
{
"id": 13,
"name": "HTML",
"rtbTypeId": 1
},
{
"id": 11,
"name": "Image",
"rtbTypeId": 1
}
],
"totalRecords": 5,
"filteredRecords": 5
}
}
More Responses
{
"statusCode": 500,
"responseObject": {
"errorMsg": "Internal server error",
"errorCode": 500
}
}
See TypeScript Prerequisites page for usage.
import {
getInstance
} from "prerequisites"
const axios = getInstance();
interface Responses {
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
success: boolean;
data: {
id: number;
label: string;
rtbTypeId: string;
}[];
totalRecords: number;
filteredRecords: number;
}
};
};
};
function getCreativeTypes_1(): Promise < Responses > {
const options = {
method: 'GET',
url: 'https://api.iqm.com/api/v3/master/creativeTypes',
params: {
query?: {
creativeTypeIds?: `string`,
ids?: `string`,
pageNo?: `number`,
noOfEntries?: `number`,
sortBy?: `string`,
order?: `string`,
searchField?: `string`
}
}
};
return axios.request(options).then(({ data }: { data: Responses }) => data);
}
Step 3: Upload a Creative
POSTOnce you have the desired Creative Type ID, you can upload a Creative. With the two request parameters, creativeRequest and creativeFiles, you will add the Creative metadata and the Creative file respectively.
creativeRequest maps an ID to fields defining the Creative metadata outlined in the table below and shown as an example in the Request Sample code block in the right-hand column.
creativeFiles are added as multipart format. See the MDN Documentation on Multipart/form-data encoding for more information.
| Request Schema | |
|---|---|
creativeRequestform data required | This parameter accepts a Map of IDs to Creative metadata. Each ID corresponds to a single Creative. |
creativeFilesmultipart/form-data | Array of Creative files to upload. Required only when Creative source type is FILE in the Creative metadata. Each uploaded file's name must exactly match the creativeSource value specified in the corresponding Creative object. Supports multiple file uploads for batch Creative creation. Accepted file types include images (JPEG, PNG, GIF), videos (MP4, WebM), and audio (MP3, WAV, OGG). |
Creative Metadata
creativeName string | Creative name | ||||||||||||||||||||||||||||
externalCreativeId string | External Creative ID | ||||||||||||||||||||||||||||
platformCreativeTypeId integer | Creative Type ID | ||||||||||||||||||||||||||||
creativeSourceType string | Creative source type Supported values: HTML, FILE, URL, VAST_URL, VAST_XML, DAAST_URL, DAAST_XML | ||||||||||||||||||||||||||||
creativeSource string | Creative source | ||||||||||||||||||||||||||||
clickUrl string | Click URL | ||||||||||||||||||||||||||||
subMediaType integer | Subcategory of media type (for native video creatives) | ||||||||||||||||||||||||||||
htmlDetails object | HTML Creative details | ||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
creativeWidth integer | Creative width (px) |
creativeHeight integer | Creative height (px) |
imageDetails object
imageDetails object properties
pixelUrl string | Pixel URL |
creativeWidth integer | Creative width (px) |
creativeHeight integer | Creative height (px) |
audioDetails object
audioDetails object properties
duration integer | Audio duration (s) | ||||||||||||
customTracking object | Custom tracking details | ||||||||||||
| |||||||||||||
startUrl string | Start URL |
firstQuartileUrl string | First quartile URL |
midPointUrl string | Midpoint URL |
thirdQuartileUrl string | Third quartile URL |
completeUrl string | Complete URL |
impressionUrl string | Impression URL |
logoSource string
videoDetails object
videoDetails object properties
creativeWidth integer | Creative width (px) | ||||||||||||
creativeHeight integer | Creative height (px) | ||||||||||||
duration integer | Video duration (s) | ||||||||||||
customTracking object | Custom tracking details | ||||||||||||
| |||||||||||||
startUrl string | Start URL |
firstQuartileUrl string | First quartile URL |
midPointUrl string | Midpoint URL |
thirdQuartileUrl string | Third quartile URL |
completeUrl string | Complete URL |
impressionUrl string | Impression URL |
nativeDetails object
nativeDetails object properties
title string | Title | ||||||
description string | Description | ||||||
cta object | Call-to-Action object details (for native video) | ||||||
| |||||||
id integer | CTA ID |
ctaText string | CTA display text |
defaultCta boolean | Default CTA for associated Creative |
brandName string
brandIconSourceUrl string
brandIconHeight integer
brandIconWidth integer
thumbnailSourceUrl string
thumbnailHeight integer
thumbnailWidth integer
Response Properties
successData object | Success data | |||
| ||||
PS string | Partial success |
failedData object
failedData object properties
PF string | Partial failure |
POST /api/v3/crt/creatives HTTP/1.1
Host: https://api.iqm.com
Authorization: Bearer YOUR_TOKEN_HERE
X-IAA-OW-ID: 12345
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="creativeRequest"
{"I001":{"creativeName":"Summer Sale Banner","externalCreativeId":"campaign-2024-001","platformCreativeTypeId":11,"creativeSourceType":"FILE","creativeSource":"summer-banner.jpg","clickUrl":"https://www.example.com/summer-sale","imageDetails":{"pixelUrl":"https://tracker.example.com/pixel","creativeWidth":728,"creativeHeight":90}},"V001":{"creativeName":"Product Demo Video","externalCreativeId":"campaign-2024-002","platformCreativeTypeId":14,"creativeSourceType":"FILE","creativeSource":"product-demo.mp4","clickUrl":"https://www.example.com/products","videoDetails":{"creativeWidth":1920,"creativeHeight":1080,"duration":30,"customTracking":{"startUrl":"https://tracker.example.com/start","firstQuartileURL":"https://tracker.example.com/25","midPointURL":"https://tracker.example.com/50","thirdQuartileURL":"https://tracker.example.com/75","completeURL":"https://tracker.example.com/complete","impressionURL":"https://tracker.example.com/impression"}}},"H001":{"creativeName":"Interactive HTML Ad","platformCreativeTypeId":13,"creativeSourceType":"HTML","creativeSource":"<a href='https://example.com'><img src='https://cdn.example.com/ad.jpg'></a>","clickUrl":"https://www.example.com","htmlDetails":{"creativeWidth":300,"creativeHeight":250}}}
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="creativeFiles"; filename="summer-banner.jpg"
Content-Type: image/jpeg
[Binary image data]
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="creativeFiles"; filename="product-demo.mp4"
Content-Type: video/mp4
[Binary video data]
------WebKitFormBoundary7MA4YWxkTrZu0gW--
{
"success": true,
"data": {
"successData": {
"PS": "701388"
},
"failedData": {
"PF": "Creative file missing. Please attach the required file. : null"
}
}
}
Step 4: Check Creative Status
GETThis API checks a Creative's status. Use the creativeId (6 digit number under data parameter in response) retrieved from the previous step to get its details.
The Creative details endpoint returns a Status ID (highlighted in code sample). A status ID of 2 means the Creative is running.
| Path Parameter | |
|---|---|
creativeId array of integers | Creative ID |
- JSON
- TypeScript
{
"success": true,
"data": {
"creativeId": 686855,
"creativeName": "300x600-w23-01",
"rtbCreativeTypeId": 1,
"platformCreativeTypeId": 11,
"creativeStatusId": 2,
"creativeSource": "https://d3jme5si7t6llb.cloudfront.net/image/202760/efk0sUk_1730201855013.jpg",
"creativeCardSource": "https://d3jme5si7t6llb.cloudfront.net/Screenshots/202760/278x220/efk0sUk_1730201855013.jpg",
"clickUrl": "http://iqm.com",
"imageDetails": {
"pixelUrl": "http://pixel.com",
"creativeWidth": 300,
"creativeHeight": 600
},
"creativeSourceType": "file",
"creativePreviewFlag": 1,
"createdAt": 1730201855165,
"modifiedAt": "2024-10-29T06:10:15.000+00:00",
"userDetails": {
"uowId": 175891,
"userName": "Hardik",
"userEmail": "hardik.v+iqmsuper@iqm.com",
"hasApprovalAccess": true,
"hasEditAccess": true
},
"organizationDetails": {
"owId": 202760,
"organizationName": "AdWing"
}
}
}
See TypeScript Prerequisites page for usage.
import {
getInstance
} from "prerequisites"
const axios = getInstance();
interface Responses {
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
success: boolean;
data: {
creativeId: number;
creativeName: string;
rtbCreativeTypeId: number;
platformCreativeTypeId: number;
creativeStatusId: number;
creativeSource: string;
creativeCardSource: string;
clickUrl: string;
imageDetails: {
pixelUrl: string;
creativeWidth: number;
creativeHeight: number;
};
creativeSourceType: string;
creativePreviewFlag: number;
createdAt: number;
modifiedAt: number;
userDetails: {
uowId: number;
userName: string;
userEmail: string;
hasApprovalAccess: boolean;
hasEditAccess: boolean;
};
organizationDetails: {
owId: number;
organizationName: string
}
}
};
};
};
}
function getCreative(): Promise<Responses> {
const options = {
method: 'GET',
url: 'https://api.iqm.com/api/v3/crt/creatives/{creativeId}',
params: {
path: {
creativeId: `number`
}
}
};