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

# Record a conversion

> Credit a sale to the video that caused it. Send `session_code` from the player so the conversion joins the play that produced it. Without it, the sale is recorded but cannot be attributed to a viewer.

Requires a token with the `conversions:write` scope.

Server: `https://app.trackplay.io/api/v1`



## OpenAPI

````yaml /api-reference/openapi.json post /conversions
openapi: 3.1.0
info:
  title: TrackPlay API
  description: >-
    Send conversions and events to TrackPlay, and read them back. Authenticated
    with scoped tokens you mint in the dashboard.
  version: 1.0.0
servers:
  - url: https://app.trackplay.io/api/v1
    description: App API. Conversions, videos, webhooks.
  - url: https://e.trackplay.io
    description: Events API. High-volume event ingest.
security:
  - bearerAuth: []
paths:
  /conversions:
    post:
      tags:
        - Conversions
      summary: Record a conversion
      description: >-
        Credit a sale to the video that caused it. Send `session_code` from the
        player so the conversion joins the play that produced it. Without it,
        the sale is recorded but cannot be attributed to a viewer.


        Requires a token with the `conversions:write` scope.


        Server: `https://app.trackplay.io/api/v1`
      operationId: createConversion
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
          description: >-
            Retry-safe key. The first response for a given key is cached for 24
            hours and replayed on a repeat, with `Idempotency-Replayed: true`
            set. Send one on every call. A retried payment webhook without it
            will double count the sale.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConversionRequest'
            examples:
              sale:
                summary: A sale attributed to a viewer's session
                value:
                  video_code: 9f2c1a7e-4d3b-4a11-9e77-0b2c5d8e1f34
                  session_code: 3b1e5c90-77aa-4f2d-8c31-6de0a9b41c22
                  conversion_id: order_10482
                  conversion_value: 297
                  conversion_currency: USD
                  conversion_product_name: Pro Annual
                  conversion_customer_email: buyer@example.com
      responses:
        '201':
          description: Conversion recorded.
          content:
            application/json:
              schema:
                type: object
                properties:
                  recorded:
                    type: boolean
                    examples:
                      - true
                  conversion_id:
                    type: string
                    examples:
                      - order_10482
                  video_code:
                    type: string
                  attributed_to_split_test:
                    type: boolean
                    description: True when the conversion was credited to a split-test arm.
        '401':
          description: Missing, invalid, or revoked token.
        '403':
          description: Token does not carry the `conversions:write` scope.
        '404':
          description: No video with that `video_code` exists in this workspace.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    examples:
                      - Video not found in this workspace.
                  video_code:
                    type: string
        '422':
          description: Validation failed.
        '429':
          description: Rate limited. The write limit is 60 requests per minute per token.
        '503':
          description: >-
            The conversion could not be written. Retry with the same
            `Idempotency-Key`.
components:
  schemas:
    ConversionRequest:
      type: object
      required:
        - video_code
      properties:
        video_code:
          type: string
          maxLength: 64
          description: >-
            The video the sale is credited to. Required. A conversion with no
            video cannot be attributed to anything.
        session_code:
          type: string
          maxLength: 128
          description: >-
            The viewer's session. Optional, but without it the sale cannot be
            joined to the play that caused it, and your play-to-sale rate stays
            blind to it.
        event:
          type: string
          maxLength: 64
          default: conversion
          description: What happened. Defaults to `conversion`.
        conversion_id:
          type: string
          maxLength: 128
          description: Your order ID. Defaults to a generated UUID if omitted.
        conversion_value:
          type: number
          minimum: 0
          description: Sale amount.
        conversion_currency:
          type: string
          minLength: 3
          maxLength: 3
          description: Three-letter currency code, e.g. `USD`.
        conversion_product_code:
          type: string
          maxLength: 128
        conversion_product_name:
          type: string
          maxLength: 255
        conversion_customer_email:
          type: string
          format: email
          maxLength: 255
        conversion_customer_name:
          type: string
          maxLength: 255
        conversion_customer_phone:
          type: string
          maxLength: 64
        conversion_data:
          type: object
          additionalProperties: true
          description: Any extra fields you want to keep with the sale.
        is_test:
          type: boolean
          description: Marks the row as a test so it can be excluded from reporting.
        split_test_id:
          type: string
          maxLength: 64
          description: >-
            Send with `split_test_variation_id` or not at all. One without the
            other cannot identify an arm, and a half-attributed row looks valid
            while being wrong.
        split_test_variation_id:
          type: string
          maxLength: 64
          description: Send with `split_test_id` or not at all.
        occurred_at:
          type: string
          format: date-time
          description: When the sale happened. Defaults to now.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        A scoped token minted in **Settings → API tokens**. Send it as
        `Authorization: Bearer tplt_…` or `X-API-Key: tplt_…`.

````