Bring your history from AppsFlyer, Adjust or Branch, and take it out again whenever you want.
Loads an export from your current platform into Measura as historical events, installs and attributions, so your cohorts and channel breakdowns cover the period before you switched.
Imported attributions are kept as the source reported them. No export carries the click-level signals needed to re-run our matching, so imported records score zero confidence and carry a written reason naming their origin. They are never confused with attributions Measura resolved itself.
| Requirement | Value |
|---|---|
| Formats | CSV or JSON (an array of objects) |
| Maximum size | 5 MB per upload |
| Maximum rows | 50,000 per upload |
| Content type | text/csv, application/json or text/plain |
| Encoding | UTF-8 |
Larger histories are imported as a sequence of uploads. Split by date range so a failed batch is easy to identify and re-run.
Export everything your platform offers. Unmapped columns are ignored rather than rejected, so a wider export costs nothing. At minimum, include the event timestamp, the event name, and at least one device identifier.
Use the raw data export. These columns are recognised automatically.
| AppsFlyer column | Measura field |
|---|---|
| Install Time | installed_at |
| Event Time | event_timestamp |
| Event Name | event_type |
| AppsFlyer ID | external_device_id |
| Advertising ID | gaid |
| Campaign | campaign_name |
| Media Source | channel |
| Attribution Type | attribution_model |
| Revenue | revenue |
| Currency | currency |
| Country Code | country_code |
| IP | ip |
| Device Type | device_model |
| OS Version | os_version |
| App Version | app_version |
| Adjust column | Measura field |
|---|---|
| installed_at | installed_at |
| event | event_type |
| gps_adid | gaid |
| network_name | channel |
| campaign_name | campaign_name |
| attribution_type | attribution_model |
| revenue_usd | revenue |
| country | country_code |
| ip_address | ip |
| device_name | device_model |
| os_name | os_name |
| os_version | os_version |
| app_version | app_version |
| Branch column | Measura field |
|---|---|
| Timestamp | event_timestamp |
| Name | event_type |
| AAID | gaid |
| Channel | channel |
| Campaign | campaign_name |
| Revenue | revenue |
| Country | country_code |
| OS | os_name |
| OS Version | os_version |
| App Version | app_version |
Branch exports carry no dedicated install time column, so the event timestamp is used for install rows.
Choosing custom applies no column translation. Your file must already use Measura field names.
[
{
"event_timestamp": "2026-05-14T08:31:02Z",
"installed_at": "2026-05-14T08:31:02Z",
"event_type": "install",
"gaid": "38400000-8cf0-11bd-b23e-10b96e40000d",
"channel": "whatsapp",
"campaign_name": "lagos-launch-may",
"attribution_model": "deterministic",
"revenue": 0,
"currency": "USD",
"device_model": "Samsung SM-A245F",
"os_name": "android",
"os_version": "14",
"app_version": "2.1.0"
}
]This is also the route for a platform we do not map natively. Rename the columns in your export tooling, then import as custom.
Source network names are translated to Measura channels. Anything unrecognised is lowercased with spaces replaced by underscores and carried through as is.
| Source value | Measura channel |
|---|---|
| Facebook Ads, facebook | meta |
| Google AdWords, google_ads | google |
| TikTok Ads | tiktok |
| Twitter Ads | twitter |
whatsapp | |
email | |
| SMS | sms |
| organic, Organic | organic |
| Source value | Measura event type |
|---|---|
| install, af_install | install |
| open, session | open |
| session_start | session_start |
| purchase, revenue, af_purchase | purchase |
| anything else | custom |
| Source value contains | Measura model |
|---|---|
| organic | organic |
| deterministic, device_id | deterministic |
| probabilistic, fingerprint | probabilistic |
| anything else | last_click |
The developer dashboard provides this flow under Migrate. To automate it, call the three endpoints directly.
# 1. Create the job
curl -X POST "$MEASURA_HOST/v1/migration-importer/start" \
-H "Authorization: Bearer $SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"app_id":"7d2e5b1a-...","source_platform":"appsflyer"}'
# → {"job_id":"c4a9...","column_mapping":{...}}
# 2. Upload the export
curl -X POST "$MEASURA_HOST/v1/migration-importer/upload?job_id=c4a9..." \
-H "Authorization: Bearer $SESSION_TOKEN" \
-H "Content-Type: text/csv" \
--data-binary @appsflyer-export.csv
# → {"job_id":"c4a9...","total_rows":24500,"status":"processing"}
# 3. Poll until complete
curl "$MEASURA_HOST/v1/migration-importer/status?job_id=c4a9..." \
-H "Authorization: Bearer $SESSION_TOKEN"
# → {"status":"completed","processed_rows":24500,"progress_pct":100,"errors":[]}Full request and response detail is in the API Reference.
A job completes when fewer than five percent of rows produced errors. At or above that threshold the job is marked failed, on the basis that a systematic problem such as a wrong platform selection or a malformed file should not be quietly half applied.
Rows that error are listed individually in the status response with the reason, so you can correct and re-upload just those.
0 and a reason recording the source platform. Imported history is never mixed with scores Measura computed.skipped, so importing history never fires conversion notifications to advertising networks.migration-import/{platform} and a fraud score of zero.Export everything Measura holds for your account at any time, without asking us and without a fee.
curl -X POST "$MEASURA_URL/rest/v1/rpc/export_my_account_data" \
-H "apikey: $ANON_KEY" \
-H "Authorization: Bearer $SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{}' > measura-export.jsonThe export contains your apps, campaigns, short links, installs, attributions with their full confidence breakdown, raw events, fraud flags and payment records, plus a totals block so you can check nothing was truncated.
Remove the Measura dependency and the initialisation call. Nothing is left behind on the device except the local event queue, which is cleared when the app is uninstalled. There is no server call required to deactivate.
Exporting does not delete. Once you have confirmed your export is complete, raise a deletion request from the dashboard; the account is erased on approval. Deletion is irreversible, so it is a deliberate separate step, never a side effect of exporting.
Migrating a large history, or coming from a platform not listed here? Talk to us and we will work through it with you.