Skip to content

Create an audience

POST
/audience/management/v1/audiences
curl --request POST \
--url https://api.ebitex.io/audience/management/v1/audiences \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "externalId": "example", "name": "example", "predicate": "example", "rowVersion": 1, "behaviours": [ { "id": "example", "kind": "example", "filter": "example", "minCount": 1, "days": 1, "scope": "example", "minMembers": 1 } ], "scorePoints": 1 }'

Creates an audience from a externalId (lowercase letters, digits and hyphens, 3 to 64 characters, unique in the organization), a name and a predicate.

predicate is one predicate tree: equals, notEquals, in, compare (lt, lte, gt, gte), exists, notExists, allOf and anyOf, each naming a property of a flat bag. The bag is the request’s own context (the members the presentation app sends) plus, for a person Audience recognises on that device, members under individual: individual.recognised, individual.stages.open, individual.stages.reached, individual.stage.<stage>.state, individual.stage.acquisition.score, individual.attribute.<field> and individual.permission.<channel>, and, for an organization that uses accounts, individual.account.member and individual.account.attribute.<field> (an account’s custom field, as a list over the person’s accounts, so it matches when any of their accounts does). Any other individual.* name is refused.

An audience that reads individual.* is never true for a visitor Audience cannot recognise, even when its predicate is a negation.

A predicate may name another audience as audience.member.<id> (true when the person is in it), and the audience takes on the scope of everything it names; audiences cannot name each other in a loop, and one another names cannot be deleted. behaviours declares things a person did ({ id, kind, filter, minCount, days }, kinds form.submitted, audience.entered, stage.moved and content.viewed (page views in the category filter names, over 1 to 365 days), at most 5), which the predicate reads as individual.did.<id>. With scope: "account" and minMembers (1 to 1,000) a behaviour counts what the people in a person’s accounts did instead: it is true for the person when, in any of their accounts, at least minMembers members each did it at least minCount times in the window. A member who joins an account brings what they did, and one who leaves takes it. Account names and account behaviours are refused with 409 accounts_not_enabled while the organization has accounts off; an audience saved earlier is kept, and has no members until they are turned on.

scorePoints (-100 to 100, never 0; send 0 to remove) makes the audience add that many points to the lead score of everyone in it. The score is the sum over the audiences a person is in, held between 0 and 100. Only an audience that reads a person and nothing about the request may add points, and one that adds points cannot read a score, directly or through an audience it names. While any audience adds points the acquisition score fact is calculated, and writing it answers 409 score_is_computed.

An organization can hold at most 200 audiences.

Key: an Audience management key with audience.management.write (write also needs read; erase needs both).

Media typeapplication/json
object
externalId
required
null | string
name
required
null | string
predicate
required
One of:
null
rowVersion
required
null | integer | string format: uint32
/^-?(?:0|[1-9]\d*)$/
behaviours
Array<object> | null
object
id
required
string
kind
required
string
filter
required
null | string
minCount
required
integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
days
required
integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
scope
null | string
minMembers
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
scorePoints
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
Examplegenerated
{
"externalId": "example",
"name": "example",
"predicate": "example",
"rowVersion": 1,
"behaviours": [
{
"id": "example",
"kind": "example",
"filter": "example",
"minCount": 1,
"days": 1,
"scope": "example",
"minMembers": 1
}
],
"scorePoints": 1
}

{ "id", "externalId", "name", "predicate": { … }, "revision", "scope", "storedMembership", "memberCount", "membershipCurrent", "createdAtUtc", "updatedAtUtc", "rowVersion", "behaviours": [ … ] }. scope is context (reads only the request’s own context), individual (reads only what Audience knows about a recognised person) or mixed.

validation_failed: the key, name or predicate is invalid; errors is keyed by field.

missing_api_key or invalid_api_key: no key was sent, or it is unknown, revoked or expired, or it was not created from the Audience settings page.

payment_required: the organization’s subscription needs attention.

scope_denied: the key lacks this route’s scope. ip_denied: the caller’s address is outside the key’s allowed ranges. app_not_available: Audience is not enabled for the organization.

not_found: no such route.

audience_limit_reached: the organization already holds 200 audiences.

rate_limited: the key spent its requests-per-minute budget; Retry-After says how long to wait. too_many_failed_authentications: too many bad keys from this address.