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

# Send events via Upstack Conversion API

> **Upstack Conversion API (CAPI)** — send a batch of tracking events from your server.
Events enter the **same collect queue and consumer** as browser pixel events (identity
resolution, enrichment, analytics, and destination forwarding). Session handling and
edge enrichment still differ from the Cloudflare pixel path.

**Match quality.** Send the end user's `ipAddress` yourself — the API never invents it
from the gateway connection. Prefer sending `userAgent` and `locale` in the body; if
omitted or blank, the API fills them from the `User-Agent` and `Accept-Language`
request headers when present. Extra JSON keys are accepted and passed through where
they map onto the TrackingEvent envelope (e.g. nested under `userProperties` or `click`).

You always send an **array** of events (send one event as an array of one). Each
event needs a `name`. An `eventId` is optional but **strongly recommended** — it makes
the event idempotent (safe retries and de-duplication); everything else is optional.

**Deduplication.** `eventId` is your idempotency key. If the same `eventId` is
received again for a pixel within the dedup window, the duplicate is skipped during
processing — so retries and webhook loops are safe. Use the same `eventId` you send
from your browser Pixel for the same event so they de-duplicate across sources
(e.g. Facebook).

**Limits.** Up to **100 events** per request; request body up to **128 KB**.
Curated string fields (emails, URLs, click ids, userAgent, …) have **no per-field
character max** — the request-body size cap is the backstop. `eventProperties`
follows the TrackingEvent `data` contract (`TrackingEventData`); known fields are
typed when present, and additional keys are allowed. `page.qsp` remains an open
object. Trait/address arrays are capped at **100** items.

**Required scope:** `events:write`.

**Field naming (CAPI body → TrackingEvent envelope).**
`userProperties` → `context.identity.traits`; `eventProperties` → `data`;
`eventId` → `id`; `identityId` → `context.identity.identityId`;
top-level `ipAddress` / `userAgent` / `sessionId` / `locale` / `timezone` / `page` /
`campaign` / `click` / `viewport` → `context.properties.*`.

**Dual-fire with the browser Pixel.** Use the same `eventId` (and preferably the same
`identityId` / `_adtik`) for the browser and server copies of one conversion so
downstream dedup and destination match quality treat them as one event.




## OpenAPI

````yaml /api-reference/openapi.yaml post /tr/api/events
openapi: 3.1.0
info:
  title: Upstack Data API
  version: '1.0'
  description: >
    Programmatic access to your Upstack Data pixel — analytics queries, the

    measures/dimensions catalog, and dashboard view management.


    All requests authenticate with two headers:


    - `x-api-key`: your Upstack API key (mint one at **Settings → API Keys** in
    the dashboard).

    - `x-pixel-id`: the pixel id the request targets. One key is scoped to one
    pixel.
servers:
  - url: https://api.upstackdata.com
    description: Production
security:
  - apiKey: []
    pixelId: []
tags:
  - name: Analytics
    description: Query events, attribution, and cohort analyses.
  - name: Catalog
    description: List the measures available to your pixel.
  - name: Dashboards
    description: >-
      Manage dashboard views — create, update, copy, delete, and the high-level
      preset builder.
  - name: Account
    description: >-
      Read and update the account that owns this API key — display name, active
      owners and admins, and subscription summary.
  - name: Costs
    description: >-
      Read and update every cost surface — global product overrides, shipping
      method, per-variant handling fees and COGS history, and per-type cost
      lines (order / gateway / shipping profile / variable / fixed). Mutations
      trigger the same per-order COGS recalculation as web-UI changes.
  - name: Products
    description: Browse products + variants in the configured catalog.
  - name: Events
    description: >-
      Upstack Conversion API (CAPI) — send server-side tracking events from your
      backend.
paths:
  /tr/api/events:
    post:
      tags:
        - Events
      summary: Send events via Upstack Conversion API
      description: >
        **Upstack Conversion API (CAPI)** — send a batch of tracking events from
        your server.

        Events enter the **same collect queue and consumer** as browser pixel
        events (identity

        resolution, enrichment, analytics, and destination forwarding). Session
        handling and

        edge enrichment still differ from the Cloudflare pixel path.


        **Match quality.** Send the end user's `ipAddress` yourself — the API
        never invents it

        from the gateway connection. Prefer sending `userAgent` and `locale` in
        the body; if

        omitted or blank, the API fills them from the `User-Agent` and
        `Accept-Language`

        request headers when present. Extra JSON keys are accepted and passed
        through where

        they map onto the TrackingEvent envelope (e.g. nested under
        `userProperties` or `click`).


        You always send an **array** of events (send one event as an array of
        one). Each

        event needs a `name`. An `eventId` is optional but **strongly
        recommended** — it makes

        the event idempotent (safe retries and de-duplication); everything else
        is optional.


        **Deduplication.** `eventId` is your idempotency key. If the same
        `eventId` is

        received again for a pixel within the dedup window, the duplicate is
        skipped during

        processing — so retries and webhook loops are safe. Use the same
        `eventId` you send

        from your browser Pixel for the same event so they de-duplicate across
        sources

        (e.g. Facebook).


        **Limits.** Up to **100 events** per request; request body up to **128
        KB**.

        Curated string fields (emails, URLs, click ids, userAgent, …) have **no
        per-field

        character max** — the request-body size cap is the backstop.
        `eventProperties`

        follows the TrackingEvent `data` contract (`TrackingEventData`); known
        fields are

        typed when present, and additional keys are allowed. `page.qsp` remains
        an open

        object. Trait/address arrays are capped at **100** items.


        **Required scope:** `events:write`.


        **Field naming (CAPI body → TrackingEvent envelope).**

        `userProperties` → `context.identity.traits`; `eventProperties` →
        `data`;

        `eventId` → `id`; `identityId` → `context.identity.identityId`;

        top-level `ipAddress` / `userAgent` / `sessionId` / `locale` /
        `timezone` / `page` /

        `campaign` / `click` / `viewport` → `context.properties.*`.


        **Dual-fire with the browser Pixel.** Use the same `eventId` (and
        preferably the same

        `identityId` / `_adtik`) for the browser and server copies of one
        conversion so

        downstream dedup and destination match quality treat them as one event.
      operationId: createEvents
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - events
              additionalProperties: true
              properties:
                events:
                  type: array
                  minItems: 1
                  maxItems: 100
                  description: The events to ingest. At least 1, at most 100 per request.
                  items:
                    type: object
                    required:
                      - name
                    additionalProperties: true
                    description: >
                      Extra keys are accepted. Documented fields are the common
                      contract;

                      nested optional objects are mapped through to the
                      TrackingEvent envelope.
                    properties:
                      name:
                        type: string
                        pattern: ^[a-zA-Z][a-zA-Z0-9_]*$
                        maxLength: 100
                        description: >
                          The event name. Use a standard event such as
                          `purchase` or `add_to_cart`,

                          or your own custom name. Must start with a letter and
                          contain only letters,

                          numbers, and underscores. Max 100 characters.
                        example: purchase
                      eventId:
                        type: string
                        minLength: 1
                        maxLength: 100
                        description: >
                          Optional but **strongly recommended**. A unique,
                          stable id you assign to this

                          event — your idempotency key. We recommend a **ULID**
                          (a unique, time-sortable id).

                          Sending the same `eventId` again de-duplicates the
                          event during processing, so

                          retries and webhook loops are safe. Use the same value
                          your browser Pixel sends

                          for an event so they de-duplicate across sources (e.g.
                          Facebook). Omit it and the

                          event is accepted but cannot be de-duplicated. When
                          provided: 1–100 characters.
                        example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
                      identityId:
                        type: string
                        minLength: 1
                        maxLength: 100
                        description: >
                          Browser/pixel identity id (`_adtik`) so server events
                          stitch to the same

                          identity as the client pixel. When provided: 1–100
                          characters.
                        example: 01HXYZ_BROWSER_ADTIK
                      userProperties:
                        type: object
                        additionalProperties: true
                        description: >
                          Who the end user is — identity traits used for
                          matching and enrichment.

                          Describes your customer, NOT your server. All fields
                          optional.

                          Extra keys are accepted and passed through on traits.
                        properties:
                          emails:
                            type: array
                            maxItems: 100
                            items:
                              type: string
                            description: The user's email address(es).
                          phones:
                            type: array
                            maxItems: 100
                            items:
                              type: string
                            description: The user's phone number(s).
                          userIds:
                            type: array
                            maxItems: 100
                            items:
                              type: string
                            description: Your own id(s) for this user (e.g. customer id).
                          genders:
                            type: array
                            maxItems: 100
                            items:
                              type: string
                            description: The user's gender(s).
                          dobs:
                            type: array
                            maxItems: 100
                            items:
                              type: string
                            description: The user's date(s) of birth.
                          addresses:
                            type: array
                            maxItems: 100
                            description: The user's postal address(es).
                            items:
                              type: object
                              additionalProperties: true
                              properties:
                                email:
                                  type: string
                                  description: Contact email for this address.
                                phone:
                                  type: string
                                  description: Contact phone for this address.
                                firstName:
                                  type: string
                                  description: First name.
                                lastName:
                                  type: string
                                  description: Last name.
                                company:
                                  type: string
                                  description: Company name.
                                address1:
                                  type: string
                                  description: Street address line 1.
                                address2:
                                  type: string
                                  description: >-
                                    Street address line 2 (apartment, suite,
                                    unit).
                                city:
                                  type: string
                                  description: City.
                                province:
                                  type: string
                                  description: >-
                                    State or province, full name (e.g.
                                    California).
                                provinceCode:
                                  type: string
                                  description: State or province code (e.g. CA).
                                country:
                                  type: string
                                  description: Country, full name (e.g. United States).
                                countryCode:
                                  type: string
                                  description: Two-letter country code (e.g. US).
                                zip:
                                  type: string
                                  description: Postal / ZIP code.
                          shopifyYIds:
                            type: array
                            maxItems: 100
                            items:
                              type: string
                            description: >-
                              Shopify `_shopify_y` cookie value(s) when
                              available.
                      eventProperties:
                        $ref: '#/components/schemas/TrackingEventData'
                      ipAddress:
                        type: string
                        description: >
                          The END USER's IP address (not your server's).
                          Required for strong match

                          quality — send it yourself; the Conversion API does
                          not invent it from

                          the API gateway connection.
                      userAgent:
                        type: string
                        description: >
                          The end user's browser user-agent. Prefer sending it
                          in the body.

                          If omitted or blank, filled from the request
                          `User-Agent` header when present.
                      sessionId:
                        type: string
                        description: Session id (e.g. browser `_adts`) when available.
                      locale:
                        type: string
                        description: >
                          The user's locale, e.g. en-US. Prefer sending it in
                          the body.

                          If omitted or blank, filled from the first
                          `Accept-Language` tag when present.
                      timezone:
                        type: string
                        description: The user's timezone, e.g. America/New_York.
                      page:
                        type: object
                        additionalProperties: true
                        description: Where the event happened — page context.
                        properties:
                          host:
                            type: string
                            description: Page host
                            e.g. shop.com.: null
                          path:
                            type: string
                            description: Page path
                            e.g. /checkout.: null
                          referrer:
                            type: string
                            description: The referring URL.
                          search:
                            type: string
                            description: The query string.
                          title:
                            type: string
                            description: The page title.
                          url:
                            type: string
                            description: The full page URL.
                          qsp:
                            type: object
                            additionalProperties: true
                            description: >-
                              Parsed query-string parameters (open object; body
                              size is the backstop).
                      campaign:
                        type: object
                        additionalProperties: true
                        description: Marketing / UTM attribution for this event.
                        properties:
                          name:
                            type: string
                            description: Campaign name.
                          campaign:
                            type: string
                            description: utm_campaign.
                          source:
                            type: string
                            description: utm_source.
                          medium:
                            type: string
                            description: utm_medium.
                          term:
                            type: string
                            description: utm_term.
                          content:
                            type: string
                            description: utm_content.
                      click:
                        type: object
                        additionalProperties: true
                        description: >
                          Destination-critical ad-click identifiers for
                          attribution and matching.

                          Documented value IDs are the common contract; extra
                          click keys are

                          accepted and passed through.
                        properties:
                          fbc:
                            type: string
                            description: Facebook click id (fbc).
                          fbp:
                            type: string
                            description: Facebook browser id (fbp).
                          fbclid:
                            type: string
                            description: Facebook click id from URL (fbclid).
                          gclid:
                            type: string
                            description: Google click id.
                          gbraid:
                            type: string
                            description: Google Ads gbraid (iOS / app).
                          wbraid:
                            type: string
                            description: Google Ads wbraid (web-to-app).
                          ttclid:
                            type: string
                            description: TikTok click id.
                          ttp:
                            type: string
                            description: TikTok browser cookie (ttp).
                          snapchatSCCid:
                            type: string
                            description: Snapchat click id (ScCid).
                          snapchatSCCookie:
                            type: string
                            description: Snapchat cookie (_scid).
                          pinterestEpik:
                            type: string
                            description: Pinterest epik.
                          liFatId:
                            type: string
                            description: LinkedIn first-party ad tracking id (li_fat_id).
                          msclkid:
                            type: string
                            description: Microsoft Advertising click id.
                          kx:
                            type: string
                            description: Klaviyo exchange id (kx).
                          klaviyoCid:
                            type: string
                            description: Klaviyo company/profile click id.
                          sendlaneCid:
                            type: string
                            description: Sendlane click / contact id.
                          omnisendCid:
                            type: string
                            description: Omnisend click / contact id.
                          redditCid:
                            type: string
                            description: Reddit click id.
                          redditUuid:
                            type: string
                            description: Reddit UUID.
                          applovinAxwrt:
                            type: string
                            description: AppLovin Axon write key / axwrt.
                          aleid:
                            type: string
                            description: AppLovin event / click id (aleid).
                          tblci:
                            type: string
                            description: Taboola click id.
                          obclid:
                            type: string
                            description: Outbrain click id.
                          nbclid:
                            type: string
                            description: NewsBreak click id.
                      viewport:
                        type: object
                        additionalProperties: true
                        description: >
                          Browser viewport / layout metrics at event time. All
                          fields optional;

                          whatever is sent is mapped through to
                          `context.properties.viewport`

                          (including partial objects).
                        properties:
                          viewportWidth:
                            type: number
                            description: Viewport width in CSS pixels.
                          viewportHeight:
                            type: number
                            description: Viewport height in CSS pixels.
                          pageHeight:
                            type: number
                            description: Full page height in CSS pixels.
                          devicePixelRatio:
                            type: number
                            description: devicePixelRatio.
            examples:
              purchase:
                summary: >-
                  Purchase with identityId, click ids, viewport, and event
                  properties
                value:
                  events:
                    - name: purchase
                      eventId: 01ARZ3NDEKTSV4RRFFQ69G5FAV
                      identityId: 01HXYZ_BROWSER_ADTIK
                      userProperties:
                        emails:
                          - jane@example.com
                        userIds:
                          - cust_889
                        shopifyYIds:
                          - y-abc
                      ipAddress: 203.0.113.5
                      page:
                        url: https://shop.com/checkout
                      click:
                        fbc: fb.1.abc
                        gclid: xyz
                        fbclid: IwAR…
                      viewport:
                        viewportWidth: 1440
                        viewportHeight: 900
                        pageHeight: 3200
                        devicePixelRatio: 2
                      eventProperties:
                        orderId: '10421'
                        value: 99.9
                        currency: USD
                        items:
                          - id: SKU1
                            name: Tee
                            price: 49.95
                            quantity: 2
              multiple:
                summary: Multiple events (SaaS + custom)
                value:
                  events:
                    - name: subscription_started
                      eventId: 01ARZ3NDEKTSV4RRFFQ69G5FAW
                      userProperties:
                        emails:
                          - jane@example.com
                      eventProperties:
                        planName: Pro
                        mrr: 99
                    - name: newsletter_signup
                      eventId: 01ARZ3NDEKTSV4RRFFQ69G5FAX
                      userProperties:
                        emails:
                          - jane@example.com
      responses:
        '200':
          description: >-
            Events accepted for processing. `eventsIngested` is the number
            queued.
          content:
            application/json:
              schema:
                type: object
                required:
                  - requestId
                  - eventsIngested
                properties:
                  requestId:
                    type: string
                    description: Unique id for this request (also the x-request-id header).
                  eventsIngested:
                    type: integer
                    description: Number of events accepted and queued for processing.
              example:
                requestId: 18d90656-34fd-4b87-b1e2-9607943d97a9
                eventsIngested: 3
        '400':
          $ref: '#/components/responses/EventsValidationError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/EventsForbidden'
        '413':
          $ref: '#/components/responses/EventsPayloadTooLarge'
        '500':
          $ref: '#/components/responses/EventsServerError'
components:
  schemas:
    TrackingEventData:
      type: object
      additionalProperties: true
      description: >
        Event payload mapped to `TrackingEvent.data` (`TrackingEventData` =

        ecommerce + SaaS properties). **No fields are required.** Known keys are
        typed

        when present; custom keys are allowed (same index signature as the
        TypeScript type).

        Same contract as the pixel / SDK event `data` object.
      properties:
        isSyntheticWebhookEvent:
          type: boolean
        firstName:
          type: string
        lastName:
          type: string
        email:
          type: string
        phone:
          type: string
        addresses:
          type: array
          items:
            $ref: '#/components/schemas/TrackingEventDataAddress'
        cartId:
          type: string
        transactionId:
          type: string
        orderId:
          type: string
        orderName:
          type: string
        affiliation:
          type: string
        currency:
          type: string
          description: ISO 4217 currency code, e.g. USD.
        price:
          type: number
        subtotalPrice:
          type: number
        value:
          type: number
          description: Order / conversion value.
        tax:
          type: number
        shipping:
          type: number
        discount:
          type: number
        coupon:
          type: string
        paymentType:
          type: string
        shippingTier:
          type: string
        creativeName:
          type: string
        creativeSlot:
          type: string
        locationId:
          type: string
        promotionId:
          type: string
        promotionName:
          type: string
        items:
          type: array
          items:
            $ref: '#/components/schemas/TrackingEventDataItem'
        orderSourceName:
          type: string
        tags:
          type: array
          items:
            type: string
        totalUnitCost:
          type: number
        totalUnitMargin:
          type: number
        accountId:
          type: string
        accountName:
          type: string
        accountCreatedAt:
          type: string
          description: ISO 8601 timestamp.
        userId:
          type: string
        userEmail:
          type: string
        userRole:
          type: string
        subscriptionId:
          type: string
        planId:
          type: string
        planName:
          type: string
        billingInterval:
          type: string
          enum:
            - day
            - week
            - month
            - year
        mrr:
          type: number
        arr:
          type: number
        mrrDelta:
          type: number
        ltv:
          type: number
        trialStartDate:
          type: string
        trialEndDate:
          type: string
        trialDaysRemaining:
          type: number
        usageInfo:
          type: object
          additionalProperties: true
          properties:
            currentUsage:
              type: number
            limit:
              type: number
            usagePercentage:
              type: number
        invoiceId:
          type: string
        amount:
          type: number
        failureReason:
          type: string
        seatCount:
          type: number
        seatDelta:
          type: number
        addonId:
          type: string
        addonName:
          type: string
        featureId:
          type: string
        featureName:
          type: string
        milestoneId:
          type: string
        milestoneName:
          type: string
        inactiveDays:
          type: number
        cancelReason:
          type: string
        cancelFeedback:
          type: string
        cancelledAt:
          type: string
    TrackingEventDataAddress:
      type: object
      additionalProperties: true
      description: >-
        Address on event data (`AddressInfo`). All fields optional; extra keys
        allowed.
      properties:
        email:
          type: string
        phone:
          type: string
        firstName:
          type: string
        lastName:
          type: string
        company:
          type: string
        address1:
          type: string
        address2:
          type: string
        city:
          type: string
        province:
          type: string
        provinceCode:
          type: string
        country:
          type: string
        countryCode:
          type: string
        zip:
          type: string
        s:
          type: string
        cra:
          type: number
        upa:
          type: number
    TrackingEventDataItem:
      type: object
      additionalProperties: true
      description: >
        Line item / content object (`GenericContent`). All fields optional;
        extra keys allowed.
      properties:
        content_type:
          type: string
        id:
          type: string
        name:
          type: string
        sku:
          type: string
        brand:
          type: string
        variant:
          type: string
        coupon:
          type: string
        currency:
          type: string
        discount:
          type: number
        index:
          type: number
        value:
          type: number
        price:
          type: number
        quantity:
          type: number
        url:
          type: string
        locationId:
          type: string
        imageUrl:
          type: string
        category:
          type: string
        category2:
          type: string
        category3:
          type: string
        category4:
          type: string
        category5:
          type: string
        unitCost:
          type: number
        unitMargin:
          type: number
    EventsError:
      type: object
      required:
        - requestId
        - message
        - error
      description: >
        Error envelope for the server-side events API. Every error carries a
        `requestId`

        and a top-level `message`; application errors also include a structured
        `error` object.
      properties:
        requestId:
          type: string
          description: >-
            Unique id for this request (also returned as the `x-request-id`
            response header). Quote it in any support ticket.
        message:
          type: string
          description: Human-readable summary of the error (mirrors `error.message`).
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - VALIDATION_ERROR
                - UNAUTHORIZED
                - FORBIDDEN
                - PAYLOAD_TOO_LARGE
                - INTERNAL_ERROR
              description: Stable, machine-readable error code you can branch on.
            message:
              type: string
              description: Human-readable summary of what went wrong.
            details:
              type: array
              description: >-
                Present on validation errors — one entry per offending
                event/field.
              items:
                type: object
                required:
                  - message
                properties:
                  index:
                    type: integer
                    description: >-
                      Zero-based position of the offending event in the `events`
                      array.
                  field:
                    type: string
                    description: >-
                      The field that failed, e.g. `name`, `eventId`, or
                      `eventProperties.value`.
                  message:
                    type: string
                    description: What is wrong with the field.
    Error:
      type: object
      required:
        - message
      properties:
        message:
          type: string
          description: Human-readable error message.
        errors:
          type: array
          description: Per-field validation errors (present on 400 responses).
          items:
            type: object
            properties:
              message:
                type: string
              key:
                type: string
              path:
                type: array
                items:
                  type: string
  responses:
    EventsValidationError:
      description: >-
        One or more events failed validation. `error.code` is
        `VALIDATION_ERROR`; `error.details` lists every offending event by
        `index` and `field`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EventsError'
    Unauthorized:
      description: >-
        Missing or invalid `x-api-key` / `x-pixel-id`, or key is
        revoked/expired.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    EventsForbidden:
      description: >-
        The API key is valid but does not carry the `events:write` scope.
        `error.code` is `FORBIDDEN`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EventsError'
    EventsPayloadTooLarge:
      description: >-
        The request body exceeds the 128 KB limit. `error.code` is
        `PAYLOAD_TOO_LARGE`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EventsError'
    EventsServerError:
      description: >-
        The events could not be accepted (transient). Safe to retry with the
        same payload. `error.code` is `INTERNAL_ERROR`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EventsError'
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Your Upstack API key. Starts with `upstack_`.
    pixelId:
      type: apiKey
      in: header
      name: x-pixel-id
      description: The pixel id the request targets.

````