# Evaluate query

Evaluate a CQL expression from a browser or device.

```
POST https://api.croct.io/client/web/evaluate
```

Evaluates a [CQL](/reference/cql/introduction) expression against the current user context and returns the result as a JSON value.

This is the client-side variant, intended for calls originating from a browser or device. It authenticates with the public [application ID](/explanation/application), enforces CORS checks against the application's [trusted origins](/explanation/application/trusted-origins), and applies rate limits tuned for browser traffic. For calls from your backend, use the [server-side variant](/reference/api/service/evaluation/endpoint/server/evaluate) instead.

## Example

Here is an example of how to evaluate an expression:

**JavaScript**

```js
const response = await fetch('https://api.croct.io/client/web/evaluate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-App-Id': '<APP ID>',
    'X-Client-Id': '<CLIENT ID>',
    'X-Token': '<USER TOKEN>',
    'X-Client-Ip': '192.0.2.10',
    'X-Client-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
    'X-Client-Library': 'Custom Client v1.0.0',
  },
  body: JSON.stringify({
    query: "user is returning",
    context: {
      timeZone: 'America/New_York',
      page: {
        url: 'https://example.com/pricing',
        title: 'Pricing',
        referrer: 'https://google.com',
      },
      campaign: {
        name: 'summer-sale',
        source: 'google',
        medium: 'cpc',
      },
      attributes: {
        plan: 'pro',
      },
    },
  }),
});

const result = await response.json();
```

**cURL**

```bash
curl -X POST 'https://api.croct.io/client/web/evaluate' \
  -H 'Content-Type: application/json' \
  -H 'X-App-Id: <APP ID>' \
  -H 'X-Client-Id: <CLIENT ID>' \
  -H 'X-Token: <USER TOKEN>' \
  -H 'X-Client-Ip: 192.0.2.10' \
  -H 'X-Client-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36' \
  -H 'X-Client-Library: Custom Client v1.0.0' \
  -d '{
    "query": "user is returning",
    "context": {
      "timeZone": "America/New_York",
      "page": {
        "url": "https://example.com/pricing",
        "title": "Pricing",
        "referrer": "https://google.com"
      },
      "campaign": {
        "name": "summer-sale",
        "source": "google",
        "medium": "cpc"
      },
      "attributes": {
        "plan": "pro"
      }
    }
  }'
```

## Request headers

This endpoint accepts the following HTTP headers:

- `Content-Type`: `string`

  Must be `application/json`.

- `X-App-Id`: `string`

  The public [application ID](/explanation/application) to use for client-side requests.

- `X-Client-Id`: `string` (optional)

  The ID of the client, in the form of a UUID.

  This must be a persistent identifier that uniquely identifies the browser or device across sessions.

  Either `X-Client-Id` or [`X-Token`](#x-token-prop) must be present.

- `X-Token`: `string` (optional)

  A base64-encoded [JSON Web Token (JWT)](https://jwt.io) that identifies the user.

  When the application enforces [signed tokens](/explanation/application/signed-tokens), the JWT must be signed using an [API key](/explanation/application/api-keys) with the **Issue user tokens** permission, or the request fails with an authorization error.

  Either `X-Client-Id` or [`X-Token`](#x-token-prop) must be present.

- `X-Client-Library`: `string` (optional)

  The SDK name and version, such as `Croct SDK JS v0.20.0`.

  Used for usage statistics and feature switching to preserve backward compatibility across SDK versions.

- `Origin`: `string` (optional)

  The origin of the request.

  Must match one of the application's [trusted origins](/explanation/application/trusted-origins). Browsers set this header automatically.

## Parameters

This endpoint accepts the following JSON body parameters:

- `query`: `string`

  The [CQL](/reference/cql/introduction) expression to evaluate.

  Must be between 1 and 500 UTF-8 characters.

- `context`: `object|null` (optional)

  Information about the user context, such as the time zone, page, and marketing campaign.

  Used to provide additional signals to [CQL](/reference/cql/introduction) expression evaluation.

  - `timeZone`: `string|null` (optional)

    The time zone of the user, represented by an [IANA time zone ID](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), such as `America/New_York`.

    Used in time-based [CQL](/reference/cql/introduction) expressions.

  - `page`: `object|null` (optional)

    Information about the page the user is currently viewing.

    - `url`: `string`

      The URL of the page, such as `https://www.example.com/products`.

      Required when `page` is provided.

    - `title`: `string|null` (optional)

      The title of the page, such as `Products`.

    - `referrer`: `string|null` (optional)

      The URL of the page that linked to the current page, such as `https://www.google.com`.

  - `campaign`: `object|null` (optional)

    Information about the marketing campaign that brought the user to the page.

    These properties are compatible with the [UTM parameters](https://en.wikipedia.org/wiki/UTM_parameters) widely used in digital marketing for tracking and analytics.

    - `name`: `string|null` (optional)

      A unique identifier for the campaign. It is usually a short string, such as `summer-sale` or `new-product-launch`.

    - `source`: `string|null` (optional)

      The advertiser, site, or publication generating the traffic. For example, `google`, `facebook`, or `newsletter`.

    - `medium`: `string|null` (optional)

      The advertising or marketing channel used to reach the user. For example, `email`, `video`, or `social`.

    - `content`: `string|null` (optional)

      An identification of the specific ad or content the user interacted with. For example, `main-banner` or `newsletter-cta`.

    - `term`: `string|null` (optional)

      The keyword or term that triggered the ad. For example, `running shoes` or `tennis racket`.

  - `attributes`: `object|null` (optional)

    Custom key-value pairs available in [CQL](/reference/cql/introduction) expressions through the `context` variable.

    For example, suppose you pass the following attributes:

    ```json
    {"cities": ["New York", "San Francisco"]}
    ```

    You can then reference them in queries like:

    ```cql
    context's cities include location's cityName
    ```

    The following restrictions apply:

    - Up to 30 entries and 5 levels deep
    - Keys can be either numbers or non-empty strings with a maximum length of 50 characters
    - Values can be null, numbers, booleans, strings (up to 50 characters), or nested maps
    - Nested maps follow the same constraints for keys and values

## Response

The service can respond with either `200 OK` or `202 Accepted` status code.

### 200 OK

The response body is the JSON-serializable result of the expression. The type depends entirely on the expression and can be a boolean, number, string, array, or object.

If the expression evaluates to a non-serializable type (such as a raw `weekday`, `user`, or `session` object), the request fails with an [`unserializable-result`](/reference/api/service/evaluation/error/unserializable-result) error instead.

#### Example response

The example query `user is returning` evaluates to a boolean:

```json
true
```

An expression that selects an object returns the corresponding JSON object. For example, evaluating `campaign` returns:

```json
{
  "name": "summer-sale",
  "source": "google",
  "medium": "cpc",
  "term": "pricing",
  "content": "banner-a"
}
```

### 202 Accepted

The request is accepted but the service is suspended and returns no content. Clients should treat this as a traffic control signal, not an error, and fall back to default behavior. The suspension reason is indicated by the `X-Suspension-Reason` header:

- `X-Suspension-Reason`: `string` (optional)

  The reason the API returned an empty response. The possible values are:

  | Value                                    | Description                                                                        |
  | ---------------------------------------- | ---------------------------------------------------------------------------------- |
  | `tracking_and_personalization_suspended` | The workspace has [suspended services](/explanation/workspace/service-suspension). |
