# Versions_CreateVersion

`POST /v1/accounts/{account}/datasets/{dataset}/versions`

Tags what the dataset yields now. ALREADY_EXISTS when the name is taken;
FAILED_PRECONDITION when the dataset holds no episode at all, or while a
trim of an episode it holds is still being applied, naming them; ABORTED when `version.digest` is set and head has moved. A
head with every episode rejected is tagged: its version has
`episode_count` 0, records why in its note, and training and export
refuse it (FAILED_PRECONDITION).
Reuses the dataset version whose episode-set digest equals head's, else
pins one from head's exact member revisions (version_kind 'tag'). A merged
dataset is tagged only when every upload it holds freezes the same training
contract (see MergeDatasets): else FAILED_PRECONDITION naming two uploads
and what differs. An upload merged into one is tagged no more
(FAILED_PRECONDITION naming the merged dataset); its tags keep
resolving. Emits VERSION_CREATED.

- Base URL: `https://junction-api.qualiastudios.dev`
- Authentication: an API key in the `X-API-Key` header

## Parameters

- `account` (path, string, required): The account id.
- `dataset` (path, string, required): The dataset id.
- `versionId` (query, string): The tag name: 1-64 characters of [0-9A-Za-z._-], starting with a letter
  or digit; not `stable` or `head`; not all hex. Unique per dataset.
- `requestId` (query, string): Idempotency key (AIP-155): a retry with the same id within 24 hours
  returns the first call's result instead of failing ALREADY_EXISTS.

## Request body

Required: `application/json` `qualia.v1.Version`

## Responses

- `200` OK: `application/json` `qualia.v1.Version`
- `default` Default error response: `application/json` `google.rpc.Status`

## Schemas

```yaml
qualia.v1.Version:
  type: object
  properties:
    name:
      type: string
      description: accounts/{account}/datasets/{dataset}/versions/{version}
    tag:
      readOnly: true
      type: string
      description: The tag name ("1.0"); empty for head.
    digest:
      type: string
      description: |-
        Opaque episode-set identity, "b3:<hex>", for the (episode id, episode
        revision) pairs the ref yields. Head and tags use the same account-scoped
        identity. Upgrades preserve current heads and retained version digests.
        Clients compare returned identities rather than computing them.
        On CreateVersion, optionally the head digest seen in the tag dialog: when
        head has moved since, the call fails with ABORTED instead of tagging
        something nobody saw.
    episodeCount:
      readOnly: true
      type: string
      description: Episodes it pins.
    durationSeconds:
      readOnly: true
      type: number
      description: Recorded time it pins, seconds.
      format: double
    rejectedCount:
      readOnly: true
      type: string
      description: Episodes the dataset itself had rejected (inherited by whoever reads it).
    manifest:
      readOnly: true
      type: array
      items:
        $ref: "#/components/schemas/qualia.v1.Version_ManifestEntry"
      description: "Per upload: how finished it was."
    lock:
      readOnly: true
      type: array
      items:
        $ref: "#/components/schemas/qualia.v1.Version_LockEntry"
      description: "Per mixture source: what it resolved to. Empty for an upload."
    note:
      type: string
      description: What the version is, in a person's words. Editable after the cut.
    reference:
      readOnly: true
      type: string
      description: |-
        The reference a training run cites: "<Dataset.slug>:<tag>", e.g.
        "restock-shelf-mix:1.0". Unique per account.
    creator:
      readOnly: true
      allOf:
        - $ref: "#/components/schemas/qualia.v1.Actor"
      description: Who cut it.
    createTime:
      readOnly: true
      type: string
      description: When it was cut.
      format: date-time
    updateTime:
      readOnly: true
      type: string
      description: When the note last changed.
      format: date-time
    etag:
      type: string
      description: Sent back on UpdateVersion.
    datasetVersionId:
      readOnly: true
      type: string
      description: |-
        The immutable dataset version the tag pins, a UUID: the id training,
        materialization and health reads take. Tags of one digest
        may share it. Empty for head, which pins nothing.
    copySource:
      readOnly: true
      allOf:
        - $ref: "#/components/schemas/qualia.v1.Version_CopySource"
      description: |-
        Set only on `v0` of a copy, which holds what the copy started with rather
        than what an upload arrived with. ListVersionsResponse.copy_source says the
        same of any dataset, `v0` or not.
    preview:
      readOnly: true
      type: string
      description: |-
        accounts/{account}/datasets/{dataset}/versionPreviews/{version_preview}:
        the preview the tag was published from (PublishVersionPreview). Empty
        for a tag of head (CreateVersion), and for head itself.
    include:
      readOnly: true
      type: array
      items:
        enum:
          - CLASS_UNSPECIFIED
          - KEPT_BY_PERSON
          - KEPT
          - FLAGGED
          - REJECTED
          - REJECTED_BY_PERSON
        type: string
        format: enum
      description: Which takes the preview took, by how they stood. Empty when `preview` is.
    includedFlaggedCount:
      readOnly: true
      type: string
      description: Episodes it pins that stood FLAGGED when the preview was made.
    includedRejectedCount:
      readOnly: true
      type: string
      description: Episodes it pins that stood REJECTED when the preview was made.
    editedCount:
      readOnly: true
      type: string
      description: |-
        Takes published with the edit drawn on them. 0 for a tag of head, which
        has every take as recorded.
    trimmedCount:
      readOnly: true
      type: string
      description: Edited takes published as one new episode (a trim, new subtasks or both).
    splitCount:
      readOnly: true
      type: string
      description: Edited takes published as two or more new episodes.
    pieceCount:
      readOnly: true
      type: string
      description: New episodes the edited takes became, across every edited take.
    draftsNotIncluded:
      readOnly: true
      type: string
      description: |-
        Takes with an edit drawn and not published when a tag of head was made:
        the tag has them as recorded. 0 for a tag published from a preview.
  description: |-
    A version tag: a human name on what a dataset yielded at one moment. Uploads and mixtures both have them. A tag never moves; many
    tags may share a digest.

    The {version} id is the tag name. Two reserved ids resolve instead of
    naming a tag: `stable` (the newest tag) and `head` (what the
    dataset yields now; a Version with no tag).
    A DatasetVersion id (`dataset_version_id`, what an upload prints) names
    the version that has it; a tag cut with that UUID as its name, before such
    names were refused, answers first, and FAILED_PRECONDITION when the two
    are different versions. Any other id that is not a tag is matched as a
    prefix (7+ hex characters) of the dataset's version digests and of their
    DatasetVersion ids without dashes. Those include an upload's
    `v0`, which has no tag row.

    Served by qds-api.
qualia.v1.Version_ManifestEntry:
  type: object
  properties:
    dataset:
      readOnly: true
      type: string
      description: |-
        accounts/{account}/datasets/{dataset}: the upload. A mixture's version
        names an upload a merge took by its merged dataset, one entry for all
        the uploads it holds, their counts summed; a merged
        dataset's own versions name its uploads.
    reviewedCount:
      readOnly: true
      type: string
      description: |-
        Episodes a person or validation had ruled on. On `v0`, 0: nothing was
        ruled yet, except on a copy, whose rulings came with it and were not
        counted (see Version.copy_source).
    totalCount:
      readOnly: true
      type: string
      description: Episodes in the upload.
    memberCount:
      readOnly: true
      type: string
      description: Episodes the version took from it.
  description: How finished one upload was when the version was cut.
qualia.v1.Version_LockEntry:
  type: object
  properties:
    source:
      readOnly: true
      type: string
      description: accounts/{account}/datasets/{dataset}/sources/{source}
    dataset:
      readOnly: true
      type: string
      description: "accounts/{account}/datasets/{dataset}: the dataset it resolved to."
    follow:
      readOnly: true
      allOf:
        - $ref: "#/components/schemas/qualia.v1.Follow"
      description: The follow it had.
    ref:
      readOnly: true
      type: string
      description: The tag it stood at, or "head".
    digest:
      readOnly: true
      type: string
      description: The digest it stood at.
    episodeCount:
      readOnly: true
      type: string
      description: Episodes it brought in.
  description: "What one mixture source resolved to when the version was cut: the lockfile row."
qualia.v1.Follow:
  type: object
  properties:
    channel:
      enum:
        - CHANNEL_UNSPECIFIED
        - STABLE
        - HEAD
      type: string
      description: Move with a channel.
      format: enum
    pin:
      type: string
      description: Stay on this version tag of the source dataset, e.g. "1.0".
  description: |-
    How a mixture source is read: on a channel that moves by itself, or pinned
    to one version tag that never moves.
qualia.v1.Actor:
  type: object
  properties:
    kind:
      readOnly: true
      enum:
        - KIND_UNSPECIFIED
        - PERSON
        - VALIDATION
        - RULE
        - MODEL
        - OPERATOR
        - SYSTEM
      type: string
      description: What kind of actor it is.
      format: enum
    user:
      readOnly: true
      type: string
      description: The person's user id when `kind` is PERSON; empty otherwise.
    displayName:
      readOnly: true
      type: string
      description: The person's display name at the time, for rendering without a lookup.
    agent:
      readOnly: true
      type: string
      description: |-
        The rule code, or for a MODEL the Qualia model tier (e.g. "qualia-vlm";
        "qualia" for any other model), when not a person.
    run:
      readOnly: true
      type: string
      description: The run a model or rule finding came from, when it has one.
    apiKey:
      readOnly: true
      type: string
      description: |-
        The API key's id when a person acted through one; empty for a session.
        Never the key itself.
    attribution:
      readOnly: true
      allOf:
        - $ref: "#/components/schemas/qualia.v1.Attribution"
      description: |-
        Signed identity evidence recorded with the change, kept apart from the
        principal above. Unset on older records and wherever none was signed.
  description: Who did something. Every decision, issue and reply names one.
qualia.v1.Attribution:
  type: object
  properties:
    authentication:
      readOnly: true
      enum:
        - AUTHENTICATION_UNSPECIFIED
        - SESSION
        - API_KEY
        - SERVICE
      type: string
      description: How the principal authenticated.
      format: enum
    initiator:
      readOnly: true
      type: string
      description: |-
        The user id of a person verified as starting the work: the person of a
        session, or the person a trusted service's signed job record names.
        Empty when nobody was verified.
    initiatorDisplayName:
      readOnly: true
      type: string
      description: The initiator's display name at the time, never their email.
    credentialCreator:
      readOnly: true
      type: string
      description: The user id of the key's creator at the time. Not who used the key.
    credentialOwner:
      readOnly: true
      enum:
        - CREDENTIAL_OWNER_UNSPECIFIED
        - PERSON
        - SPACE
      type: string
      description: Who owned the key at the time.
      format: enum
    credentialOwnerSpace:
      readOnly: true
      type: string
      description: |-
        The owning space's id (a workspace or the organization) when
        `credential_owner` is SPACE.
  description: |-
    How a change was authenticated and who verifiably started it.
    Only the trusted mesh signs it. It never authorizes anything, and a key's
    creator or owner is never the person who used the key.
qualia.v1.Version_CopySource:
  type: object
  properties:
    datasetDisplayName:
      readOnly: true
      type: string
      description: |-
        The source dataset's name. Empty for a source in another organization,
        and for an upload forked for a copied mixture, which has no record of
        its own.
    workspaceDisplayName:
      readOnly: true
      type: string
      description: The source's workspace's name; empty when no record names it.
    organizationDisplayName:
      readOnly: true
      type: string
      description: The source's organization's name; set only for another organization.
    version:
      readOnly: true
      type: string
      description: The source's version tag; empty for the version it stood at then.
    copyTime:
      readOnly: true
      type: string
      description: When the copy was made.
      format: date-time
  description: |-
    What a copy started from, in the words its own organization may read: a
    source in another organization is named by its workspace and organization
    only, with no dataset and no id. Names are as they were when it was copied.
google.rpc.Status:
  oneOf:
    - $ref: "#/components/schemas/ApiError"
    - $ref: "#/components/schemas/GatewayError"
  description: "The body of a failed call: one of the two shapes below."
ApiError:
  title: API error
  type: object
  required:
    - code
    - message
    - retryable
    - details
  properties:
    code:
      type: string
      description: The gRPC code name in upper case, e.g. `NOT_FOUND`.
    message:
      type: string
    retryable:
      type: boolean
      description: Whether the same call may succeed if retried.
    details:
      type: array
      items:
        type: object
      description: "Empty, except when a dataset copy or move is refused: then one `google.rpc.ErrorInfo` with the refusal's `reason` code, its `domain` and, in `metadata`, the datasets it names."
  description: A refusal from the API itself.
GatewayError:
  title: Gateway error
  type: object
  required:
    - detail
  properties:
    detail:
      type: string
      description: What went wrong.
  description: A refusal from the gateway before the call reaches the API, for example `401` bad or missing API key, `403` key lacks the scope or environment closed, `413` body too large.
```
