Contentful Personalization & Analytics
    Preparing search index...

    Contentful Logo

    Contentful Personalization & Analytics

    API Client

    Guides · Reference · Contributing

    The Contentful Optimization API Client provides low-level transport for the Experience API and Insights API. Application-facing SDKs compose this package with event builders, state management, queueing, and runtime-specific defaults.

    We recommend starting applications with Web, React Web, Node, or React Native SDKs. Use this package directly when building or maintaining SDK layers, tests, tooling, or first-party integrations that need raw API access.

    Important

    Upgrading from v1? Follow the v1-to-v2 migration guide before changing package versions or route-dependent infrastructure.

    Table of Contents

    Install using an NPM-compatible package manager, pnpm for example:

    pnpm install @contentful/optimization-api-client
    

    Import and initialize the unified API client; both CJS and ESM module systems are supported, ESM preferred:

    import { ApiClient } from '@contentful/optimization-api-client'

    const client = new ApiClient({
    spaceId: 'your-space-id',
    environment: 'master',
    })

    Use @contentful/optimization-api-client when you need direct low-level access to the Experience API or Insights API transport surface. Use an application-facing SDK when you need optimization state, consent handling, event builders, entry resolution, tracking, or platform defaults.

    Option Required? Default Description
    spaceId Yes N/A Contentful Space identifier for Experience and Insights API requests
    environment No 'master' Contentful space environment identifier for Experience and Insights APIs
    experience No See Experience options below Experience API endpoint and default request options
    insights No See Insights options below Insights API endpoint options
    fetchOptions No SDK defaults Fetch timeout and retry behavior

    Common Experience API options:

    Option Required? Default Description
    baseUrl No 'https://experience.ninetailed.co/' Base URL for the Experience API
    enabledFeatures No ['ip-enrichment', 'location'] Experience API features for mutation requests
    ip No undefined IP address override for Experience API analysis
    locale No API default Locale query parameter for localized responses
    location No API fallback Request location default for single-profile mutations
    plainText No Endpoint-specific Sends single-profile mutation endpoints as text
    preflight No false Aggregates a profile state without storing it

    Experience mutation request options except baseUrl can also be provided per mutation request. getProfile is a read request and only uses locale from per-call options; mutation-only options such as enabledFeatures, ip, location, plainText, and preflight do not apply. Single-profile mutation requests default to plainText: true and send text/plain unless overridden. Batch profile updates with upsertManyProfiles are the JSON-default exception and use plainText: false by default. locale is sent as the Experience API locale query parameter and can localize profile fields such as location.city and location.country. Higher-level SDK merge-tag helpers resolve against the profile values returned by the Experience API, so applications that render localized Contentful entries commonly pass the same locale used for the CDA entry fetch. Pass a valid locale tag; invalid locale syntax can fail Experience API request validation. See Locale handling in the Optimization SDK Suite for how this request locale relates to Contentful and SDK-resolved locales.

    Common Insights API options:

    Option Required? Default Description
    baseUrl No 'https://ingest.insights.ninetailed.co/' Base URL for the Insights API

    Common fetchOptions are fetchMethod, requestTimeout, retries, intervalTimeout, onFailedAttempt, and onRequestTimeout. Default retries intentionally apply only to HTTP 503 responses.

    For every option, callback payload, request type, and response type, use the generated API Client reference.

    Experience API methods are scoped to client.experience and return profile and optimization data:

    const { profile, selectedOptimizations, changes } = await client.experience.upsertProfile(
    {
    profileId: 'f0837d7dc6344c36a3a0a06c4cde754b',
    events: [pageEvent],
    },
    { locale: 'de-DE' },
    )

    Common methods include getProfile, createProfile, updateProfile, upsertProfile, and upsertManyProfiles.

    Applications can configure request location through their normal SDK's api.location option. Stateless Node integrations can override it per request through forRequest({ experienceOptions: { location } }); see the Node SDK configuration and Web SDK configuration. The direct transport example below is for SDK-layer and tooling consumers.

    For createProfile, updateProfile, and upsertProfile, set location in the Experience client configuration or in per-request options:

    import { ExperienceApiClient } from '@contentful/optimization-api-client'

    const experience = new ExperienceApiClient({
    spaceId: 'your-space-id',
    environment: 'master',
    location: { countryCode: 'DE', country: 'Germany' },
    })

    await experience.createProfile({ events: [pageEvent] })
    await experience.upsertProfile(
    { profileId: 'f0837d7dc6344c36a3a0a06c4cde754b', events: [pageEvent] },
    {
    location: {
    countryCode: 'FR',
    country: 'France',
    city: 'Paris',
    coordinates: { latitude: 48.8566, longitude: 2.3522 },
    },
    },
    )

    With the unified ApiClient, place the constructor default under experience.location. A per-request location replaces the entire constructor default; the client does not merge them. The backend merges each event's context.location over the resolved request location, so event fields override matching request fields. If neither source supplies a location, existing backend fallback behavior applies, including Cloudflare request geolocation when enabled.

    Pass location: {} to override the constructor default and supply an empty request-location default instead of Cloudflare geolocation. This does not erase an existing profile location. The backend selects profile location from the latest timestamped event with a non-empty location in the batch, falling back to the existing profile location when none is available. Request location affects evaluation and profile updates; it is not a permanent location lock. The ip option controls IP enrichment through X-Force-IP and does not control profile geolocation.

    upsertManyProfiles does not send request-level location, including a constructor default. For batch updates, supply location through each event's context.location.

    For how these inputs affect profile continuity across later server and browser requests, see Location inputs and profile updates.

    Insights API methods are scoped to client.insights and send analytics event batches:

    await client.insights.sendBatchEvents([
    {
    profile,
    events: [viewEvent],
    },
    ])

    Insights endpoints do not return response data. For last-chance browser lifecycle delivery, pass a per-call beacon sender that receives the request URL and already serialized body.

    Schema entry point

    @contentful/optimization-api-client/api-schemas owns the Experience API and Insights API runtime validation schemas, inferred types, and validation helpers used by this client. Import those contracts from that entry point when building SDK layers, tooling, or tests:

    import { ExperienceResponse } from '@contentful/optimization-api-client/api-schemas'
    

    This entry point does not include Contentful CDA schemas. Import CDA schemas from @contentful/optimization-core/api-schemas instead. That Core entry point also provides an aggregate schema surface for SDK layers that need both CDA and API contracts.

    ExO interaction events use the Experience and ExperienceFragment entity kinds. They accept parentVariantId for the root Experience's selected variant, including default for its baseline. This is separate from the rendered entity's own variantId. SDK event builders supply these values; the schemas preserve them during request serialization and accept older events that omit them.

    This package also exports fetch helper functions used by SDK layers:

    Helper Purpose
    createProtectedFetchMethod Adds timeout and retry protection around a fetch method
    createRetryFetchMethod Applies retry policy to retryable responses
    createTimeoutFetchMethod Aborts requests after the configured timeout

    Use generated reference docs for helper signatures and callback payloads.