First-Party Data Uploader: Send any ID types
The First-Party Data Uploader is an upgraded and expanded version of the legacy CRM Data API that can ingest anonymous IDs without the requirement of signing UID agreements. While you can still use the legacy REST API to upload email addresses and phone numbers, the GraphQL First-Party Data Uploader is generally considered the most efficient and flexible upload method for all types of IDs.
TIP: If you are new to GraphQL, check out our GraphQL API Resource Hub and familiarize yourself with the basics.
The following sections list and define the supported ID types and detail the data upload steps.
Supported ID types
The following table lists the ID types supported by the CRM Data GraphQL API, including regional availability and the associated onboarder type you need to specify when generating a data drop endpoint.
NOTE: Email addresses and phone numbers are processed through our CRM Data Onboarding Service and converted to UID2 or EUID for audience targeting and measurement. For examples of normalized or hashed values, see PII normalization, hashing, and encoding.
| ID Type | ID Category | Onboarder Type | Description |
|---|---|---|---|
Email |
Direct identifier | UNIFIED_ID or EUID |
PII sent as email addresses. |
EmailHashedUnifiedId2 |
Direct identifier | UNIFIED_ID or EUID |
PII sent as normalized, Base64-encoded SHA-256 hash of a normalized email address, ready for conversion to UID2. |
Phone |
Direct identifier (APAC, NAMER) | UNIFIED_ID or EUID |
PII sent as phone numbers. |
PhoneHashed |
Direct identifier (APAC, NAMER) | UNIFIED_ID or EUID |
PII sent as normalized, Base64-encoded SHA-256 hash of a normalized phone number. |
UID2 |
Direct identifier | UID2_PASSTHROUGH |
The raw Unified ID 2.0 value, also known as UID2. This value is case-sensitive. Raw UID2s are generated and managed using UID2 APIs. See also Unified IDs. |
UID2Token |
Direct identifier | UID2_PASSTHROUGH |
The encrypted UID2 token, also known as an advertising token. This token is case-sensitive. Tokens are generated and managed using UID2 APIs. For details about UID2 APIs, see UID2 Endpoints. For details about UID2 tokens, see Raw IDs vs. tokens. |
EUID |
Direct identifier | UID2_PASSTHROUGH |
The raw European Unified ID value, also known as EUID. This value is case-sensitive. EUID offers user transparency and privacy controls designed to meet market requirements in European regions with the same normalization and encoding of PII as UID2. See also European Unified ID Overview. |
EUIDToken |
Direct identifier | UID2_PASSTHROUGH |
The encrypted EUID token, also known as an advertising token. This token is case-sensitive. For details, see Unified IDs. |
IDL |
Anonymous identifier | PASSTHROUGH |
The 49-character or 70-character RampID (previously known as IdentityLink or IDL). IMPORTANT: This must be a RampID from LiveRamp that is mapped specifically for The Trade Desk. For details about mapping a RampID, see LiveRamp documentation. |
TDID |
Anonymous identifier | PASSTHROUGH |
The Trade Desk 36-character (including dashes) global unique ID (GUID) for this user. |
DAID |
Anonymous identifier | PASSTHROUGH |
The raw device ID for this user, sent in 36-character GUID format (including dashes). Use the iOS ID for advertisers (IDFA) or Android advertising ID (AAID). |
ID5 |
Anonymous identifier (EU) | PASSTHROUGH |
The ID5 for the user. Data providers holding these IDs should engage with ID5 directly to obtain the necessary decryption keys. For details about ID5, see the ID5 site. IMPORTANT: The ID5 ID is supported only in Europe and must be in decrypted form. |
NetID |
Anonymous identifier (EU) | PASSTHROUGH |
The user's netID as a 70-character Base64-encoded string. For details about netID, see the netID Developer Zone. |
FirstId |
Anonymous identifier (France) | PASSTHROUGH |
The user's First-id, a first-party cookie typically set by publishers in France. For details about First-id, see the First-id site. |
NOTE: Directly identifiable IDs are available only to advertisers and partners who have signed the UID agreement.
Using CRM Data GraphQL API
Here's what you need to know about using the CRM Data Platform GraphQL API:
- To be able to use the API, be sure to contact your Technical Account Manager for the appropriate permissions.
- The API can be used by advertisers and data partners to push data on behalf of the advertiser. If you are an external provider uploading or managing data on behalf of an advertiser, be sure to work with your Technical Account Manager to obtain your data provider ID to complete the
dataProviderIdproperty. - There are two types of segments you can create: targeting and conversion.
- You can upload email addresses and phone numbers as raw values—we will hash them immediately and delete the raw data. If you prefer to pre-hash before uploading, your data must follow the required normalization and encoding format.
- You must generate a unique, auto-expiring, single-use drop endpoint to upload new or update existing data in a segment. This drop endpoint must be regenerated after each use regardless of success or failure. For details, see CRM data upload overview.
- Apply conversion tracking tags to campaigns before sending conversions.
Special requirements
If you are an advertiser in the Medical Health industry category, make sure the audience data you upload complies with the following requirements:
- It must not contain data about individuals in Washington or Nevada.
- It must include only the following data:
- Consented data: You have affirmative consent from the individual to use and disclose data about their health for advertising purposes.
- Modeled data: Identifiers are associated with individuals for whom you have no knowledge or evidence suggesting specific health conditions.
ID field reference
The following table lists different types of IDs that the First-Party Data Uploader requires or returns. It also explains where or how you can retrieve their values instead of storing them.
NOTE: Depending on the operation, an ID might appear under different field names. For example,
trackingTag.idortrackingTagId, andownerIdordataOwnerId.
| ID Field | Description | Value Origin or Location |
|---|---|---|
ownerId |
The party that owns a data segment. | These fields are included in crmDataSegmentCreate calls and responses when creating data segments. |
advertiserId |
The advertiser that owns a data segment. | This ID is assigned by The Trade Desk platform. You can retrieve it in the platform UI. |
dataProviderId |
The external provider authorized by the advertiser to upload and manage their first-party data. | Include only if you are uploading data as an external provider of advertiser data. |
segmentId |
Identifies a data segment. This ID is used for retrieving segment details. | This ID is returned in the id field in the crmDataSegmentCreate response when creating data segments. You can retrieve it by querying segments for the advertiser. |
dropId |
The data uploaded to a segment with a unique, auto-expiring, single-use drop endpoint. This ID is used for checking the data processing status. | This ID is returned in the crmDropBind response along with the drop URL.IMPORTANT: Be sure to save this ID for subsequent status checks. |
targetingData.id |
Identifies targeting data in the segment. | You can retrieve this ID by using the crmDataSegment query. |
trackingTagId |
The tracking tag for a conversion data segment that is used to attach the segment to a campaign. | This ID is returned in the crmDataSegmentCreate response when you create a conversion data segment. You can also retrieve this ID by using the crmDataSegment query. |
Data upload workflow
The following table lists the tasks involved in the data upload process.
| Step | Task | Operation | Notes |
|---|---|---|---|
| 1 | Create a data segment. | crmDataSegmentCreate mutation |
You must have your advertiser ID. |
| 2 | (Required only for conversion segments) Attach a conversion data segment to a campaign. | campaigns querycampaignUpdate mutation |
You cannot attribute upload data to a campaign without completing this step. IMPORTANT: You must have the tracking tag ID returned in the preceding step. |
| 3 | Generate a unique, auto-expiring, single-use drop endpoint for uploading your data. | crmDropBind mutation |
IMPORTANT: This drop endpoint must be regenerated after each use regardless of success or failure. During this step, you specify the type of PII you will be uploading, onboarder types, and your merging preferences. |
| 4 | Upload your first-party data to the generated drop endpoint. | N/A | The drop URL auto-expires after an hour. IMPORTANT: You can use the drop URL only one time, even if it is still live or fails. See also FAQs. |
| 5 | Check the data processing status. | crmDropInfo query |
You can define the level of detail to be returned. You must specify the data drop ID returned in step 3. |
The following sections illustrate each step in the process.
Create a data segment
To create a CRM data segment, you must specify the following in the CreateTargetingSegment mutation:
The type of segment you want to create: TARGETING or CONVERSION.
The ID of the advertiser who owns this segment.
A descriptive segment name.
The geographical region from which the data originates or is allowed to be stored.
Here's what you need to know:
- If you are an external provider uploading data on behalf of an advertiser, you must include your data provider ID. If you don't have one, contact your Technical Account Manager.
- If you call this endpoint with the same parameters, new segments will be created with the same name but with different segment IDs.
- To upload EUIDs, you must set the
regionproperty value toEU.
IMPORTANT: When you create a segment with the
Regionproperty value set toEU, you may not yet upload phone numbers or hashed phone numbers.
Targeting data segment example
Here's an example crmDataSegmentCreate GraphQL mutation that shows how to create a targeting data segment.
mutation {
crmDataSegmentCreate(input: {
name: "DATA_SEGMENT_NAME_PLACEHOLDER"
ownerId: { advertiserId: "ADVERTISER_ID_PLACEHOLDER" }
region: US
segmentType: TARGETING
}) {
data {
id
name
region
dataProviderId
dataOwnerId
dataOwnerType
}
errors {
... on MutationError {
message
field
}
}
}
}
A successful response returns the segment ID (id) that you can use for subsequent data upload and update calls.
Conversion data segment example
Here's an example crmDataSegmentCreate GraphQL mutation that shows how to create a conversion data segment.
TIP: For conversion data segments, include the tracking tag in the response and pass its ID to associate it with the campaign when updating its conversion columns.
mutation {
crmDataSegmentCreate(input: {
name: "DATA_SEGMENT_NAME_PLACEHOLDER"
ownerId: { advertiserId: "ADVERTISER_ID_PLACEHOLDER" }
region: US
segmentType: CONVERSION
}) {
data {
id
name
region
dataProviderId
dataOwnerId
dataOwnerType
targetingData {
trackingTag {
id
}
}
}
errors {
... on MutationError {
message
field
}
}
}
}
A successful response returns the segment ID (id) that you can use for subsequent data upload and update calls. It also returns the tracking tag ID required in the following step.
Attach a conversion data segment to a campaign
NOTE: This step is required only for conversion segments. If you want to upload a segment for targeting, skip to Generate a data drop endpoint.
To attach a conversion data segment to a campaign, complete the following steps:
| Step | Task | Operation | Notes |
|---|---|---|---|
| 1 | Get the current campaign conversion columns. | campaigns query |
The retrieved conversionReportingColumns data is required in step 2. |
| 2 | Update the campaign with the conversion reporting columns. | campaignUpdate mutation |
To avoid losing the previous data, you must send the conversion reporting column data retrieved in step 1 along with the new data. |
Get campaign conversion columns
Here's an example campaigns GraphQL query that shows how to fetch the current campaign conversion columns.
query GetCampaignConversionReportingColumnsExample(
$where: CampaignFilterInput
$first: Int
) {
campaigns(where: $where) {
nodes {
id
conversionReportingColumns(first: $first) {
nodes {
trackingTag {
id
}
customCPAConfig {
include
weight
}
crossDeviceAttribution {
id
}
id
reportingColumnId
customROASConfig {
include
viewthroughWeight
weight
clickWeight
}
campaign {
id
}
}
}
}
}
}
Here's an example response to the query:
{
"data": {
"campaigns": {
"nodes": [
{
"id": "a1b2c3d",
"conversionReportingColumns": {
"nodes": [
{
"trackingTag": {
"id": "x9y8z7w",
"name": "Demo (3pd)-1-BrandX-12345 - purchase",
"__typename": "TrackingTag"
},
"customCPAConfig": {
"include": false,
"weight": 0.0,
"__typename": "CustomCPAConfig"
},
"crossDeviceAttribution": {
"concept": "HOUSEHOLD",
"id": "IdentityAllianceWithHousehold",
"name": "Identity Alliance with Household",
"__typename": "CrossDeviceAttribution"
},
"id": "m4n5p6qr2s3t4u",
"reportingColumnId": 1,
"customROASConfig": {
"include": false,
"viewthroughWeight": 0.0,
"weight": 0.0,
"clickWeight": 0.0,
"__typename": "CustomROASConfig"
},
"campaign": {
"id": "a1b2c3d",
"__typename": "Campaign"
},
"__typename": "CampaignConversionReportingColumn"
},
{
"trackingTag": {
"id": "k7l8m9n",
"name": "ClientB - Default",
"__typename": "TrackingTag"
},
"customCPAConfig": {
"include": false,
"weight": 1.0,
"__typename": "CustomCPAConfig"
},
"crossDeviceAttribution": null,
"id": "h6i7j8kp1q2r3s",
"reportingColumnId": 2,
"customROASConfig": {
"include": false,
"viewthroughWeight": 1.0,
"weight": 1.0,
"clickWeight": 1.0,
"__typename": "CustomROASConfig"
},
"campaign": {
"id": "a1b2c3d",
"__typename": "Campaign"
},
"__typename": "CampaignConversionReportingColumn"
}
],
"__typename": "ConversionReportingColumnsConnection"
},
"__typename": "Campaign"
}
],
"__typename": "CampaignsConnection"
}
}
}
Update campaign conversion columns
Here's an example campaignUpdate GraphQL mutation that shows how to update the campaign with the new conversion data and the conversion columns retrieved in the preceding step. To do so, you must provide the trackingTagId value returned in the crmDataSegmentCreate response when you created the data segment.
IMPORTANT: To avoid losing the previous campaign conversion data, you must include it in this call.
mutation ($input: CampaignUpdateInput!) {
campaignUpdate(input: $input) {
data {
id
name
channelType
}
userErrors {
field
message
}
}
}
Here's an example $input variable with the values from the response returned in the preceding step.
{
"variables": {
"input": {
"id": "a1b2c3d",
"campaignConversionReportingColumns": [
{
"trackingTagId": "x9y8z7w",
"reportingColumnId": 1,
"includeInCustomCPA": false,
"customROASConfig": {
"includeInCustomROAS": false,
"customROASClickWeight": 0,
"customROASViewthroughWeight": 0,
"customROASWeight": 0
},
"crossDeviceAttributionModelId": "IdentityAllianceWithHousehold"
},
{
"trackingTagId": "k7l8m9n",
"reportingColumnId": 2,
"includeInCustomCPA": false,
"customROASConfig": {
"includeInCustomROAS": false,
"customROASClickWeight": 1,
"customROASViewthroughWeight": 1,
"customROASWeight": 1
}
},
{
"trackingTagId": "z7a8b9c",
"reportingColumnId": 3,
"includeInCustomCPA": false,
"crossDeviceAttributionModelId": "Adbrain"
}
]
}
}
}
Generate a data drop endpoint
To create a unique, auto-expiring, single-use drop endpoint for uploading your CRM data, use the crmDropBind GraphQL mutation and specify the following:
The data segment ID, which was returned in the response (id) when you created the segment.
The piiTypes and onboarderTypes values. For specific values, see Supported ID types. See also Onboarder types.
Whether you want the data to be added to existing data or replace it (mergeMode).
Here's what you need to know:
- The
inputFormatfield specifies the format of the data file being uploaded. If no value is provided, the default isValuePerLinefor targeting segments, andConversionCSVfor conversion segments. Depending on the input file format:- We can accept multiple PII types per drop for both targeting and conversions.
- The
piiTypesfield is not required for theTARGETING_CSVandCONVERSION_CSVinput formats.
- The
piiTypesvalues may include both direct (PII) and anonymous identifiers. - There are two ways to update a segment. You can add new data on top of the existing data, or replace it completely by setting the
mergeModeproperty to eitherADDorREPLACE. You cannot replace data in conversion segments. - If the
ttl(Time-to-Live, in minutes) value is not provided, the default is129600minutes (90 days). The maximum is 259,200 minutes (180 days), except for segments created with email addresses or phone numbers, which are capped at 90 days (129600minutes) and automatically reduced to that cap if a higher value is specified. - After each use, regardless of success or failure, you must regenerate a drop endpoint.
Input formats
The following table describes the supported inputFormat field values and how the system expects the IDs to be provided for each format when ingesting them. It also indicates whether you must specify the piiTypes values for each format.
| Input Format Value | Description | PII Types Required? |
|---|---|---|
VALUE_PER_LINE |
Default format for targeting segments. One value per line, no header. | Required |
CSV |
CSV with headers. Column name must match the PII types. | Required |
TARGETING_CSV |
CSV format for targeting segments with two columns: 'Pii' and 'Pii Type'. Each row specifies the PII value and its type. | N/A, ignored if sent |
CONVERSION_CSV |
Default format for conversion segments. Column names are described in Conversion headers. | N/A, ignored if sent |
Onboarder types
The onboarderTypes array indicates if any additional processing is required for the data in the segment. Specifically, each type indicates whether the input data should be converted to UIDs or passed through unchanged.
NOTE: The
onboarderTypesarray is optional because our CRM Data Onboarding Service can infer the correct type from the uploaded data. However, we recommend specifying it explicitly for accuracy and efficient processing.
The following table describes each onboarder type and the IDs associated with it. See also Supported ID types.
| Onboarder Type | Description | IDs |
|---|---|---|
UNIFIED_ID |
Convert PII to UID2s. | Email addresses, phone numbers, hashed email addresses, hashed phone numbers |
EUID |
Convert PII to EUIDs | Email addresses, phone numbers, hashed email addresses, hashed phone numbers |
UID2_PASSTHROUGH |
No conversion is required because the included UIDs have already been processed. | UID2s, UID2 tokens, EUIDs, EUID tokens |
PASSTHROUGH |
No processing is required because the included IDs are anonymous and require no additional processing. | TDIDs, DAIDs, IDLs (RampIDs), ID5s, netIDs, First-ids, and IPv4 addresses |
Mutation example
Here's an example crmDropBind GraphQL mutation that shows how to generate a drop endpoint for several ID types.
mutation {
crmDropBind(
input: {
dropId: "DATA_DROP_ID_PLACEHOLDER"
segmentId: "DATA_SEGMENT_ID_PLACEHOLDER"
mergeMode: ADD
onboarderTypes: [UNIFIED_ID, UID2_PASSTHROUGH, PASSTHROUGH]
piiTypes: [EMAIL, UID2Token, TDID]
inputFormat: CSV
}
) {
data {
id
uploadUrl
urlExpirationTime
}
errors {
... on MutationError {
message
field
}
}
}
}
A successful call returns the ID of newly created drop, pre-signed URL (uploadUrl) for uploading the data, and the time when the upload link will expire (urlExpirationTime).
Send segment data to the generated drop endpoint
TIP: We strongly recommend larger uploads rather than splitting your data into many small drops. For example, to ensure fast, reliable ingestion (typically under an hour), upload a segment in one drop containing up to 500 million records. See also FAQs.
To send your CRM data, you must have the following:
A CSV file with your data, unless you selected VALUE_PER_LINE input format for targeting segments.
The pre-signed URL (uploadUrl) generated in the preceding step.
The following sections explain the CSV file requirements for targeting and conversions, and provide an example Python script for uploading the file.
Targeting data headers
If you selected CSV as the inputFormat value for your upload when generating a drop URL, here's what you need to know about uploading targeting data:
- Column names must represent the PII type being sent. For example
email,phone_number,device_id. - A single row may contain multiple identifiers. This can imply that those identifiers belong to the same individual.
- We do not preserve identifier linkage. Each ID is onboarded independently.
- Any relationship between identifiers in the same row will be discarded.
Conversion data headers
The following table lists the valid headers for conversion data upload files.
| Property Header | Required? | Data Type | Description | Example |
|---|---|---|---|---|
PiiType |
Required | String | The value of a PII type for your PII property. For details, see Supported ID types. |
EmailHashedUnifiedId2 |
PII |
Required | String | The value of the PII. | customer@example.org |
TimestampUtc |
Required | DateTime | A valid timestamp in UTC, using the following ISO 8601 format:
T as the delimiter. For example, yyyy-MM-ddTHH:mm:ss is also accepted.The value must not be set to a future time. |
2024-07-09T15:30:45.123Z |
Value |
Optional | Decimal | The monetary value of this conversion as a decimal. | 19.98 |
ValueCurrency |
Optional | String | The currency of the Value field amount. |
USD |
Country |
Optional | String | The full name of the country where the conversion occurred. | United States |
Region |
Conditionally required | String | Required if the Country field is set to United States. The full name or code of the region where the conversion occurred. |
NY, New York |
NielsenDMA* |
Optional | Integer | The numerical metropolitan area geotargeting code where the conversion occurred. | 501 |
City |
Optional | String | The city where the conversion occurred. | US NYC |
PostalCode |
Optional | String | The postal or ZIP code where the conversion occurred. | 10004 |
OrderId |
Optional | String | The unique identifier for a transaction or conversion event, with a maximum length of 64 characters. | abc123XyZ |
item_brand |
Optional | String | The brand name of the item. | Cookie Brand Name |
ClientIPAddress |
Optional | String | The client's IP address associated with the conversion event. | 198.51.100.7 |
ReferrerUrl |
Optional | String | The URL of the web page associated with the conversion event. | https://www.example.com/ |
TD1-TD10 |
Optional | String(150) | Ten sequentially numbered custom dynamic properties that can be used to provide additional conversion metadata. | N/A |
privacy_type |
Conditionally required | String | Specifies the applicable privacy regulation based on the user's geographical location:
|
GDPR |
is_applicable |
Conditionally required | Boolean | Indicates if the value specified in the privacy_type property is applicable. IMPORTANT: Must always be set to true if the privacy_type property is populated. |
true or 1 |
consent_string |
Conditionally required | String | The user's consent when the privacy regulations are in effect. The format depends on the privacy_type property value:
|
N/A |
* © 2026, The Nielsen Company (US), LLC. The DMA® data is used pursuant to a license from The Nielsen Company (US), LLC. Any use and/or reproduction of these materials without the express written consent of The Nielsen Company (US), LLC, is strictly prohibited. DMA® data is valid for the period 2025 - 2026. DMA® is a registered service mark of The Nielsen Company (US), LLC and is used pursuant to license.
Python script example
File data is not transmitted through the GraphQL API. Instead, upload files directly to S3 storage via a pre-signed upload URL (the uploadUrl value returned in the response when you generated a data drop endpoint).
Here's an example Python script for uploading the CSV file. Be sure to replace the PLACEHOLDER values.
# Upload CSV file data as-is
import requests
# Read CSV file content without processing
with open('ADVERTISER_FILE_PATH_PLACEHOLDER.csv', 'r', encoding='utf-8') as csvfile: # Replace ADVERTISER_FILE_PATH_PLACEHOLDER.csv with the path of your actual file.
csv_content = csvfile.read()
upload_response = requests.put(drop['UPLOAD_URL_PLACEHOLDER'], data=csv_content.encode())
if upload_response.status_code == 200:
print("Email data uploaded successfully")
else:
raise Exception(f"Upload failed: {upload_response.status_code}")
return segment['id'], drop['id']
# Run the workflow
segment_id, drop_id = asyncio.run(create_targeting_segment_workflow())
Check data drop processing status
To check the processing status of the segment data that you have sent to the upload URL, use the crmDropInfo query and specify the following:
The CRM data segment ID, which was returned as id in the crmDataSegmentCreate response when you created the segment. See also ID field reference.
The processing and other details you want to retrieve.
NOTE: If you've uploaded multiple drops for the same segment, you can retrieve the status of the latest data drop or of all drops in a single call.
Here's an example crmDropInfo GraphQL query that returns basic processing status information.
query GetDataDropProcessingStatusExample($dropId: ID!) {
crmDropInfo(id: $dropId) {
onboarderTypes
piiTypes
segmentId
ttl
dropStatus {
alerts
processingComplete
published
receiptUrl
}
}
}
Here's an example crmDropInfo GraphQL query that returns more detailed processing status information that includes all stages of drop ingestion.
query GetDataDropProcessingStatusExtendedExample($dropId: ID!) {
crmDropInfo(id: $dropId) {
onboarderTypes
piiTypes
segmentId
ttl
dropEvents {
eventTime
eventType
service
eventData {
__typename
... on DropUploadStats {
alerts
terminal
type
}
... on DropBindStats {
alerts
terminal
type
}
... on IngestPiiProcessingStats {
alerts
failedTotal
ingestedTotal
receiptUrl
terminal
type
uniqueTotal
validTotal
ingestedPiis {
onboarderType
piiType
total
}
validPiis {
piiType
total
}
}
... on OnboardingStats {
livePiis {
onboarderType
piiType
total
}
liveUserIds {
onboarderType
piiType
total
}
terminal
}
... on DataServerUploadStats {
alerts
dataServerErrorsTotal
expiredTotal
sentToDataServerTotal
terminal
type
}
... on DropError {
alerts
terminal
type
}
}
}
dropStatus {
alerts
processingComplete
published
receiptUrl
}
}
}
CRM data management tasks
After you successfully upload your data, you can manage it by retrieving your segments and updating them as needed. Here's what you need to know about updating segments and their data:
- Updates to a segment can include removing inactive users, adding new data on top of existing data, or replacing existing data.
- To update a segment, you must generate a unique, auto-expiring, single-use drop endpoint with the ID of the segment that you want to update.
- If your update fails, you must generate a new drop endpoint.
- To replace data from a segment, update the data and be sure to set the
mergeModeproperty value toREPLACE.
The following table lists the relevant endpoints for each management task.
| Task | Operation | Notes |
|---|---|---|
| Query a data segment created for an advertiser. | crmDataSegment query |
You can use this query to retrieve the tracking tag, targeting data, and other IDs and segment details. |
| Query all data segments created for an advertiser. | You can retrieve a list of all segments uploaded so far and look up their names, IDs, and any other relevant details instead of storing them. | |
| Update your segment data. | crmDropBind mutation |
You must upload the updated segment data. |
| Remove inactive users from a targeting data segment. | crmDropBind mutation |
You must upload the updated segment data. IMPORTANT: This action permanently removes the IDs, and you cannot restore them. |
| Archive a data segment. | crmDataSegmentArchive mutation |
This removes the segment from targeting. |
The following sections provides examples of common querying and update tasks that you may need to perform when managing your CRM data.
Query a data segment
To retrieve a data segment, use the crmDataSegment query and specify the following:
The data segment ID, which was returned as id in the crmDataSegmentCreate response when you created the segment. See also ID field reference.
The segment details you want to retrieve.
The following sections provide query examples that show how to retrieve targeting data IDs and tracking tag IDs.
Query a targeting data ID
Here's an example crmDataSegment GraphQL query that returns the targetingData.id value for a targeting data segment.
query GetTargetingDataIdExample($segmentId: ID!) {
crmDataSegment(id: $segmentId) {
id
name
targetingData {
id
}
segmentType
}
}
Query a tracking tag ID
Here's an example crmDataSegment GraphQL query that returns the trackingTag.id value for a conversion data segment.
query GetTrackTagIDforConversionSegmentExample($segmentId: ID!) {
crmDataSegment(id: $segmentId) {
id
name
targetingData {
id
}
segmentType
... on ConversionSegment {
trackingTag {
id
}
}
}
}
Query all data segments for an advertiser
To retrieve multiple data segments for an advertiser, use the advertiser GraphQL query with the advertiser ID and the CrmDataSegmentFilterInput filter. For example:
query GetAdvertiserDataSegmentsExamples(
$advertiserId: ID!
$where: CrmDataSegmentFilterInput
) {
advertiser(id: $advertiserId) {
crmDataSegments(where: $where) {
nodes {
createdTimestamp
dataOwnerId
dataOwnerType
dataProviderId
id
name
region
retentionPeriod
segmentType
segmentVersion
lastDrop {
creationTime
deskType
id
mergeMode
onboarderTypes
ownerId
piiTypes
segmentId
ttl
urlExpirationTime
}
}
}
}
}
Update data in a segment
To update data in a segment, complete the following steps:
- Generate a unique, auto-expiring, single-use drop endpoint with the advertiser ID and the data ID of the segment that you want to update.
- Upload the list of current users in the segment, along with any additional users you want to add, to the generated drop endpoint.
NOTE: Conversion data segments do not support the
REPLACEvalue inmergeMode. You can only useADD, which is set by default.
Remove inactive users from a data segment
Here's what you need to know about removing IDs:
- This action permanently removes the IDs, and you cannot restore them.
- You cannot remove users from conversion segments because those users contribute to measurement.
To remove inactive users from a targeting data segment, you can replace data in the segment or complete the following steps:
- Generate a unique, auto-expiring, single-use drop endpoint with the advertiser ID and CRM data ID of the segment that you want to update and set the
ttlvalue to0to expire inactive users. - Upload a list of inactive users to be removed from the segment to the generated drop endpoint.
Archive a data segment
To archive a data segment, use the crmDataSegmentArchive mutation and specify its ID. It was returned as id in the crmDataSegmentCreate response when you created the segment. See also ID field reference.
Archived segments are not retained, and all their IDs are sent with ttl value set to to 0, which effectively excludes them from targeting.
Here's an example crmDataSegmentArchive GraphQL mutation:
mutation ($segmentId: String! ) {
crmDataSegmentArchive(
input: {
id: $segmentId
}
) {
errors {
... on MutationError {
message
field
}
}
}
}
FAQs
The following are most commonly asked questions about managing CRM data.
How soon does the drop URL expire?
Drop URLs expire within one hour after the link is generated, regardless of whether the operation was a success or failure. If you attempt to re-upload data using the same URL, the upload attempt will be logged but the data will be ignored.
How many times can I use the same URL to upload email addresses, if the URL is still live?
Only once. The URL points to a particular drop (or file path in S3), which is processed only once. If you re-upload and overwrite your previously uploaded file while the URL is valid, the data will not be processed.
What's the recommended rate of generating drop URLs for the same segment?
There are no restrictions. However, if you have multiple segments to upload, you can send them in parallel.
How many concurrent uploads can I do? If I have 60 drop URLs, can I use all 60 at the same time?
There are no restrictions. However, the ingestion time depends on the number of drops, rather than drop size. If you split the segment into many drops, the ingestion might take much longer.
What is the maximum payload size for uploading data?
There is no strict drop size limit. However, we strongly recommend larger uploads rather than splitting your data into many small drops.
Here's what you need to know and do:
- Processing time depends on the number of drops, not the drop size.
- For best performance, upload the segment in as few drops as possible—ideally one large drop. For example, a single 50-million‑record file is preferred over 10 files of 5 million each or 100 files of 500,000 each.
- Submitting many small drops can significantly slow ingestion and may result in HTTP 429 (Too Many Requests) errors.
TIP: To ensure fast, reliable ingestion (typically under an hour), upload a segment in one drop containing up to 500 million records.
Can I create a single data segment for both audience targeting and conversion measurement?
No. You cannot create a single data segment that does both conversion measurement and audience targeting.
What's the difference between the First-Party Uploader and legacy CRM API?
The First-Party Data Uploader is the newer, expanded solution. It supports all ID types, uses GraphQL, and can ingest anonymous IDs without requiring a signed UID agreement.
The CRM Data API is a legacy REST-based method primarily designed for uploading directly identifiable data (such as email addresses and phone numbers). It supports TDIDs only in certain cases and typically requires a signed UID agreement for sending them.
In short, the First-Party Data Uploader is more flexible and is the recommended option for new integrations.
Do I need a UID agreement?
To upload directly identifiable IDs, you must have signed the UID agreement. For anonymous IDs, you do not need to sign the UID agreement.
How can I retrieve the tracking tag ID for a conversion data segment I created?
You can retrieve it by using the crmDataSegment query. For details, see Query a data segment.
How can I retrieve the targeting data ID for a targeting data segment I created?
You can retrieve it by using the crmDataSegment query. For details, see Query a data segment.
Does the First-Party Data Uploader supports IPv4 address uploads for direct IP targeting?
Yes. You can use the crmDataSegmentCreate and crmDropBind mutations to upload IPv4 addresses for direct IP targeting. No UID paperwork is required.
The following code samples illustrate the key steps and field values. For more details, please stay tuned for updates as we're working on a designated user guide for uploading IP addresses.
IMPORTANT: You must have the appropriate access permissions. For details, contact your Technical Account Manager.
The following is an example crmDataSegmentCreate mutation that shows how to create a data segment by setting the segmentTypefield to TARGETING_DIRECT_IP.
mutation {
crmDataSegmentCreate(input: {
name: "DATA_SEGMENT_NAME_PLACEHOLDER"
ownerId: { advertiserId: "ADVERTISER_ID_PLACEHOLDER" }
region: US
segmentType: TARGETING_DIRECT_IP
}) {
data {
id
name
region
dataProviderId
dataOwnerId
dataOwnerType
}
errors {
... on MutationError {
message
field
}
}
}
}
The following is an example crmDropBind mutation that shows how to create a data segment by setting the segmentTypefield to TARGETING_DIRECT_IP.
mutation {
crmDropBind(
input: {
dropId: "DATA_DROP_ID_PLACEHOLDER"
segmentId: "DATA_SEGMENT_ID_PLACEHOLDER"
mergeMode: ADD
piiTypes: [IPV4]
onboarderTypes: [PASSTHROUGH]
inputFormat: VALUE_PER_LINE
}
) {
data {
id
uploadUrl
urlExpirationTime
}
errors {
... on MutationError {
message
field
}
}
}
}