Upload a Matched Audience
Upload a Matched Audience with this in-depth Tutorial using IQM's API.
Get started uploading a matched audience with the following endpoints:
POSTPOST
POST
GET
About IQM Matched Audience
The Audience API allows you to upload an Audience for matching in XLSX or CSV format. Once uploaded and processed, the matched Audience can be used for advertising Campaign targeting.
More Resources
- Matched Audience Help Center article
- Audience API Guidelines
Before You Begin
To upload Matched Audience, 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
- CSV or XLSX File for Matching
File requirements for Audience matching:
- CSV or XLSX file for Audience matching with maximum 1GB or 5M records
- Without Voter ID / Email / Phone / Address in the file
- One of the following system field combinations is required for matching
- First Name, Last Name, Zip, State
- Last Name, Street Address, Zip, State
- Street Address, Zip, state
- Other fields are optional and can be added along with the above fields
- One of the following system field combinations is required for matching
- With Voter ID / Email / Phone / Address in the file
- Only one of these fields is required - Voter ID or Email or Phone, or Address. The preferred format for full address is Street, City, Zip, and State
- Other fields are optional and can be added along with one of the above fields
Upload Matched Audience Using the IQM API
This Quickstart Guide will cover how to create a matched Audience.
The minimum requirements to perform this task are: logging in with authentication credentials, selecting columns for matching, and uploading an Audience. 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 Column List
- Optional if you already know desired/supported columns
- Upload Matched Audience
- Upload the Audience with parameters from the previous steps
- Check Audience Status
- Matched Audience requires processing and approval before it can be used for targeting
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 |
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: Audience Request Properties
GETGET
GET
GET
GET
To upload a matched Audience, you will need to gather some information about your Audience and file to fill in the required parameters for the upload endpoint. These include:
| Parameter | Description |
|---|---|
| Audience subtype ID Healthcare vertical | The Audience subtype ID for the Matched Audience being uploaded. See Audience Subtype List endpoint for more details. |
| Column IDs for matching | A list of column IDs for matching which correspond to the columns in the file being uploaded. See Matched Audience Column List endpoint for more details. |
| Data format ID | The data format ID corresponds to the type of identifiers being uploaded. See Data Format List endpoint for more details. |
| Data partner ID | The data partner ID corresponds to the source of the data being uploaded and is used for reporting purposes. See Data Partner List endpoint for more details. |
| Column combination ID Political vertical | The column combination ID corresponds to the combination of columns being used for matching. See Matched Column Combinations endpoint for more details. |
- JSON
- TypeScript
{
"success": true,
"data": [
{
"id": 1,
"label": "Voter ID",
"key": "Voters_ID",
"order": 1,
"isSingleColumn": true
},
{
"id": 26,
"label": "NPI ID",
"key": "NPI_ID",
"order": 2,
"isSingleColumn": true
},
{
"id": 2,
"label": "Email",
"key": "Email",
"order": 3,
"isSingleColumn": true
},
{
"id": 3,
"label": "Phone",
"key": "Phone",
"order": 4,
"isSingleColumn": true
},
{
"id": 4,
"label": "Full Address",
"key": "Residence_FullAddress",
"order": 5,
"isSingleColumn": true
},
{
"id": 5,
"label": "First Name",
"key": "Voters_FirstName",
"order": 6,
"isSingleColumn": false
},
{
"id": 6,
"label": "Last Name",
"key": "Voters_LastName",
"order": 7,
"isSingleColumn": false
},
{
"id": 7,
"label": "Zip",
"key": "Residence_Addresses_Zip",
"order": 8,
"isSingleColumn": false
},
{
"id": 8,
"label": "State",
"key": "Residence_Addresses_State",
"order": 9,
"isSingleColumn": false
},
{
"id": 9,
"label": "Street Address",
"key": "Residence_Addresses_AddressLine",
"order": 10,
"isSingleColumn": false
},
{
"id": 10,
"label": "Full Name",
"key": "Voters_FullName",
"order": 11,
"isSingleColumn": false
},
{
"id": 11,
"label": "City",
"key": "Residence_Addresses_City",
"order": 12,
"isSingleColumn": false
},
{
"id": 12,
"label": "ZipPlus4",
"key": "Residence_Addresses_ZipPlus4",
"order": 13,
"isSingleColumn": false
},
{
"id": 13,
"label": "Age",
"key": "Voters_Age",
"order": 14,
"isSingleColumn": false
},
{
"id": 14,
"label": "Gender",
"key": "Voters_Gender",
"order": 15,
"isSingleColumn": false
},
{
"id": 15,
"label": "Ethnicity",
"key": "Ethnic_Description",
"order": 16,
"isSingleColumn": false
},
{
"id": 16,
"label": "Latitude",
"key": "Residence_Addresses_Latitude",
"order": 17,
"isSingleColumn": false
},
{
"id": 17,
"label": "Longitude",
"key": "Residence_Addresses_Longitude",
"order": 18,
"isSingleColumn": false
}
]
}
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;
key: string;
order: number;
isSingleColumn: boolean;
}[];
}
};
};
};
function getMatchedAudienceColumnList(): Promise < Responses > {
const options = {
method: 'POST',
url: 'https://api.iqm.com/api/v3/audience/static/column-list',
};
return axios.request(options).then(({ data }: { data: Responses }) => data);
}
Step 3: Upload Matched Audience
POSTCreate a Matched Audience by uploading a file with user data. The metadata is sent as a JSON string in the audienceRequest form data field, and the file is uploaded as multipart/form-data in the file form data field.
| Request Schema | |
|---|---|
audienceRequest form data required | Audience metadata details |
file multipart/form-data required | File to be uploaded |
audienceRequest Properties
audienceName string | Audience Name | |||||||
fileRowCount integer | Number of rows in the file | |||||||
fileColumnCount integer | Number of columns in the file | |||||||
audienceSubtypeId integer | Audience Subtype ID | |||||||
columnMappings array | Array of column mapping objects | |||||||
| ||||||||
columnId integer | Column ID |
fileColumnName string | File column name |
dataFormatId integer | Data Format ID |
dataPartnerId integer
columnCombinationId integer
audienceRequest sample object for Political Matched Audience
{
"audienceName": "matched-audience-example-fs",
"fileRowCount": 5,
"fileColumnCount": 10,
"columnMappings": [
{
"columnId": 5,
"fileColumnName": "l2-voter-id",
"dataFormatId": null
},
{
"columnId": 6,
"fileColumnName": "email",
"dataFormatId": 1
}
],
"dataPartnerId": 2,
"columnCombinationId": 11
}
audienceRequest sample object for Healthcare Matched Audience
{
"audienceName": "Revamped Healthcare Matched Audience 02",
"dataPartnerId": 7,
"audienceSubtypeId": 3,
"columnMappings": [
{
"columnId": 18,
"fileColumnName": "NPI_ID"
}
],
"fileRowCount": 19,
"fileColumnCount": 1,
"columnCombinationId": 14,
"consentGiven": true
}
POST /api/v3/audience/matched HTTP/1.1
Host: api.iqm.com
Authorization: Bearer 0ed52da8-24ab-44b1-bc88-7ea03a090d24
X-IAA-OW-ID: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="audienceRequest"
Content-Type: application/json
{"audienceName":"Healthcare Patient Audience 2025","dataPartnerId":7,"audienceSubtypeId":3,"columnCombinationId":14,"fileRowCount":1200,"fileColumnCount":3,"consentGiven":true,"columnMappings":[{"columnId":18,"fileColumnName":"NPI_ID"},{"columnId":19,"fileColumnName":"first_name"},{"columnId":20,"fileColumnName":"last_name"}]}
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="patient-data.csv"
Content-Type: text/csv
[Binary CSV file data]
------WebKitFormBoundary7MA4YWxkTrZu0gW--
{
"success": true,
"data": {
"matchedAudienceId": 12345,
"message": "Matched audience created successfully"
}
}
Step 4: Check Audience Status
GETBefore the Audience can be used for Campaign targeting it has to be processed and approved. Once the status is Ready, the Audience can be targeted. Use the matchedAudienceId generated in the last step with this endpoint to get Audience details.
For further information see the complete Matched Audience Details API Documentation.
| Path Parameters | |
|---|---|
audienceId string required | Matched Audience ID |
- JSON
- TypeScript
{
"statusCode": 200,
"responseObject": {
"id": 1,
"audienceName": "Sample audience name",
"existingColumnMatching": "{\"FirstName\":\"Voters_FirstName\",\"LastName\":\"Voters_LastName\",\"State\":\"Residence_Addresses_State\",\"Zip4\":\"Residence_Addresses_Zip\"}",
"metadata": "{\"voterIDColumn\":[],\"columns\":[\"Voter File VANID\",\"LastName\",\"FirstName\",\"MiddleName\",\"Suffix\",\"Address\",\"City\",\"State\",\"Zip5\",\"Zip4\",\"Sex\",\"Age\",\"Preferred Phone\",\"CD\",\"SD\",\"HD \"],\"fileName\":\"NYSD3DigitalUniverse.csv\",\"fileSize\":7856375,\"rows\":0}",
"rawS3URL": "",
"status": "Pending",
"matchRate": 57.88,
"minEcpm": 0,
"maxEcpm": 0,
"s3FileName": "MatchedAudienceSample.csv",
"included": 0,
"excluded": 0,
"createdDate": 1642843451,
"modifiedDate": 1642843884,
"organizationName": "Sample organization name",
"userName": "Sample user name",
"dataCost": 1.5,
"owId": 1,
"uowId": 1,
"rawS3URLError": "File not available currently, please check later",
"uniques": 52432,
"approvedRejectedByUserName": "Sample user name",
"approvedRejectedByUserEmail": "example@example.com",
"isApprovalAccess": true,
"isEditAccess": true
}
}
See TypeScript Prerequisites page for usage.
import {
getInstance
} from "prerequisites"
const axios = getInstance();
interface Responses {
200: {
content: {
"application/json": {
statusCode: number;
responseObject: {
id: number;
audienceName: string;
existingColumnMatching: string;
metadata: string;
rawS3URL: string;
status: string;
matchRate: number;
minEcpm: number;
maxEcpm: number;
s3FileName: string;
included: number;
excluded: number;
createdDate: number;
modifiedDate: number;
organizationName: string;
userName: string;
dataCost: number;
owId: number;
uowId: number;
rawS3URLError: string;
uniques: number;
approvedRejectedByUserName: string;
approvedRejectedByUserEmail: string;
isApprovalAccess: boolean;
isEditAccess: boolean;
};
};
};
};
};
function getMatchedAudienceDetails(): Promise < Responses > {
const options = {
method: 'GET',
url: 'https://api.iqm.com/api/v3/audience/matched/{audienceId}',
params: {
path: {
audienceId: `number`,
}
}
};
return axios.request(options).then(({ data }: { data: Responses }) => data);
}