BuildBaseBuildBase

Audience and lists

Manage marketing contacts, tag and segment them, and import a CSV in three steps.

An audience contact is a marketing record. It does not need an account — a newsletter signup is a contact with no user behind it. Contacts are what email campaigns send to and what audience workflow triggers fire on.

curl -G https://api.console.buildbase.app/api/audience \
  -H "Authorization: $BUILDBASE_TOKEN" \
  --data-urlencode 'filter={"unsubscribed":false}' \
  --data-urlencode '$limit=50'

Before you start

Define your audience attributes in the BuildBase console under Audience → Attributes before importing, so CSV columns have something to map onto.

Contacts

MethodPathPurpose
GET/api/audienceList contacts, paginated
GET/api/audience/:idOne contact
POST/api/audienceCreate
PATCH/api/audience/:idUpdate core fields
PATCH/api/audience/:id/attributesUpdate custom attributes
PATCH/api/audience/:id/tagsReplace tags
PATCH/api/audience/:id/blockBlock — excluded from all sending
PATCH/api/audience/:id/unblockRestore
PATCH/api/audience/:id/link-userAttach this contact to a user account
DELETE/api/audience/:idDelete

link-user is the bridge between the two identities. Until it is set, a contact and a user with the same email are unrelated records — linking them is what lets the console show one timeline for the person.

Per-contact history is available at /:id/timeline, /:id/activities, /:id/attributes-history, /:id/lists, and /:id/emails.

Lists

Audience lists are the unit a campaign sends to, managed at /api/audience-lists. A contact's memberships are readable from GET /api/audience/:id/lists.

Lists are also what workflows act on: actions.audience_list_add and actions.audience_list_remove move contacts between them, and triggers.audience.added_to_list fires when they do.

Importing a CSV

Import is three calls. The CSV is parsed on upload, held in Redis, then processed by a background job.

1. Upload. Send the file as multipart under the field name file:

curl -X POST https://api.console.buildbase.app/api/audience/import/upload \
  -H "Authorization: $BUILDBASE_TOKEN" \
  -F "[email protected]"
{
  "importId": "9f1c…",
  "headers": ["Email", "Full name", "Company"],
  "rowCount": 1284,
  "previewRows": []
}

previewRows holds the first three parsed rows, so you can show the user what their mapping will do before committing.

2. Start. Map CSV columns to fields and choose what happens on a duplicate:

curl -X POST https://api.console.buildbase.app/api/audience/import/start \
  -H "Authorization: $BUILDBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "importId": "9f1c…",
    "mapping": { "Email": "email", "Full name": "name", "Company": "company" },
    "duplicateStrategy": "update",
    "tags": ["webinar-2026"]
  }'

Returns { "jobId": "…" }.

FieldRequiredNotes
importIdYesFrom step 1
mappingYesCSV header → field. Must map both email and name
duplicateStrategyNoupdate (default) or skip
tagsNoApplied to every imported contact

3. Poll. The job is asynchronous:

curl https://api.console.buildbase.app/api/audience/import/status/$JOB_ID \
  -H "Authorization: $BUILDBASE_TOKEN"
{ "state": "completed", "progress": 100, "result": {}, "failedReason": null }

An unknown job id returns 404. Fetch a template with the org's attribute columns already present from GET /api/audience/import/sample.

Warning

Uploaded CSVs expire after 30 minutes. The parsed file is held in Redis between steps 1 and 2, so a user who leaves the mapping screen open too long gets 400 with "Import data expired. Please re-upload the CSV file."

Do not treat importId as durable — it is a handle on a short-lived buffer, not a stored import.

Mapping validation rejects the whole import if email or name is missing, so check the mapping before calling start rather than after.

Exporting

GET /api/audience/export returns the audience as CSV. It honours the same filter parameter as the list endpoint, so you can export a segment rather than everything.

Next Steps