Skip to main content
Audience profiles hold contact details that you supply for campaign audiences. A profile belongs to your team and is identified by its E.164 phone number. Profile attributes and consent assertions do not override STOP opt-outs or grant permission to send a campaign. Creating or updating profiles and starting imports require enrollment in the audience profiles beta. Reading profiles, polling or cancelling imports, and deleting profiles stay available if your team leaves the beta, so you can always inspect and remove the data you stored. Use a team API key with campaigns:read to read profiles and import reports, or campaigns:manage to change them. Project tokens cannot access team profiles.

Create or update a profile

Send the phone number in the path. Provide tags and attributes even when they are empty. Omit expectedRevision for a new profile; use the revision from the latest read when replacing an existing profile.
The response includes the profile’s revision. A stale revision returns 409; read the profile again before applying your intended replacement. A team can hold at most 100,000 profiles, including deleted profiles pending expiry. A deleted profile releases capacity only after its deletion record is purged. To record a consent assertion, include consent with purpose: "campaigns", source, a reference to your evidence, allowed, and assertedAt as Unix milliseconds. Read assertions with GET /platform/audience-profiles/{phone}/consent. Assertions record what you supplied; they do not clear an opt-out.

Delete and recreate a profile

Delete a profile with its current revision:
Deletion removes the profile’s tags, attributes, consent assertions and its membership in every audience, together with that member’s variables. It also clears the preview row of each of those audiences. It does not change recipients already added to a campaign, including draft campaigns, CSV files you uploaded earlier, or your team’s opt-outs. Remove a draft campaign’s recipient separately if you no longer want to contact them. Polymorfa keeps a deletion record with the phone number and a new revision for 30 days, so delayed writes cannot bring the contact back. During those 30 days:
  • adding the phone to an audience returns 409 naming its row, numbered as in invalidRows; nothing in that request is added
  • recreating the profile requires expectedRevision set to the revision the delete returned; a put without it returns 409 with a message naming that revision

Import profiles from CSV

Submit one UTF-8 CSV file of at most 10 MiB and 10,000 data rows per job. The header must include phone, tags, and attributes unless you provide a column mapping. tags contains a JSON array; attributes contains a JSON object. Optional columns are expectedRevision, provenanceReference, consentAllowed, consentAssertedAt, and consentReference. Supply all three consent columns together when recording an assertion. A row for a phone that already has a profile, including one deleted in the last 30 days, must carry that profile’s current expectedRevision; otherwise the row is reported as a conflict and the profile is left unchanged. The timestamp uses a date-time that JavaScript can parse, such as 2026-09-27T00:00:00Z. If your CSV uses different names, pass mapping in the import request. Map phone, tags, and attributes to their exact header names; map any optional fields you want to import. Unmapped columns are ignored. A file can have at most 32 columns, and each header name can use at most 64 UTF-8 bytes.
Encode the file as standard padded base64 and send it with a replay key:
The file is piped through jq and curl, so a file near the 10 MiB limit does not hit the shell’s argument size limit. For a file with Mobile, Labels, and Fields headers, add this object to the JSON request:
Only one import per team can be queued or running. Repeating the same replay key with the same file, mapping, and key returns its existing job; reusing it with different content or mapping returns 409. An oversized file or row count returns 413. Use GET /platform/audience-profile-imports/{jobId} to check the job. The report includes processed, created, updated, invalid, and conflicting counts, plus up to 20 row numbers and reason codes for each failure category. It does not include submitted phone numbers or attribute values. When the job completes, its CSV is removed. The aggregate report remains available for 30 days. An import that has not finished seven days after you submit it is cancelled and its CSV removed; profile changes from batches that already ran remain. Use DELETE /platform/audience-profile-imports/{jobId} to cancel the remaining work. Profile changes committed by earlier batches remain. Cancellation removes the CSV and retains the aggregate report for 30 days.