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

# Start a Drive Upload

> Get a temporary URL for uploading a prepared file directly to storage.

Use this flow for large files or to avoid base64 encoding. The file appears in Drive after you upload its bytes and [commit the upload](https://docs.transparencyhubnetwork.ai/api-reference/drive/commit-upload.md).

**Required scope:** `drive:write`

> [!NOTE]
>
> This endpoint requires the Drive document creation API to be deployed to the selected environment, with Drive enabled.

## 1. Start the upload

Send the file name, matching MIME type and exact byte size in `declared_size`. Omit `parent_id` or use `null` for the Drive root. Association-wide keys must also specify `chapter_id`.

The key owner's current Drive permissions and the chapter's storage quota apply.

```json Request theme={null}
{
  "file_name": "Annual report.pdf",
  "content_type": "application/pdf",
  "declared_size": 12345,
  "parent_id": 22
}
```

```json 201 theme={null}
{
  "status": "success",
  "data": {
    "upload_session_id": 123,
    "upload_url": "https://example.blob.core.windows.net/drive-5-9/staging/report.pdf?REPLACE_WITH_RETURNED_SAS",
    "expires_at": "2026-10-24T10:40:00+00:00"
  }
}
```

## 2. Upload the bytes

`PUT` the raw file bytes to the returned `upload_url`, adding the `x-ms-blob-type: BlockBlob` header:

```bash theme={null}
curl --request PUT "$UPLOAD_URL" \
  --header "x-ms-blob-type: BlockBlob" \
  --header "Content-Type: application/pdf" \
  --data-binary "@Annual report.pdf"
```

Set `UPLOAD_URL` to the exact URL returned by the API. Treat it as a temporary secret, and do not send your Transparency Hub API key to storage.

The upload URL lasts 30 minutes. The session's `expires_at` is the commit deadline, with a further 10 minutes of grace; it does not extend the upload URL's lifetime.

## 3. Commit the upload

Call [Commit a Drive Upload](https://docs.transparencyhubnetwork.ai/api-reference/drive/commit-upload.md) using `upload_session_id` and the original API key. Association-wide keys must specify the same chapter again. Until commit succeeds, the uploaded bytes are not a Drive item.

For small documents, [Create a Drive Document](https://docs.transparencyhubnetwork.ai/api-reference/drive/create-document.md) completes these steps in one request.


## OpenAPI

````yaml POST /v1/drive/files/upload-session
openapi: 3.0.3
info:
  title: Transparency Hub Public API
  version: 1.7.0
  description: Key-authenticated REST API for association and chapter integrations.
servers:
  - url: https://api.transparencyhubnetwork.ai/api
  - url: https://testapi.transparencyhubnetwork.ai/api
    description: Test
security:
  - ApiKeyAuth: []
  - BearerAuth: []
paths:
  /v1/drive/files/upload-session:
    post:
      summary: Start a Drive file upload
      description: >-
        Requires drive:write and the key owner's Drive permissions. PUT the raw
        file bytes to upload_url with x-ms-blob-type: BlockBlob within 30
        minutes, then POST /v1/drive/files/commit. Do not forward your API key
        to blob storage. The file is visible in Drive only after commit. Treat
        upload_url as a temporary secret.
      parameters:
        - $ref: '#/components/parameters/chapterId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDriveUploadSession'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - success
                  data:
                    $ref: '#/components/schemas/DriveUploadSession'
        '400':
          description: >-
            Invalid input, unsupported file type, invalid file signature, size
            mismatch, or quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            Missing drive:write scope, forbidden chapter, or insufficient Drive
            permissions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Parent folder or upload session not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: File name conflict or upload session already finalized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: Drive is disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  parameters:
    chapterId:
      name: chapter_id
      in: query
      schema:
        type: integer
      description: >-
        Required for association-wide keys; must match the key's chapter for
        chapter-bound keys.
  schemas:
    CreateDriveUploadSession:
      type: object
      required:
        - file_name
        - content_type
        - declared_size
      properties:
        chapter_id:
          type: integer
          minimum: 1
          description: >-
            Required for association-wide keys; otherwise the key chapter is
            used.
        parent_id:
          type: integer
          minimum: 1
          nullable: true
          description: Omit or use null for the Drive root.
        file_name:
          type: string
          minLength: 1
          maxLength: 255
        content_type:
          type: string
          description: A supported Drive MIME type matching file_name.
        declared_size:
          type: integer
          minimum: 1
          description: Exact file size in bytes.
    DriveUploadSession:
      type: object
      required:
        - upload_session_id
        - upload_url
        - expires_at
      properties:
        upload_session_id:
          type: integer
        upload_url:
          type: string
          format: uri
          description: >-
            Temporary secret SAS URL. PUT the raw bytes with x-ms-blob-type:
            BlockBlob.
        expires_at:
          type: string
          format: date-time
          description: >-
            Session commit deadline. The upload URL lasts 30 minutes; the commit
            deadline includes 10 minutes of grace.
    Error:
      type: object
      required:
        - status
        - code
        - message
      properties:
        status:
          type: string
          enum:
            - error
        code:
          type: string
        message:
          type: string
        details:
          type: object
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    BearerAuth:
      type: http
      scheme: bearer

````

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