Audiences
Audiences define targeting rules within a campaign. Each audience has a set of filters that determine which users match, a priority order for evaluation, and optional entitlement checks, frequency caps, and inline experiments.
All audience endpoints require a private API key (Authorization: Bearer sk_...).
Create an Audience
POST /v1/projects/:id/campaigns/:cid/audiencesRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Audience name |
filters | array | Yes | Array of filter objects (see Filter Operators below) |
entitlement_check | string | No | Entitlement key to check before showing a paywall (e.g., "pro") |
frequency_cap | string | No | Frequency cap expression (e.g., "3/day", "1/session") |
experiment | object | No | Inline experiment definition (see Inline Experiments) |
Filter Object
| Field | Type | Required | Description |
|---|---|---|---|
field | string | Yes | The user property or event field to filter on |
operator | string | Yes | Comparison operator (see table below) |
value | any | Yes | The value to compare against |
conjunction | string | No | "and" (default) or "or" -- how this filter combines with the previous one |
Example
curl -X POST https://agentwallie.com/api/v1/projects/PROJECT_ID/campaigns/CAMPAIGN_ID/audiences \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_private_key" \
-d '{
"name": "Power Users - US",
"filters": [
{ "field": "country", "operator": "is", "value": "US" },
{ "field": "event_count", "operator": "gte", "value": 50, "conjunction": "and" }
],
"entitlement_check": "pro",
"frequency_cap": "1/session"
}'Response 201 Created
{
"id": "aud_abc123",
"name": "Power Users - US",
"priorityOrder": 0,
"entitlementCheck": "pro",
"frequencyCap": "1/session",
"campaignId": "CAMPAIGN_ID",
"createdAt": "2025-01-15T10:00:00.000Z",
"updatedAt": "2025-01-15T10:00:00.000Z",
"filters": [
{
"id": "flt_001",
"field": "country",
"operator": "is",
"value": "US",
"conjunction": "and",
"audienceId": "aud_abc123"
},
{
"id": "flt_002",
"field": "event_count",
"operator": "gte",
"value": "50",
"conjunction": "and",
"audienceId": "aud_abc123"
}
],
"experiment": null
}New audiences are automatically assigned the next priority order. The first audience created gets priorityOrder: 0, the second gets 1, and so on.
Filter Operators
| Operator | Description | Example Value |
|---|---|---|
is | Exact match | "US" |
is_not | Not equal | "US" |
contains | String contains substring | "gmail" |
gt | Greater than | 10 |
gte | Greater than or equal | 10 |
lt | Less than | 5 |
lte | Less than or equal | 5 |
in | Value is in array | ["US", "CA", "UK"] |
not_in | Value is not in array | ["CN", "RU"] |
exists | Field exists (non-null) | true |
not_exists | Field does not exist | true |
Filter values are stored as strings internally. Non-string values (numbers, arrays) are JSON-serialized on storage and deserialized on evaluation.
List Audiences
GET /v1/projects/:id/campaigns/:cid/audiencesReturns all audiences for the campaign, ordered by priorityOrder ascending. Includes filters.
Example
curl https://agentwallie.com/api/v1/projects/PROJECT_ID/campaigns/CAMPAIGN_ID/audiences \
-H "Authorization: Bearer sk_your_private_key"Response 200 OK
[
{
"id": "aud_abc123",
"name": "Power Users - US",
"priorityOrder": 0,
"entitlementCheck": "pro",
"frequencyCap": "1/session",
"campaignId": "CAMPAIGN_ID",
"filters": [
{ "id": "flt_001", "field": "country", "operator": "is", "value": "US", "conjunction": "and" }
]
},
{
"id": "aud_def456",
"name": "Everyone Else",
"priorityOrder": 1,
"entitlementCheck": null,
"frequencyCap": null,
"campaignId": "CAMPAIGN_ID",
"filters": []
}
]Reorder Audiences
PUT /v1/projects/:id/campaigns/:cid/audiences/reorderSets the priority order of audiences. Audiences are evaluated in priority order during SDK config resolution -- the first matching audience wins.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
order | string[] | Yes | Array of audience IDs in desired priority order (index 0 = highest priority) |
Example
curl -X PUT https://agentwallie.com/api/v1/projects/PROJECT_ID/campaigns/CAMPAIGN_ID/audiences/reorder \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_private_key" \
-d '{
"order": ["aud_def456", "aud_abc123"]
}'Response 200 OK
Returns the full list of audiences with updated priorityOrder values.
Update an Audience
PUT /v1/projects/:id/campaigns/:cid/audiences/:aidAll fields are optional. If filters is provided, all existing filters are replaced.
Request Body
| Field | Type | Description |
|---|---|---|
name | string | New audience name |
filters | array | Replacement filter array (deletes all existing filters and creates new ones) |
entitlement_check | string | Updated entitlement key |
frequency_cap | string | Updated frequency cap |
Example
curl -X PUT https://agentwallie.com/api/v1/projects/PROJECT_ID/campaigns/CAMPAIGN_ID/audiences/aud_abc123 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_private_key" \
-d '{
"name": "Power Users - North America",
"filters": [
{ "field": "country", "operator": "in", "value": ["US", "CA"], "conjunction": "and" },
{ "field": "event_count", "operator": "gte", "value": 50, "conjunction": "and" }
]
}'Response 200 OK
Returns the updated audience with filters.
Delete an Audience
DELETE /v1/projects/:id/campaigns/:cid/audiences/:aidExample
curl -X DELETE https://agentwallie.com/api/v1/projects/PROJECT_ID/campaigns/CAMPAIGN_ID/audiences/aud_abc123 \
-H "Authorization: Bearer sk_your_private_key"Response 204 No Content
No response body.
Deleting an audience also deletes its filters and any associated experiment. This action cannot be undone.
Inline Experiments
When creating an audience, you can attach an experiment inline. This creates both the audience and an experiment in a single request.
Experiment Object
| Field | Type | Required | Description |
|---|---|---|---|
variants | array | Yes | Array of variant objects (min 1) |
variants[].paywall_id | string | Yes | Paywall ID for this variant |
variants[].traffic_percentage | number | Yes | Traffic allocation (0-100) |
confidence_threshold | number | No | Statistical significance threshold (0-1). Default: 0.95 |
auto_promote | boolean | No | Auto-promote the winner when significance is reached. Default: false |
Example with Inline Experiment
curl -X POST https://agentwallie.com/api/v1/projects/PROJECT_ID/campaigns/CAMPAIGN_ID/audiences \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_private_key" \
-d '{
"name": "US Premium Users",
"filters": [
{ "field": "country", "operator": "is", "value": "US" }
],
"experiment": {
"variants": [
{ "paywall_id": "pw_control", "traffic_percentage": 50 },
{ "paywall_id": "pw_redesign", "traffic_percentage": 50 }
],
"confidence_threshold": 0.95,
"auto_promote": true
}
}'If variant traffic percentages sum to less than 100, the remainder becomes the holdout group. Holdout users see no paywall. Total traffic must not exceed 100%.
The response includes the created experiment with its variants:
{
"id": "aud_xyz789",
"name": "US Premium Users",
"priorityOrder": 0,
"filters": [ ... ],
"experiment": {
"id": "exp_abc123",
"holdoutPercentage": 0,
"confidenceThreshold": 0.95,
"autoPromote": true,
"variants": [
{ "id": "var_001", "paywallId": "pw_control", "trafficPercentage": 50 },
{ "id": "var_002", "paywallId": "pw_redesign", "trafficPercentage": 50 }
]
}
}For full experiment lifecycle management (pause, resume, promote, results), see the Experiments reference.