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

# Get or create version by facts

> Answers the live version of the product whose facts are the ones you send, and creates it when no version holds them. Send the agent state you are about to test, and callers that run at the same time on that state all receive one version instead of each creating its own. The key order you send does not change the match. The answer is 200 whether the version already existed or was created now, because the caller asks for the version for a state and not for a new row.



## OpenAPI

````yaml https://api.galtea.ai/openapi.json post /versions/get-or-create
openapi: 3.0.0
info:
  version: 1.0.0
  title: Product Management Service API
  description: API documentation for Product Management Service
  contact:
    name: Galtea AI
servers:
  - url: https://api.galtea.ai
security:
  - bearerAuth: []
tags: []
externalDocs:
  description: Galtea Platform Documentation
  url: https://docs.galtea.ai
paths:
  /versions/get-or-create:
    post:
      tags:
        - versions
      summary: Get or create version by facts
      description: >-
        Answers the live version of the product whose facts are the ones you
        send, and creates it when no version holds them. Send the agent state
        you are about to test, and callers that run at the same time on that
        state all receive one version instead of each creating its own. The key
        order you send does not change the match. The answer is 200 whether the
        version already existed or was created now, because the caller asks for
        the version for a state and not for a new row.
      operationId: getOrCreateVersion
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GetOrCreateVersionBody'
      responses:
        '200':
          description: Version resolved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Version'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Too many requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearerAuth: []
components:
  schemas:
    GetOrCreateVersionBody:
      type: object
      properties:
        productId:
          type: string
          minLength: 1
          example: prod_123
          description: Product the version belongs to.
        facts:
          type: object
          additionalProperties:
            type: string
          description: >-
            The agent state this version represents, as a flat map of text to
            text. Every key and every value is trimmed, an entry whose key or
            value is then empty is dropped, and the rest is kept exactly, so
            "0.7" and "0.70" are two different facts. At most 32 keys, and at
            most 2000 bytes once the map is encoded as JSON, which counts its
            punctuation too. No key and no value may hold the NUL character or
            half of a surrogate pair. Two keys that become equal after the
            spaces around them are removed are refused, unless both become
            empty, which drops them instead because a blank key names no fact; a
            key repeated with the exact same spelling never reaches that rule,
            because JSON parsing keeps only its last value. Two live versions of
            one product may not hold the same facts; the key order you send does
            not change that comparison. A map that leaves no entry is stored as
            null. At least one key and value must survive the trimming, or the
            call is refused.
          example:
            model: gpt-4o
            temperature: '0.7'
            promptVersion: '12'
        name:
          type: string
          example: nightly build
          description: >-
            Name for the version, used only when this call creates one. A
            version the call finds keeps the name it already has. A name another
            version of the product holds is refused.
      required:
        - productId
        - facts
      additionalProperties: false
    Version:
      type: object
      properties:
        id:
          type: string
          example: ver_123
        productId:
          type: string
          example: prod_123
        userId:
          type: string
          nullable: true
          example: user_123
        number:
          type: integer
          readOnly: true
          minimum: 1
          example: 7
          description: >-
            The version's sequence number inside its product. It starts at 1, is
            assigned when the version is created, never changes, and is never
            reused after a version is deleted. The canonical label is "v"
            followed by this number.
        name:
          type: string
          example: support release
          description: >-
            Optional human label. Omit it and the version is stored under its
            canonical label. A name of "v" followed by digits is rejected,
            because it reads as the number of another version. The one exception
            is the number this version is given, which produces the same result
            as omitting the name. "v1.0" is accepted.
        description:
          type: string
          nullable: true
          example: Version description
        modelId:
          type: string
          nullable: true
          example: model_123
        systemPrompt:
          type: string
          nullable: true
          example: You are a helpful assistant
        datasetUri:
          type: string
          nullable: true
          example: https://example.com/dataset.csv
        datasetDescription:
          type: string
          nullable: true
          example: Training dataset
        guardrails:
          type: string
          nullable: true
          example: Safety guidelines
        facts:
          type: object
          nullable: true
          additionalProperties:
            type: string
          description: >-
            The agent state this version represents, as a flat map of text to
            text. Every key and every value is trimmed, an entry whose key or
            value is then empty is dropped, and the rest is kept exactly, so
            "0.7" and "0.70" are two different facts. At most 32 keys, and at
            most 2000 bytes once the map is encoded as JSON, which counts its
            punctuation too. No key and no value may hold the NUL character or
            half of a surrogate pair. Two keys that become equal after the
            spaces around them are removed are refused, unless both become
            empty, which drops them instead because a blank key names no fact; a
            key repeated with the exact same spelling never reaches that rule,
            because JSON parsing keeps only its last value. Two live versions of
            one product may not hold the same facts; the key order you send does
            not change that comparison. A map that leaves no entry is stored as
            null.
          example:
            model: gpt-4o
            temperature: '0.7'
            promptVersion: '12'
        otelInputSourceRule:
          type: object
          nullable: true
          description: >-
            Recover a turn's user-visible input for products whose user message
            lives on a non-LLM span. Set per product or version (version wins).
            Per span it applies only when no LLM input is present. Per turn the
            value it extracts IS the turn input, ahead of every fallback, and
            the turn input is EMPTY when the rule extracts nothing from any span
            of the turn. The two directions resolve independently.
          properties:
            spanName:
              type: string
              description: Exact OTLP span name to match.
              example: ExecuteActivity:add_user_message
            attribute:
              type: string
              description: >-
                Span attribute key holding the JSON blob (string or object) to
                read.
              example: app.arguments
            path:
              type: string
              description: >-
                JSONPath into the parsed attribute value, resolving to the input
                text. Must start with the $ root.
              example: $[0].message.content
            predicate:
              type: object
              nullable: true
              description: >-
                Optional gate: apply the rule only when the node at
                predicate.path equals predicate.equals.
              properties:
                path:
                  type: string
                  example: $[0].message.role
                equals:
                  type: string
                  example: user
              required:
                - path
                - equals
          required:
            - spanName
            - attribute
            - path
          example:
            spanName: ExecuteActivity:add_user_message
            attribute: app.arguments
            path: $[0].message.content
            predicate:
              path: $[0].message.role
              equals: user
        otelOutputSourceRule:
          type: object
          nullable: true
          description: >-
            Recover a turn's user-visible output for templated or non-LLM
            replies whose final answer lives on a non-LLM span. Set per product
            or version (version wins). Per span it applies only when no LLM
            output is present. Per turn the value it extracts IS the turn
            output, ahead of every fallback, and the turn output is EMPTY when
            the rule extracts nothing from any span of the turn. The two
            directions resolve independently.
          properties:
            spanName:
              type: string
              description: Exact OTLP span name to match.
              example: ExecuteActivity:save_reply
            attribute:
              type: string
              description: >-
                Span attribute key holding the JSON blob (string or object) to
                read.
              example: app.arguments
            path:
              type: string
              description: >-
                JSONPath into the parsed attribute value, resolving to the
                output text. Must start with the $ root.
              example: $[0].message.content
            predicate:
              type: object
              nullable: true
              description: >-
                Optional gate: apply the rule only when the node at
                predicate.path equals predicate.equals.
              properties:
                path:
                  type: string
                  example: $[0].message.role
                equals:
                  type: string
                  example: assistant
              required:
                - path
                - equals
          required:
            - spanName
            - attribute
            - path
          example:
            spanName: ExecuteActivity:save_reply
            attribute: app.arguments
            path: $[0].message.content
            predicate:
              path: $[0].message.role
              equals: assistant
        initializationEndpointConnectionId:
          type: string
          nullable: true
          example: ec_123
        conversationEndpointConnectionId:
          type: string
          nullable: true
          example: ec_123
        finalizationEndpointConnectionId:
          type: string
          nullable: true
          example: ec_123
        phoneConnectionId:
          type: string
          nullable: true
          description: >-
            The version's phone connection (telephony conversation target). At
            most one conversation target may be set across
            conversationEndpointConnectionId, phoneConnectionId, and
            webRtcConnectionId.
          example: phoneConnection_123
        webRtcConnectionId:
          type: string
          nullable: true
          description: >-
            The version's WebRTC connection (live two-way audio conversation
            target). At most one conversation target may be set across
            conversationEndpointConnectionId, phoneConnectionId, and
            webRtcConnectionId.
          example: webRtcConnection_123
        parentVersionId:
          type: string
          nullable: true
          example: ver_122
          description: >-
            Id of the version this one was revised from (its direct parent in
            the revision lineage). On create, providing this value records the
            parent edge; the parent must belong to the same product. Omit or
            null to create a root version with no parent. On responses, this is
            the recorded parent edge (null for roots).
        createdAt:
          type: string
          format: date-time
        deletedAt:
          type: string
          format: date-time
          nullable: true
    Error:
      type: object
      properties:
        error:
          type: string
          example: Error type
        message:
          type: string
          example: Error message description
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key authorization. Pass your API key in the Authorization header as
        a Bearer token. Both new (`gsk_*`) and legacy (`gsk-`) API keys are
        accepted, e.g. `Authorization: Bearer gsk_...` or `Authorization: Bearer
        gsk-...`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.