> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sprig.com/llms.txt
> Use this file to discover all available pages before exploring further.

# In-product targeting

> Configure Event triggers, audience rules, and delivery delay for an in-product survey.

Targeting is a single sub-resource of an `IN_PRODUCT_SURVEY` Study. It contains the complete delivery
decision:

* `triggers`: existing Events that can trigger the Study.
* `audience`: visitor conditions evaluated for eligibility.
* `delaySeconds`: how long to wait after the trigger before presentation.

Targeting does not apply to a shareable `SURVEY`.

## Create or replace targeting

`PUT /v2/studies/{studyId}/targeting` creates targeting when none exists and replaces the complete
resource on later calls. There is no separate create operation and no partial update.

1. Read the Study and save its ETag.
2. List Events and select at least one Event UUID.
3. Optionally list Attribute definitions and compose an audience expression.
4. Send the entire targeting document with `If-Match`.
5. Save the new ETag returned by the `204` response.

```bash theme={null}
curl --request PUT "https://api.sprig.com/v2/studies/$STUDY_ID/targeting" \
  --header "Authorization: API-Key $SPRIG_API_KEY" \
  --header 'If-Match: "126300"' \
  --header "Content-Type: application/json" \
  --data '{
    "triggers": [
      {"id": "11111111-1111-4111-8111-111111111111"}
    ],
    "audience": {
      "operator": "AND",
      "conditions": [
        {
          "type": "ATTRIBUTE",
          "attribute": "plan",
          "comparator": "EQUALS",
          "value": "enterprise"
        },
        {
          "type": "SESSION_COUNT",
          "comparator": "GREATER_THAN_OR_EQUAL",
          "value": 2
        }
      ]
    },
    "delaySeconds": 10
  }'
```

`GET /v2/studies/{studyId}/targeting` returns `null` when targeting has not been configured.
`DELETE /v2/studies/{studyId}/targeting` clears every trigger, audience rule, and delay without
deleting referenced Event, Attribute, or Group definitions.

## Trigger Events

Call `GET /v2/events` to list Event definitions in the authenticated environment. A trigger
references the returned `id`, not an internal numeric Event ID or Event name.

Supported Event definitions are:

* `TRACKED`: a code Event sent by a Sprig SDK.
* `PAGE_URL`: a page URL Event configured for Web delivery.

Each Study needs 1–10 unique triggers. Multiple triggers use **OR** semantics: any one matching Event
can trigger the Study. Event properties are not part of this public targeting contract.

> [!WARNING]
>
> The Study API lists existing Events but does not create them. A new code Event must be sent by an SDK
> and approved in **Events > Manage Requests** before it can be used.

## Audience expressions

Set `audience` to `null` to make every visitor eligible after a trigger. Otherwise, provide one
condition or a nested group:

```json theme={null}
{
  "operator": "OR",
  "conditions": [
    {
      "type": "USER_ID",
      "comparator": "EXISTS"
    },
    {
      "type": "LANGUAGE",
      "comparator": "EQUALS",
      "value": "fr"
    }
  ]
}
```

Groups use `AND` or `OR` and can contain conditions or more groups. The limits are:

* At most 5 expression levels.
* At most 20 direct children in one group.
* At most 100 conditions in the complete audience expression.

## Condition reference

| Condition | Purpose | Comparators |
| - | - | - |
| `ATTRIBUTE` | Match a visitor attribute by stable key. | Scalar comparison, text matching, `EXISTS`, `NOT_EXISTS` |
| `USER_ID` | Distinguish identified and anonymous visitors. | `EXISTS`, `NOT_EXISTS` |
| `LANGUAGE` | Match the SDK locale or language code. | `EQUALS` |
| `DEVICE_TYPE` | Match `DESKTOP` or `MOBILE` browser class. Web only. | `EQUALS`, `NOT_EQUALS` |
| `GROUP` | Match an existing environment Group by stable ID. | `IN`, `NOT_IN` |
| `SESSION_COUNT` | Match total visitor sessions from 1–999. | Numeric comparison |
| `PAGE_VIEW_COUNT` | Match page views in the current session from 1–999. Web only. | Numeric comparison |

Numeric comparators are `EQUALS`, `GREATER_THAN`, `GREATER_THAN_OR_EQUAL`, `LESS_THAN`, and
`LESS_THAN_OR_EQUAL`.

Attribute scalar comparison also supports `NOT_EQUALS`. Text comparison supports `CONTAINS`,
`NOT_CONTAINS`, `STARTS_WITH`, and `ENDS_WITH`.

Call `GET /v2/attributes` for valid Attribute keys and authoring value types. Definitions do not
include observed visitor values.

Reference fields have these limits:

* Attribute keys and Group IDs: 1–128 characters.
* Language or locale values: 1–35 characters.
* Session and page-view counts: integers from 1–999.

`GROUP` requires an existing environment Group ID. Study API V2 does not create or list Groups, so
an integration must already have the stable ID. If your integration does not have it, configure a
different supported condition or contact [support@sprig.com](mailto:support@sprig.com).

## Delivery delay

`delaySeconds` is an integer from 0 through 999. Use `0` to present immediately after a qualifying
trigger. A delay can protect a critical flow from interruption, but eligibility can change while the
timer runs.

## Validation and compatibility

An in-product survey cannot launch without at least one trigger. The validation endpoint reports
`TARGETING_REQUIRED` at `targeting/triggers` when targeting is missing.

The API returns:

* `INVALID_STUDY` with detailed issues for an invalid expression or unresolved reference.
* `STUDY_NOT_FOUND` when targeting is requested for a shareable survey.
* `UNSUPPORTED_TARGETING` when existing legacy targeting cannot be represented safely.
* `400 INVALID_VALUE` for a malformed or unquoted `If-Match`, `412 CONCURRENT_UPDATE` for a stale
  ETag, or `428 CONCURRENT_UPDATE` when `If-Match` is missing.

Do not replace incompatible legacy targeting merely to suppress `UNSUPPORTED_TARGETING`; review the
Study in Sprig first.
