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

# Starting a Document Upload

Start an upload by `POST`ing the `filename` and `size` to `/documents/init_upload`. To actually perform the upload it is then necessary to transmit the file to the provided `upload_url`, with any `additional_fields` as needed.

### Performing the actual upload

A typical upload involves `POST`ing a sample up to 20GB in size to a provided HTTPS URL. The `Content-Type` should be `multipart/form-data` and the `additional_fields` should be included in the `POST` body.

The workflow using [httpie](https://httpie.org) or Python requests is:

<CodeGroup>
  ```sh httpie theme={null}
  # Start the upload
  # Start the upload
  http --auth $ONE_CODEX_API_KEY: POST \
  https://app.onecodex.com/api/v1/documents/init_upload \
  filename=report.pdf size:=31337

  # Returns a 200 response with the following JSON body:
  # {
  #     "additional_fields": {
  #         "AWSAccessKeyId": "XXXXXXXXXXXXXXXXXXXX",
  #         "acl": "private",
  #         "key": "user_xxxxxxxxxxxxxxxx/file_yyyyyyyyyyyyyyyy/${filename}",
  #         "policy": "CiAgICAgICAgICAgAgICAgICB7ImJ1Y2tldCI6ICJyZWZnZW5vbWljcy11c2VyZGF0YS1kZXYtZW5jcnlwdGVkIiB9LAogICAS1lbmNyeXB0aW9uIjogIkFFUzI1NiJ9LAogICAgICAgICAgICAgICAgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgInVzZXJfNGFkYTU2MTAzZDlhNDhiOC9maWxlXzI4NDU5NTA4NTkyYTQ4MWMvIl0sCiAgICAgICAgICAgICAgICB7InN1Y2Nlc3NfYWN0aW9uX3N0YXR1cyI6ICIyMDEifSwKICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgICAg",
  #         "signature": "ELADfQLgxXXXXXXXXx/5D99Q9AY=",
  #         "success_action_status": 201,
  #         "x-amz-server-side-encryption": "AES256"
  #     },
  #     "document_id": "28459508592a481c",
  #     "upload_url": "https://refgenomics-userdata-dev-encrypted.s3.amazonaws.com"
  # }

  http -f POST \
      https://sample-upload-bucket.s3.amazonaws.com \
      AWSAccessKeyId="XXXXXXXXXXXXXXXXXXXX" acl="private" \
      key="user_xxxxxxxxxxxxxxxx/file_yyyyyyyyyyyyyyyy/${filename}" \
      policy="CiAgICAgICAgICAgAgICAgICB7ImJ1Y2tldCI6ICJyZWZnZW5vbWljcy11c2VyZGF0YS1kZXYtZW5jcnlwdGVkIiB9LAogICAS1lbmNyeXB0aW9uIjogIkFFUzI1NiJ9LAogICAgICAgICAgICAgICAgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgInVzZXJfNGFkYTU2MTAzZDlhNDhiOC9maWxlXzI4NDU5NTA4NTkyYTQ4MWMvIl0sCiAgICAgICAgICAgICAgICB7InN1Y2Nlc3NfYWN0aW9uX3N0YXR1cyI6ICIyMDEifSwKICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgICAg" \
      signature="ELADfQLgxXXXXXXXXx/5D99Q9AY=" success_action_status:=201 \
      x-amz-server-side-encryption="AES256" \
      file@report.pdf

  # Returns a 201 response

  # Confirm the upload (see below)
  http --auth $ONE_CODEX_API_KEY: POST \
      https://app.onecodex.com/api/v1/documents/confirm_upload \
      sample_id="28459508592a481c"
  ```

  ```python Python theme={null}
  import os
  import requests

  # Start the upload
  resp = requests.post('https://app.onecodex.com/api/v1/documents/init_upload',
                       json={'filename': 'report.pdf',
                             'size': os.path.getsize('report.pdf')},
                       auth=(os.getenv('ONE_CODEX_API_KEY'), '')
                      ).json()

  # Perform the upload (should return a 201)
  requests.post(resp['upload_url'], data=resp['additional_fields'],
               files={'file': open('report.pdf')})

  # Finally, confirm the upload (should return a 200)
  requests.post('https://app.onecodex.com/api/v1/documents/confirm_upload',
                json={'document_id': resp['document_id']},
                auth=(os.getenv('ONE_CODEX_API_KEY'), ''))
  ```
</CodeGroup>


## OpenAPI

````yaml POST /api/v1/documents/init_upload
openapi: 3.0.0
info:
  title: One Codex API (v1)
  description: >-
    The One Codex API (v1) -- programmatic access to One Codex's suite of
    microbial genomics data storage, analysis, and query tools.
  version: v1
servers:
  - url: https://app.onecodex.com
security:
  - apiKeyAuth: []
paths:
  /api/v1/documents/init_upload:
    post:
      summary: POST documents init_upload
      operationId: post_documents_init_upload
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                filename:
                  type: string
                  description: >-
                    The filename of the document to be uploaded, optionally
                    gzipped (and ending in `.gz` or `.gzip`). Filenames should
                    only contain alphanumeric characters, dashes, underscores,
                    and periods.
                size:
                  type: integer
                  minimum: 1
                  description: The size of the file in bytes.
              required:
                - filename
                - size
        required: true
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  additional_fields:
                    type: string
                    nullable: true
                    description: Additional fields to include in the upload.
                    items:
                      type: object
                  document_id:
                    type: string
                    description: The `document_id` of the uploaded document.
                  upload_url:
                    type: string
                    description: The URL to POST the document to.
components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

````