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

# Create a dataset

> Create a dataset. A dataset is the labelled data a training run reads: an 80% train CSV and a 20%
test CSV that keeps its labels.

Two ways to fill it:

* **Upload.** The response carries one `uploadTargets` entry per file (`TRAIN` and `TEST`). PUT each
  CSV to its signed URL, then call `POST /api/v1/datasets/{datasetKey}/clean`.
* **From a refinement.** Send `featureRefinementKey` instead. The refined train and test files and
  the target that refinement reached come across with it, `uploadTargets` comes back empty, and
  there is nothing to upload.

The dataset starts `PENDING`, moves to `PROCESSING` when cleaning starts, and is ready to train from
at `COMPLETED`. Poll `GET /api/v1/datasets/{datasetKey}` for the status.




## OpenAPI

````yaml api-reference/openapi.yaml POST /api/v1/datasets
openapi: 3.0.1
info:
  title: MathFi.ai API
  description: >
    The MathFi.ai REST API runs the two products end to end.


    **Feature Refinery** takes your labelled data and works out which columns

    actually carry the signal. It returns a reduced train and test pair, a

    per-column keep/remove decision, and the performance target the refined data

    reached.


    **Model Crucible** takes a dataset, trains every algorithm family against it

    at once, ranks the results on held-out data by fewest wrong decisions, and

    keeps the best three as versions of one model. You pick which one
    predictions

    run against.


    Everything is asynchronous: you create a thing, upload to a signed URL,
    start

    it, then poll until the state is terminal. Nothing streams and nothing
    blocks.
  contact:
    name: MathFi.ai
    url: https://mathfi.ai
    email: support@mathfi.ai
  license:
    name: MathFi.ai
    url: https://mathfi.ai
  version: 1.0.0
servers:
  - url: https://{tenant}-api.mathfi.ai
    description: >-
      Your tenant's API. Each customer has their own, so the host varies.
      Replace {tenant} with the name issued when your tenant was created.
    variables:
      tenant:
        default: your-tenant
        description: The tenant name issued to you.
security:
  - BearerAuth: []
tags:
  - name: Authentication
    description: Exchange credentials for a bearer token
  - name: Feature Refinery
    description: Reduce a dataset to the columns that earn their place
  - name: Datasets
    description: >-
      Prepare labelled data for training, from uploads or from a finished
      refinement
  - name: Training
    description: Run the Crucible against a dataset and choose the champion model
  - name: Models
    description: Trained models and their versions
  - name: Predictions
    description: Score unlabelled data against a champion model
paths:
  /api/v1/datasets:
    post:
      tags:
        - Datasets
      summary: Create a dataset
      description: >
        Create a dataset. A dataset is the labelled data a training run reads:
        an 80% train CSV and a 20%

        test CSV that keeps its labels.


        Two ways to fill it:


        * **Upload.** The response carries one `uploadTargets` entry per file
        (`TRAIN` and `TEST`). PUT each
          CSV to its signed URL, then call `POST /api/v1/datasets/{datasetKey}/clean`.
        * **From a refinement.** Send `featureRefinementKey` instead. The
        refined train and test files and
          the target that refinement reached come across with it, `uploadTargets` comes back empty, and
          there is nothing to upload.

        The dataset starts `PENDING`, moves to `PROCESSING` when cleaning
        starts, and is ready to train from

        at `COMPLETED`. Poll `GET /api/v1/datasets/{datasetKey}` for the status.
      operationId: createDataset
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DatasetCreationRequest'
            examples:
              Example Dataset Request:
                summary: Dataset creation request
                value:
                  datasetName: Example Dataset
                  numberOfBuckets: 10
        required: true
      responses:
        '201':
          description: Dataset successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatasetCreationOutput'
        '400':
          description: Invalid dataset name or number of buckets provided
        '500':
          description: Internal server error
components:
  schemas:
    DatasetCreationRequest:
      required:
        - datasetName
      type: object
      properties:
        datasetName:
          maxLength: 30
          minLength: 3
          type: string
          description: The unique dataset name
          example: German Credit refined
        description:
          maxLength: 150
          minLength: 3
          type: string
          description: The dataset description in plain text
          nullable: true
          example: Refined German Credit data, 4 buckets
        numberOfBuckets:
          minimum: 4
          maximum: 1000
          type: integer
        featureRefinementKey:
          description: >-
            Build this dataset from a completed refinement instead of from
            uploaded files. Its refined train and test files and the threshold
            it trained to come across with it, so no upload target is returned.
            Its bucket count comes across as the default: the cleaning here
            starts from scratch, so a caller that sends its own bucket count
            above is honoured.
          type: string
          format: uuid
          nullable: true
    DatasetCreationOutput:
      required:
        - datasetCreationProgressUrl
        - datasetKey
        - status
      type: object
      properties:
        datasetKey:
          pattern: >-
            ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
          type: string
          format: uuid
        numberOfBuckets:
          type: integer
        status:
          $ref: '#/components/schemas/DatasetCreationStatus'
        datasetCreationProgressUrl:
          type: string
        datasetUploadInfo:
          $ref: '#/components/schemas/UploadMetadata'
        uploadTargets:
          description: >-
            Where to PUT each input file. A dataset built from a train and a
            labelled test file returns one target per file; a dataset whose
            files came from a completed refinement returns none, because nothing
            is uploaded. Empty on the single-file pipeline.
          type: array
          items:
            $ref: '#/components/schemas/DatasetUploadTarget'
    DatasetCreationStatus:
      type: string
      description: >+
        Status of dataset creation: 


        * `PENDING` - The dataset has been created and is pending further
        actions. Mainly data addition

        * `PROCESSING` - The dataset is currently being processed. When this
        status is returned an url to check status is returned too

        * `COMPLETED` - The dataset has been processed and is completed. The
        dataset is now ready to be used for training models

        * `FAILED` - The dataset processing has failed

      enum:
        - PENDING
        - PROCESSING
        - COMPLETED
        - FAILED
    UploadMetadata:
      description: >
        Where to PUT the CSV on the single-file route. Prefer `uploadTargets`,
        which names each file it

        expects.


        `uploadUrl` is a signed URL valid for 60 minutes. PUT the CSV as a
        binary body with

        `Content-Type: text/csv` and every header listed in `extraHeaders` (one
        colon-joined

        `Name:value` pair per header, semicolon-separated). Send no
        `Authorization` header: the signature

        covers the request, and an extra header breaks it.
      type: object
      properties:
        uploadUrl:
          type: string
          description: The signed URL for uploading the CSV file using a PUT request.
        extraHeaders:
          type: string
          description: >
            Additional headers required for the PUT request. These are formatted
            as a 

            comma-separated string (e.g.,
            `headerName1:headerValue1,headerName2:headerValue2`). 

            Ensure all specified headers are included in the request.
    DatasetUploadTarget:
      description: One place the client must PUT an input file to.
      required:
        - kind
        - url
      type: object
      properties:
        kind:
          type: string
          enum:
            - TRAIN
            - TEST
          description: >-
            TRAIN is the 80% training file; TEST is the 20% file WITH its
            labels, which is what the models are scored against.
        url:
          type: string
          description: Signed upload URL — PUT the CSV directly to it.
        requiredHeader:
          type: string
          nullable: true
          description: >-
            A single request header the PUT must include, as one colon-joined
            "Name:value" string. The PUT must ALSO send "Content-Type:
            text/csv". Null when no extra header is required.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````