Fetch content

Fetch personalized content from your backend.

POST
https://api.croct.io/external/web/content

Retrieves the content of a slot on behalf of a specific user, applying audience targeting and experiment assignment. The response reflects the active experience for that user.

This is the server-side variant, intended for calls originating from your backend. It authenticates with an API key and applies rate limits tuned for backend traffic. For calls from a browser or device, use the client-side variant instead.

Example

Here is an example of how to fetch personalized content from a backend:

123456789101112131415161718192021222324252627282930313233343536
const response = await fetch('https://api.croct.io/external/web/content', {  method: 'POST',  headers: {    'Content-Type': 'application/json',    'X-Api-Key': '<API KEY>',    '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({    slotId: 'home-hero',    version: '1',    preferredLocale: 'en-us',    includeSchema: true,    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 {content, metadata} = await response.json();

Request headers

This endpoint accepts the following HTTP headers:

Content-Type
string

Must be application/json.

X-Api-Key
string

The API key to use for server-side requests.

X-Client-Id(optional)
string

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.

X-Token(optional)
string

A base64-encoded JSON Web Token (JWT) that identifies the user.

Pass this header to use the identified user’s context.

When the application enforces signed tokens, the JWT must be signed using an API key with the Issue user tokens permission, or the request fails with an authorization error.

Either X-Client-Id or X-Token must be present.

X-Client-Ip(optional)
string

The IP address of the client.

Defaults to the IP of the incoming request. Passing a loopback address such as 127.0.0.1 also falls back to the request IP, which is useful for local development.

X-Client-Agent(optional)
string

The user agent of the client.

Defaults to the User-Agent header of the incoming request.

X-Client-Library(optional)
string

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.

Parameters

This endpoint accepts the following JSON body parameters:

slotId
string

The ID of the slot to fetch, such as hero-banner.

version(optional)
string

The schema version of the slot to fetch, in major or major.minor format, such as 1 or 1.2.

Defaults to the latest version when omitted.

preferredLocale(optional)
string|null

The locale code of the content to fetch.

The code consists of a two-part string that specifies the language and, optionally, the country. For example, en represents English, en-us stands for English (United States), and pt-br for Portuguese (Brazil). It is case-insensitive and supports both hyphens and underscores as separators to accommodate the different conventions used by browsers, libraries, and other systems.

Falls back to the slot’s default locale when the preferred locale is unsupported or omitted. Pass null to explicitly use the default.

previewToken(optional)
string

A base64-encoded JSON Web Token (JWT) that identifies the preview session.

When previewing content, the platform generates a preview token and passes it to your application as a URL parameter. Forward this token through this field to enable preview mode.

When provided, audience targeting is bypassed and the previewed variant is returned.

includeSchema(optional)
boolean

Whether to include the slot’s content schema in metadata.schema.

Default:false
context(optional)
object

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

Used to evaluate audience targeting rules and CQL expressions.

timeZone(optional)
string

The time zone of the user, represented by an IANA time zone ID, such as America/New_York.

Used to evaluate time-based targeting rules.

page(optional)
object

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(optional)
string

The title of the page, such as Products.

referrer(optional)
string

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

campaign(optional)
object

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

These properties are compatible with the UTM parameters widely used in digital marketing for tracking and analytics.

name(optional)
string

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

source(optional)
string

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

medium(optional)
string

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

content(optional)
string

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

term(optional)
string

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

attributes(optional)
object

Custom key-value pairs available in CQL targeting expressions through the context variable.

For example, suppose you pass the following attributes:

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

You can then reference them in queries like:

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 headers

X-Suspension-Reason(optional)
string

The reason the API returned an empty response.

When the workspace has suspended services, the API returns 202 Accepted with an empty body and this header. Clients should treat this as a traffic control signal, not an error, and fall back to default behavior.

The possible values are:

ValueDescription
tracking_and_personalization_suspendedThe workspace has suspended services.

Response

This endpoint returns a JSON response with the following properties:

content
object

The resolved slot content.

The shape is defined by the slot’s content schema, plus a reserved _component field.

_component
string|null

The component identifier and major version, such as hero-banner@1.

Is null when no component is associated with the slot.

metadata
object

Metadata describing how the content was resolved.

version
string

The resolved slot schema version.

contentSource
string

The source of the returned content. The possible values are:

ValueDescription
slotThe slot’s default content was returned.
experienceAn active experience matched the request.
experimentAn experiment variant was assigned.
experience(optional)
object

Details about the matched experience.

This property is included when contentSource is experience or experiment.

experienceId
string

The ID of the matched experience.

audienceId
string

The ID of the audience the user matched.

experiment(optional)
object

Details about the running experiment.

This property is included when the experience has an active experiment.

experimentId
string

The ID of the experiment.

variantId
string

The ID of the assigned variant.

schema(optional)

The slot’s content schema definition.

Human-readable labels and descriptions are omitted from the returned schema for security reasons, since they may contain sensitive business information.

This property is included only when the request set includeSchema to true.

Example response

Here is an example of a JSON response from this endpoint:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
{  "content": {    "_component": "home-hero@1",    "heading": "Personalized for Pro users",    "cta": {      "label": "Upgrade now",      "link": "https://example.com/upgrade"    }  },  "metadata": {    "version": "1.0",    "contentSource": "experience",    "experience": {      "experienceId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",      "audienceId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",      "experiment": {        "experimentId": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",        "variantId": "6ba7b812-9dad-11d1-80b4-00c04fd430c8"      }    },    "schema": {      "root": {        "type":"structure",        "title":"Hero",        "attributes": {          "heading": {            "position":0,            "type": {              "type":"text"            }          },          "cta": {            "position":1,            "type": {              "type":"structure",              "attributes": {                "label":{                  "position":0,                  "type":{                    "type":"text"                  }                },                "link": {                  "position":1,                  "type": {                    "type":"text"                  }                }              }            }          }        }      },      "definitions": {}    }  }}