The Raw Export API V2 exports your contact attributes and events as CSV or Parquet files. Insider One prepares the files, stores them in its own S3 bucket, and delivers signed download URLs. You pull the data into your data warehouse, BI tools, or downstream systems.
The export is asynchronous. You submit a request, receive an export_id immediately, and collect the files once they are ready by polling a status endpoint or handling a webhook.
How it works
Asynchronous by design. The POST endpoint accepts your request and returns an export_id immediately. Insider One then estimates, chunks, and runs the export in the background. Collect results by polling the status endpoint, handling the webhook, or both.
You define the user set. Export the users in a saved segment, or let an events query define the user set. The two modes are mutually exclusive.
Attributes and events arrive as separate files. A single export produces separate attribute files and event files, chunked for scale. There is no server-side join since you join them on insider_id.
Public names everywhere. V2 uses the same names you see in the InOne panel. Internal codes and c_-prefixed custom names are rejected. Custom attributes and parameters use the custom.namespace, such as custom.loyalty_tier.
Strict validation. Invalid selectors are rejected up front with a 400 error that echoes the exact selector you sent.
How V2 differs from V1
Aspect | V1 | V2 |
|---|---|---|
Execution | Synchronous, request blocks until done | Asynchronous, returns an export_id, then poll or webhook |
Output layout | Single file per export | Separate, chunked attribute and event files |
Join key column | iid | insider_id |
Attribute columns | a_email; customs a_c_<name> | email; for customs: custom.<attribute name> |
Event columns | e_product_id; customs e_c_<name> | product_id; for customs: custom.<event name> |
Accepted selectors | Public name OR internal short OR c_ custom | Public name only |
Formats | CSV, Parquet, JSON | CSV, Parquet (No JSON) |
Validation | Looser, some bad input accepted silently | Strict, invalid selectors rejected with 400 |
Event-derived user set | Not available | user_source: "events" |
Result retrieval | Webhook only | Webhook and status polling |
Headers
Header | Sample Value | Description |
|---|---|---|
X-PARTNER-NAME | mybrand | This is your partner name. Navigate to InOne > Inone Settings > Account Settings to copy your partner name. The partner name should be lowercase. |
X-REQUEST-TOKEN | 1a2b3c4e5d6f | This key is required to authorize your request. Refer to API Authentication Tokens to generate your token. |
Content-Type | application/json | This header specifies the media type of the resource. |
Running scenario
Every example on this page is built on the same scenario. You run an online store. Your analytics team wants two things: a snapshot of a saved customer segment with key attributes, and every purchase event from the last quarter for a revenue model.
Scenario reference
Segment: Saved segment, referenced by segment_id: 12345
Attributes: name, email, age, custom.loyalty_tier
Event: purchase with params product_id, currency, custom.gift_wrap
Format: csv
1. Submit an export
Use this endpoint to request an export of attributes, events, or both, for a user set defined by a saved segment or an events query. The endpoint validates your request and returns an export_id immediately. The export runs in the background.
Endpoint
POST https://unification.useinsider.com/api/raw/v2/export
Body Parameters
Field | Description | Data Type | Required |
|---|---|---|---|
format | Output format. Accepted values: "csv" or "parquet". JSON is not supported. | String | Required |
hook | Webhook URL where Insider One delivers the result manifest and signed download URLs. Must include a scheme and host. | String | Required |
user_source | Defines the user set. "segment" (default) exports users in a saved segment. "events" derives the user set from the events query. Mutually exclusive; passing segment alongside user_source: "events" is rejected. | String | Optional |
attributes | Public attribute names, for example, ["email", "age", "custom.loyalty_tier"]. Pass ["*"] to export all registered attributes. Cannot be combined with named selectors. At least one of attributes or events is required. | Array | Conditional |
events | Event export specification. Required when user_source is "events". See the events object reference below. | Object | Conditional |
segment | Saved segment reference: {"segment_id": 12345}. Required when user_source is "segment". Forbidden with user_source: "events". | Object | Optional |
explode_json | Explodes a JSON column into separate named columns in the output. | Map | Optional |
get_tags | When true, includes a tags column in event output files. | Boolean | Optional |
The events object:
Field | Description | Data Type | Required |
|---|---|---|---|
start_date | Start of the export date range as a Unix epoch timestamp in seconds. Values above 1e12 are rejected as milliseconds. | Number | Required |
end_date | End of the export date range in Unix epoch seconds. Must be greater than start_date. | Number | Required |
wanted | List of events to export. One entry per event type. See the wanted entry reference below. | Array | Required |
Each entry in wanted:
Field | Description | Data Type | Required |
|---|---|---|---|
event_name | Public name of the event, such as purchase. | String | Required |
params | Public parameter names to include as columns, for example, ["product_id", "currency", "custom.gift_wrap"]. | Array | Required |
filters | At most one filter per event entry. Narrows which event rows are exported. See the filters reference below. | Array | Optional |
The filters entry:
Field | Description | Data Type | Required |
|---|---|---|---|
key | Public parameter name to filter on | String | Required |
operator | Comparison operator: eq (equals), ne (not equals), lt (less than), gt (greater than), lteq (less than or equal), gteq (greater than or equal). | String | Required |
values | Inline list of values to match. Use for short lists. Provide either values or values_url, not both. | Array | Conditional |
values_url | URL of a file listing values to match. One value per row, no header row. Use for long lists. Provide either values_url or values, not both. | String | Conditional |
Finding the right names for your request
V2 accepts public names only. Internal short codes and c_-prefixed custom names are rejected with 400. The Metadata Name Reference lists every default attribute, event, and event parameter under its public name, exactly as it should appear in your request.
Sample Request: Segment with attributes
curl --location --request POST 'https://unification.useinsider.com/api/raw/v2/export' \
--header 'X-PARTNER-NAME: mybrand' \
--header 'X-REQUEST-TOKEN: <request-token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"format": "csv",
"user_source": "segment",
"segment": { "segment_id": 12345 },
"attributes": ["name", "email", "age", "custom.loyalty_tier"],
"hook": "https://example.com/hook"
}'Sample Request: Event-derived user set
curl --location --request POST 'https://unification.useinsider.com/api/raw/v2/export' \
--header 'X-PARTNER-NAME: mybrand' \
--header 'X-REQUEST-TOKEN: <request-token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"format": "csv",
"user_source": "events",
"events": {
"start_date": 1730000000,
"end_date": 1733000000,
"wanted": [
{
"event_name": "purchase",
"params": ["product_id", "currency", "custom.gift_wrap"]
}
]
},
"hook": "https://example.com/hook"
}'Sample Responses
200 Accepted
{ "export_id": "abc123" }200 confirms acceptance, not completion. The export runs asynchronously. Collect files by polling the status endpoint or handling the webhook delivered to your hook URL.
Rate limit:
10 export request per account per UTC day. The quota resets at 00:00 UTC. Requests that return a non-success response do not count against the daily quota.
Output files
A single export produces separate attribute files and event files, chunked for scale. There is no server-side join; you join them yourself on insider_id.
File Type | Columns |
|---|---|
Attribute file | insider_id (first column), then each requested attribute under its public name. Custom attributes appear as custom.<name>. |
Event file | insider_id, event_name (public name), timestamp, source, then each requested parameter. Custom parameters appear as custom.<name>. The tags column is included only when get_tags: true. |
CSV and Parquet column names are identical for the same request; one parsing pipeline handles both formats. Download URLs are signed and valid for approximately 24 hours. Download files promptly after the export completes.
2. Check export status
Use this endpoint to poll an export's status. You can poll, rely on the webhook, or both. Exports are scoped to the requesting account; an unknown or non-owned export_id returns not-found.
GET https://unification.useinsider.com/api/raw/v2/export/export_id
curl --location --request GET 'https://unification.useinsider.com/api/raw/v2/export/export_id' \
--header 'X-PARTNER-NAME: mybrand' \
--header 'X-REQUEST-TOKEN: <request-token>' \Response fields
Field | When present |
|---|---|
export_id | Always |
status | Always: processing, completed, failed, or rejected |
format | When completed |
files | When completed: {"attributes": [...], "events": [...]} |
totals | When completed: file counts |
Status reference
Status | Meaning | What to do |
|---|---|---|
processing | Request accepted. Export is being prepared in the background. | Keep polling or wait for the webhook. Nothing to download yet. |
completed | Files are ready. format, files, and totals are populated. | Download files from the signed URLs. Valid for approximately 24 hours. |
failed | Export was accepted but could not finish; typically an out-of-memory or query timeout error. | Check the error reason in the webhook, then retry with a narrower request. |
rejected | Estimated volume exceeded processing limits. The job was turned down before running. | Narrow the request, for example, smaller segment, shorter date range, or fewer events, then retry. |
Sample response: processing
{ "export_id": "abc123", "status": "processing" }Sample response: completed
{
"export_id": "abc123",
"status": "completed",
"format": "csv",
"files": {
"attributes": [
{ "name": "attrs-0.csv", "url": "https://s3...signed", "rows": 50000 }
],
"events": [
{ "name": "event-purchase-0.csv", "url": "https://s3...signed", "rows": 120000 }
]
},
"totals": { "attribute_files": 1, "event_files": 1, "total_files": 2 }
}Sample Requests
Request 1: Filter by a list of values from a file
An analyst wants Q1 purchases limited to a specific product list. The list is long, so product IDs are supplied as a file via values_url rather than inline. The file must have one column and no header row.
curl --location --request POST 'https://unification.useinsider.com/api/raw/v2/export' \
--header 'X-PARTNER-NAME: mybrand' \
--header 'X-REQUEST-TOKEN: <request-token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"format": "csv",
"user_source": "events",
"events": {
"start_date": 1767225600,
"end_date": 1775001600,
"wanted": [
{
"event_name": "purchase",
"params": ["product_id", "unit_price"],
"filters": [
{
"key": "product_id",
"operator": "eq",
"values_url": "https://example.com/files/product_ids.csv"
}
]
}
]
},
"hook": "https://example.com/hook"
}'Request 2: Attributes, multiple events, filter, tags, and Parquet output
A retail data science team runs a quarterly export for a churn and propensity model. The request combines a saved segment, several attributes, three events over Q1 with one filtered to USD purchases, event tags, and Parquet output for the warehouse.
curl --location --request POST 'https://unification.useinsider.com/api/raw/v2/export' \
--header 'X-PARTNER-NAME: mybrand' \
--header 'X-REQUEST-TOKEN: <request-token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"format": "parquet",
"user_source": "segment",
"segment": {
"segment_id": 12345,
},
"attributes": ["name", "email", "country", "last_purchase_date", "custom.loyalty_tier"],
"events": {
"start_date": 1767225600,
"end_date": 1775001600,
"wanted": [
{
"event_name": "purchase",
"params": ["product_id", "unit_price", "currency"],
"filters": [
{ "key": "currency", "operator": "eq", "values": ["USD"] }
]
},
{
"event_name": "item_added_to_cart",
"params": ["product_id", "product_name"]
},
{
"event_name": "email_open",
"params": ["campaign_id"]
}
]
},
"get_tags": true,
"hook": "https://example.com/hooks/raw-export"
}'Errors
Synchronous errors (400) are returned immediately when the request is invalid. Representative error messages:
format is required / format must be csv or parquet
at least one of attributes or events is required
segment or vertical is required when user_source is segment
segment and user_source=events are mutually exclusive
events is required when user_source is events
invalid attribute <selector> / unknown attribute <selector>
invalid event parameter <selector> / unknown event parameter <selector>
invalid event name <selector>
invalid hook
Rate limit (429): daily quota exceeded. The quota resets at 00:00 UTC.
Asynchronous errors: a request accepted with 200 can surface later as status: "failed" (system error during processing) or status: "rejected" (estimated volume exceeded limits) on the status endpoint and in the webhook payload.
invalid vs. unknown:
invalid means the name is malformed, such as wrong shape, uppercase characters, a c_ prefix, or an internal code. unknown means the name is well-formed but not registered for your account. The error message echoes the exact selector you sent.
Error reference
Use this table to identify and resolve the errors this endpoint returns. Each row shows the status code, the response body you receive, what causes it, and how to fix it.
Status | JSON response | Cause | Fix |
|---|---|---|---|
400 Bad Request | "format is required" "format must be csv or parquet" | The format field is missing, or it holds a value other than csv or parquet. | Set format to either csv or parquet. |
400 Bad Request | "at least one of attributes or events is required" | The request defines a user set but does not say what to export. | Include an attributes array, an events object, or both. |
400 Bad Request | "segment or vertical is required when user_source is segment" | user_source is set to segment, but neither a segment nor a vertical is named. | Add the segment or vertical field, or change user_source to events. |
400 Bad Request | "segment and user_source=events are mutually exclusive" | The request names a segment while user_source is set to events. The two ways of defining a user set cannot be combined. | Choose one. Use user_source=segment with a segment, or user_source=events with an events object. |
400 Bad Request | "events is required when user_source is events" | user_source is set to events, but no events object defines which events form the user set. | Add the events object, including the wanted entries that select the user set. |
400 Bad Request | "invalid attribute <selector>" "unknown attribute <selector>" | invalid means the name is malformed, for example, an internal short code such as em, a raw c_ prefix, uppercase characters, or a dot in the wrong place. unknown means the name is well-formed but is not registered for your account. | V2 accepts public names only. Use email rather than em, and custom.<name> for custom attributes. The error echoes the exact selector you sent, so compare it against your attribute list in the panel. |
400 Bad Request | "invalid event parameter <selector>" "unknown event parameter <selector>" | The event parameter name is malformed, or it is well-formed but not registered for your account. Sending pid instead of product_id is a common case. | Use the public parameter name, for example product_id. Address custom parameters through the custom. namespace, for example custom.loyalty_tier. |
400 Bad Request | "invalid event name <selector>" | The event name is malformed or is not a recognized event for your account. | Use the event name exactly as it appears in your panel, in lowercase. |
400 Bad Request | "invalid hook" | The hook field is missing, or the URL has no scheme or host. | Supply a complete URL including scheme and host, for example, https://example.com/callback. The field is required. |
429 Too Many Requests | "daily quota exceeded" | You reached the daily export quota. Failed requests do not count against it. | Wait for the quota to reset at 00:00 UTC. To request a higher quota, contact the Insider One team. |
200 OK, then status: "failed" | {"status": "failed"} | The export was accepted, but a system error occurred during processing. This surfaces on the status endpoint and in the webhook payload, not in the original response. | Poll the status endpoint or handle the webhook rather than treating the initial 200 as completion. Resubmit the export. If it fails again, contact the Insider One team with the export_id. |
200 OK, then status: "rejected" | {"status": "rejected"} | The export was accepted, but the estimated output volume exceeded the allowed limits. | Narrow the user set, reduce the number of attributes and event parameters, or shorten the date range, then resubmit. |
FAQs
Naming and selectors
Q: Why is my request returning "invalid attribute" or "invalid event parameter"?
A: You most likely sent an internal short code such as em or pid, or a raw c_ custom code. v2 accepts public names only. Use email, product_id, and custom.<name>. The error echoes the exact selector you sent.
Q: What is the difference between "invalid" and "unknown" in an error?
A: invalid means the name is malformed, such as wrong shape, uppercase characters, a dot in the wrong place, a c_ prefix, or an internal code. unknown means the name is well-formed but not registered for your account.
Q: How do I address a custom attribute or event parameter?
A: Use the custom. namespace, for example, custom.loyalty_tier. Output columns also return as custom.<name>.
Q: How do I find the public names for attributes and events?
A: See the Metadata Name Reference for all default names.
Export behavior and output
Q: Is the export synchronous?
A: No. The POST endpoint returns an export_id immediately. Collect the files by polling GET /api/raw/v2/export/{export_id} or by handling the webhook delivered to your hook URL.
Q: Why did I receive multiple files for one export?
A: Large exports are chunked for scale; attribute files are split by ID range, and event files are split by event name and date range. You also always receive attribute files and event files separately since there is no server-side join.
Q: How do I join attributes to events?
A: Join on insider_id. It is the first column in every attribute file and is present in every event row.
Q: Can I export all attributes at once?
A: Yes. Pass "attributes": ["*"]. It expands to all registered attributes under their public names. It cannot be combined with named selectors in the same request.
Q: What formats are supported?
A: CSV and Parquet. JSON output is not supported. CSV headers and Parquet column names are identical for the same request, so one parsing pipeline handles both formats.
Q: How long are the download URLs valid?
A: Signed download URLs are valid for approximately 24 hours. Download files promptly after the export completes.
Q: Can I export directly to my own S3 bucket?
A: No. Insider One prepares files in its own S3 bucket and delivers signed download URLs to your webhook and the status endpoint. Download the files from those URLs into your own systems.
User set and filtering
Q: How do I choose which users are exported?
A: Pass a saved segment with user_source: "segment", or let an events query define the user set with user_source: "events". The two modes are mutually exclusive; passing a segment object alongside user_source: "events" is rejected.
Q: What does a rejected status mean?
A: The estimated volume of your export exceeded processing limits, and the job was turned down before running. Narrow the request, such as a smaller segment, a shorter date range, or fewer events, and retry.
Rate limits
Q: What are the rate limits?
A: 10 export requests per account per UTC day. The quota resets at 00:00 UTC. Requests that return a non-success response do not count against the daily quota.