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

# Create a dataset

> Step one of three. This creates an empty dataset; the file goes next, straight to storage through a signed URL from getUploadEndpoint, and validateUpload then checks it. Your data never passes through this API.



## OpenAPI

````yaml openapi/prentis-training.openapi.yaml POST /accounts/{account}/datasets
openapi: 3.1.0
info:
  title: Prentis Training API
  version: 0.1.0
  summary: >-
    Fine-tune models on your own data, with the same API key you use for
    inference.
  description: >
    Upload a dataset, start a fine-tuning job on it, and watch it train -- from
    code, with

    the API key you already use for inference. The jobs and datasets are the
    same ones the

    console shows: anything started here appears there, and the other way round.


    Every path is under `/v1/accounts/{account}`, where `{account}` is the
    account the key

    belongs to. A key reaches its own account only.


    A finished job produces a model in your account
    (`accounts/{account}/models/{outputModelId}`),

    listed under Custom models in the console. To call it, deploy it on a
    dedicated deployment

    and send inference requests to the deployment
    (`accounts/{account}/deployments/{deployment}`).
servers:
  - url: https://compute.prentis.ai/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: training
  - name: datasets
paths:
  /accounts/{account}/datasets:
    post:
      tags:
        - datasets
      summary: Create a dataset
      description: >-
        Step one of three. This creates an empty dataset; the file goes next,
        straight to storage through a signed URL from getUploadEndpoint, and
        validateUpload then checks it. Your data never passes through this API.
      operationId: createDataset
      parameters:
        - $ref: '#/components/parameters/Account'
        - name: datasetId
          in: query
          required: false
          schema:
            type: string
            maxLength: 64
          description: >-
            The id to give the dataset: lowercase letters, digits and hyphens,
            up to 64. It becomes part of the dataset's name and can never be
            changed or reused, even after the dataset is deleted. Leave it out
            to derive one from displayName.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DatasetDraft'
      responses:
        '201':
          headers:
            x-request-id:
              $ref: '#/components/headers/x-request-id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dataset'
              example:
                name: accounts/my-account/datasets/support-chats
                datasetId: support-chats
                displayName: Support chats
                source: DATASET_SOURCE_UPLOAD
                state: DATASET_STATE_CREATING
                createTime: '2026-10-10T07:40:00Z'
                updateTime: '2026-10-10T07:40:00Z'
          description: Created.
        '400':
          $ref: '#/components/responses/Error400'
        '401':
          $ref: '#/components/responses/Error401'
        '403':
          $ref: '#/components/responses/Error403'
        '409':
          $ref: '#/components/responses/Error409'
        '429':
          $ref: '#/components/responses/Error429'
        '500':
          $ref: '#/components/responses/Error500'
        '503':
          $ref: '#/components/responses/Error503'
      x-codeSamples:
        - lang: curl
          label: cURL
          source: >-
            curl
            "https://compute.prentis.ai/v1/accounts/my-account/datasets?datasetId=support-chats"
            \
              -H "Authorization: Bearer $PRENTIS_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{"displayName": "Support chats"}'
        - lang: python
          label: Python
          source: >-
            import os

            import time

            import requests


            BASE = "https://compute.prentis.ai/v1/accounts/my-account"

            HEADERS = {"Authorization": f"Bearer
            {os.environ['PRENTIS_API_KEY']}"}

            path = "train.jsonl"


            # 1. Create the dataset.

            requests.post(f"{BASE}/datasets", params={"datasetId":
            "support-chats"},
                          headers=HEADERS, json={"displayName": "Support chats"}).raise_for_status()

            # 2. Ask for an upload URL, then PUT the file straight to it.

            up =
            requests.post(f"{BASE}/datasets/support-chats:getUploadEndpoint",
            headers=HEADERS,
                               json={"filenameToSize": {path: str(os.path.getsize(path))}})
            up.raise_for_status()

            with open(path, "rb") as f:
                requests.put(up.json()["filenameToSignedUrl"][path], data=f).raise_for_status()

            # 3. Validate, and wait for the verdict.

            requests.post(f"{BASE}/datasets/support-chats:validateUpload",
            headers=HEADERS,
                          json={"uploadSession": up.json()["uploadSession"]["name"]}).raise_for_status()
            while (ds := requests.get(f"{BASE}/datasets/support-chats",
            headers=HEADERS).json())["state"] \
                    == "DATASET_STATE_VALIDATING":
                time.sleep(5)
            print(ds["state"])
components:
  parameters:
    Account:
      name: account
      in: path
      required: true
      schema:
        type: string
        maxLength: 64
      description: >-
        Your account id -- the one in the console's address bar (my-account for
        this key). It must be the account the key belongs to.
  schemas:
    DatasetDraft:
      type: object
      required:
        - displayName
      properties:
        displayName:
          type: string
          maxLength: 128
          description: A human-readable name for the dataset, up to 128 characters.
    Dataset:
      type: object
      properties:
        name:
          type: string
        datasetId:
          type: string
        displayName:
          type: string
        source:
          type: string
          enum:
            - DATASET_SOURCE_UPLOAD
            - DATASET_SOURCE_JOB_OUTPUT
            - DATASET_SOURCE_SPLIT
        sourceJob:
          type: string
        parentVersion:
          type: string
        state:
          type: string
          enum:
            - DATASET_STATE_CREATING
            - DATASET_STATE_UPLOADING
            - DATASET_STATE_VALIDATING
            - DATASET_STATE_READY
            - DATASET_STATE_FAILED
            - DATASET_STATE_DELETED
        latestVersionNo:
          type: integer
        totalBytes:
          type: string
          format: int64
        activeReferenceCount:
          type: integer
        createdBy:
          type: string
        createTime:
          type: string
          format: date-time
        updateTime:
          type: string
          format: date-time
        deleteTime:
          type: string
          format: date-time
        versions:
          type: array
          items:
            $ref: '#/components/schemas/DatasetVersion'
        lineage:
          $ref: '#/components/schemas/DatasetLineage'
    DatasetVersion:
      type: object
      properties:
        name:
          type: string
        versionId:
          type: string
        versionNo:
          type: integer
        bytes:
          type: string
          format: int64
        exampleCount:
          type: string
          format: int64
        estimatedTokenCount:
          type: string
          format: int64
        checksum:
          type: string
        state:
          type: string
          enum:
            - DATASET_VERSION_STATE_UPLOADING
            - DATASET_VERSION_STATE_VALIDATING
            - DATASET_VERSION_STATE_READY
            - DATASET_VERSION_STATE_FAILED
        validation:
          $ref: '#/components/schemas/DatasetValidation'
        createTime:
          type: string
          format: date-time
        topLevelKeys:
          type: array
          items:
            type: string
    DatasetLineage:
      type: object
      properties:
        consumers:
          type: array
          items:
            $ref: '#/components/schemas/DatasetConsumer'
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - message
            - type
            - code
          properties:
            message:
              type: string
            type:
              type: string
              enum:
                - invalid_request_error
                - authentication_error
                - permission_error
                - not_found_error
                - rate_limit_error
                - server_error
                - service_unavailable
                - billing_error
            code:
              type: string
              enum:
                - INVALID_REQUEST
                - INVALID_API_KEY
                - OPERATION_NOT_ALLOWED
                - TENANT_SUSPENDED
                - AGREEMENT_REQUIRED
                - DATA_RESIDENCY_VIOLATION
                - PROVIDER_NOT_ALLOWED
                - PROVIDER_SERVICE_UNAVAILABLE
                - INSUFFICIENT_BALANCE
                - PAYMENT_REQUIRED
                - MODEL_NOT_FOUND
                - MODEL_ALREADY_EXISTS
                - DATASET_NOT_FOUND
                - DATASET_ALREADY_EXISTS
                - DATASET_STATE_INVALID
                - DATASET_IN_USE
                - DATASET_TOO_LARGE
                - JSONL_LINE_NOT_OBJECT
                - JSONL_MISSING_FIELD
                - JSONL_ENCODING
                - JOB_NOT_FOUND
                - JOB_STATE_INVALID
                - TRAINING_RUN_ABANDONED
                - TRAINING_TOKENIZE_FAILED
                - TRAINING_BASE_NOT_EXPORTABLE
                - IDEMPOTENCY_CONFLICT
                - QUOTA_EXCEEDED
                - INTERNAL
                - STORAGE_UNAVAILABLE
            param:
              type:
                - string
                - 'null'
    DatasetValidation:
      type: object
      properties:
        totalLines:
          type: string
          format: int64
        validLines:
          type: string
          format: int64
        firstErrorLine:
          type: string
          format: int64
        errorClass:
          type: string
          enum:
            - JSONL_LINE_NOT_OBJECT
            - JSONL_MISSING_FIELD
            - JSONL_ENCODING
    DatasetConsumer:
      type: object
      properties:
        name:
          type: string
        kind:
          type: string
          enum:
            - DATASET_CONSUMER_KIND_TRAINING_JOB
            - DATASET_CONSUMER_KIND_BATCH_JOB
            - DATASET_CONSUMER_KIND_EVALUATION_JOB
            - DATASET_CONSUMER_KIND_DATASET
        pinnedVersion:
          type: string
        state:
          type: string
        blocksDelete:
          type: boolean
  headers:
    x-request-id:
      schema:
        type: string
      required: true
      description: >-
        On every response, successes and errors alike. Quote it when you ask us
        about a call.
    Retry-After:
      schema:
        type: integer
        minimum: 0
      description: How many seconds to wait before retrying, on the responses that set it.
  responses:
    Error400:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `DATASET_STATE_INVALID`, `INVALID_REQUEST`,
        `JSONL_ENCODING`, `JSONL_LINE_NOT_OBJECT`, `JSONL_MISSING_FIELD`,
        `TRAINING_BASE_NOT_EXPORTABLE`, `TRAINING_TOKENIZE_FAILED`. See the
        Errors page for what each one means, whether it is safe to retry, and
        whether it is billed.
    Error401:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `INVALID_API_KEY`. See the Errors page for what
        each one means, whether it is safe to retry, and whether it is billed.
    Error403:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `AGREEMENT_REQUIRED`,
        `DATA_RESIDENCY_VIOLATION`, `OPERATION_NOT_ALLOWED`,
        `PROVIDER_NOT_ALLOWED`, `PROVIDER_SERVICE_UNAVAILABLE`,
        `TENANT_SUSPENDED`. See the Errors page for what each one means, whether
        it is safe to retry, and whether it is billed.
    Error409:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `DATASET_ALREADY_EXISTS`, `DATASET_IN_USE`,
        `IDEMPOTENCY_CONFLICT`, `JOB_STATE_INVALID`, `MODEL_ALREADY_EXISTS`. See
        the Errors page for what each one means, whether it is safe to retry,
        and whether it is billed.
    Error429:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `QUOTA_EXCEEDED`. See the Errors page for what
        each one means, whether it is safe to retry, and whether it is billed.
    Error500:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `INTERNAL`, `TRAINING_RUN_ABANDONED`. See the
        Errors page for what each one means, whether it is safe to retry, and
        whether it is billed.
    Error503:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `STORAGE_UNAVAILABLE`. See the Errors page for
        what each one means, whether it is safe to retry, and whether it is
        billed.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        `Authorization: Bearer <your API key>` -- the same key as inference. A
        key reaches the account it belongs to and no other.

````

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