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

# Start Knowledge Base Upload Session

> Creates an upload session for a new knowledge base document. Returns a `sessionId` used for the subsequent chunk upload and complete calls.

**Supported MIME types:** `application/pdf`, `text/plain`, `application/vnd.openxmlformats-officedocument.wordprocessingml.document`, `text/markdown`

**Max file size:** 100 MB | **Max chunk size:** 10 MB




## OpenAPI

````yaml https://api.voice-agents.miraiminds.co/swagger.yaml post /v1/knowledge-base/upload/start
openapi: 3.0.3
info:
  title: Voice Agent by Mirai Minds
  version: 1.1.0
  description: >
    Build AI voice assistants that call your customers or handle inbound calls —
    no telephony expertise required.


    ## Authentication


    Every request (except `/health`) requires two headers:

    - `x-public-key` — your public key

    - `x-private-key` — your private key


    Workspace-scoped endpoints also need a `workspace` header with the workspace
    `_id` returned on onboarding.


    ## Entity Hierarchy


    ```

    Organization

    └── Workspace  (holds assistants + telephony numbers)
        └── Assistant
            ├── Telephony       (inbound + outbound phone numbers)
            ├── Knowledge Base  (documents + FAQ for RAG)
            └── Analysis Plan   (post-call AI evaluation)
    ```


    ## Quick Start (5 minutes)


    1. **Create a workspace** — `POST /v2/workspace/onboard/custom`
       → A default telephony number is auto-assigned in production.
    2. **Create an assistant** — `POST /v1/admin/assistant/create`
       → Use `variant.type: custom` and write your `agent.systemPrompt`.
    3. **Make a call** — `POST /v2/call/initiate`
       → Pass `callbackUrl` to receive real-time webhook events.

    See the **Onboarding** tag below for the full step-by-step guide.
  contact:
    name: API Architecture Team
    url: https://miraiminds.co
  license:
    name: Mirai Minds Proprietary License
    url: >-
      https://github.com/MiraiMinds/voice-agent-integration-specs/blob/main/LICENSE.md
servers:
  - url: https://api.voice-agents.miraiminds.co
    description: Production Server
  - url: https://api.stage.voice-agent.miraiminds.co
    description: Staging Server
  - url: http://localhost:3000
    description: Local Server
security:
  - PublicKeyAuth: []
    PrivateKeyAuth: []
tags:
  - name: Onboarding
    description: >
      Create and configure a workspace. **Custom is the recommended path** for
      all non-Shopify integrations.


      ---


      ## Complete Onboarding Flow (Custom)


      ### Step 1 — Create a workspace


      ```bash

      curl -X POST
      https://api.voice-agents.miraiminds.co/v2/workspace/onboard/custom \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "name": "Acme Support Line",
          "currencyCode": "USD",
          "timezone": "America/New_York",
          "supportContacts": {
            "phoneNumber": "+14155550100",
            "email": "support@acme.com"
          },
          "trustSignals": {
            "valuePropositionOneLiner": "Premium 24x7 AI support for Acme customers."
          }
        }'
      ```


      **Response:**

      ```json

      {
        "message": "Workspace onboarded successfully.",
        "data": {
          "_id": "6690a1b2c3d4e5f600000002",
          "name": "Acme Support Line",
          "variant": "custom"
        }
      }

      ```


      > **Auto-assigned number**: In production, every new workspace is
      automatically assigned a default telephony number. Check your assigned
      number via the Telephony APIs.


      ---


      ### Step 2 — Create an assistant


      Use the workspace `_id` from Step 1 as the `workspace` header value.


      ```bash

      curl -X POST
      https://api.voice-agents.miraiminds.co/v1/admin/assistant/create \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "workspace: 6690a1b2c3d4e5f600000002" \
        -H "Content-Type: application/json" \
        -d '{
          "name": "Acme Support Assistant",
          "variant": { "type": "custom" },
          "agent": {
            "identity": { "name": "Priya", "gender": "female", "voice": "priya" },
            "systemPrompt": "You are Priya, a helpful support agent for Acme. The customer name is {{customerName}}. Resolve their issue politely and professionally."
          },
          "icpContext": { "language": "english" },
          "callSettings": {
            "slots": [{ "startTime": "09:00", "endTime": "18:00" }],
            "maxCallDuration": 300,
            "concurrentCallCount": 5,
            "retryProtocol": {
              "maxAttemptsNoPickup": 2,
              "maxAttemptsLowEngagement": 1,
              "reAttemptPeriod": 300,
              "maxRescheduleCount": 1
            }
          },
          "analysisPlan": {
            "successCriteriaPlan": "Return true only if the customer issue was fully resolved and the customer expressed satisfaction. Return false if they were still confused, unhappy, or escalated.",
            "summaryPlan": "Summarize the customer issue, the resolution provided, and the customer sentiment."
          }
        }'
      ```


      **Response:**

      ```json

      {
        "message": "Assistant created successfully",
        "data": { "assistantId": "69a57cdba3f3ab7e07cca1e4" }
      }

      ```


      > **Number auto-assignment**: The workspace default number is
      auto-assigned as `outbound` on the **first** assistant in the workspace.
      Additional assistants need numbers assigned explicitly via the `telephony`
      field in the create/update payload.


      ---


      ### Step 3 — (Optional) Purchase a dedicated inbound number


      Search for available numbers:

      ```bash

      curl
      "https://api.voice-agents.miraiminds.co/v1/number-pool/search?countryCode=US&limit=5"
      \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "organization: YOUR_ORG_ID"
      ```


      Purchase it:

      ```bash

      curl -X POST
      https://api.voice-agents.miraiminds.co/v1/number-pool/purchase \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "organization: YOUR_ORG_ID" \
        -H "Content-Type: application/json" \
        -d '{ "number": "+14155550101", "countryCode": "US", "numberType": "local" }'
      ```


      Assign to assistant (inbound = customers call in, outbound = caller ID for
      outgoing calls):

      ```bash

      curl -X PUT
      https://api.voice-agents.miraiminds.co/v1/admin/assistant/update/69a57cdba3f3ab7e07cca1e4
      \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "workspace: 6690a1b2c3d4e5f600000002" \
        -H "Content-Type: application/json" \
        -d '{
          "telephony": {
            "inbound": "6700a1b2c3d4e5f600000111",
            "outbound": "6700a1b2c3d4e5f600000222"
          }
        }'
      ```


      ---


      ### Step 4 — Make your first call


      ```bash

      curl -X POST https://api.voice-agents.miraiminds.co/v2/call/initiate \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "workspace: 6690a1b2c3d4e5f600000002" \
        -H "Content-Type: application/json" \
        -d '{
          "phoneNumber": "+14155550200",
          "assistant": "69a57cdba3f3ab7e07cca1e4",
          "callbackUrl": "https://yourapp.com/webhooks/call-events",
          "payload": { "customerName": "Alex" }
        }'
      ```
  - name: Assistant
    description: >
      Assistants are the core of the platform. Each assistant has:

      - An **identity** (name, voice, gender)

      - A **systemPrompt** (the AI's instructions)

      - **Telephony** config (inbound/outbound numbers)

      - A **Knowledge Base** (documents + FAQ for RAG retrieval)

      - An **analysisPlan** (post-call AI evaluation)

      - **callSettings** (scheduling, retry logic, concurrency)


      ---


      ## Variant Types


      | Variant | Use case | systemPrompt |

      |---------|----------|--------------|

      | `custom` | Any use case you define | Required — you author it |

      | `abandoned_cart` | Shopify cart recovery | Auto-generated — leave empty
      |

      | `cod_to_prepaid` | Convert Shopify COD orders to prepaid |
      Auto-generated — leave empty |

      | `address_verification` | Verify or collect Shopify shipping addresses |
      Auto-generated — leave empty |

      | `order_confirmation` | Confirm Shopify orders before fulfillment |
      Auto-generated — leave empty |

      | `ndr_followup` | Follow up on failed delivery / NDR events |
      Auto-generated — leave empty |


      ## Using Preset Variants


      1. Create the assistant with `variant.type` set to the preset variant and
      leave `agent.systemPrompt` empty.

      2. Put preset configuration under `variant.config.<variant_type>`.

      3. Initiate calls with `payload` fields that match the variant input
      schema. Shopify order variants use Shopify order-like payloads;
      `ndr_followup` uses courier NDR data.


      Config quick reference:

      - `cod_to_prepaid`: requires `paymentLinkValidity`, `codFee`, and
      `supportContacts`.

      - `address_verification`: requires `minDays`, `maxDays`, and
      `supportContacts`.

      - `order_confirmation`: optional `supportContacts`.

      - `ndr_followup`: optional `maxRescheduleDays`, `webhookToken`, and
      `supportContacts`. Shiprocket can post NDR events to `POST
      /v1/shiprocket/ndr-webhook/{assistantId}`; when `webhookToken` is set,
      send the same value in `x-api-key`.


      ---


      ## Using the Knowledge Base (RAG)


      The knowledge base lets the assistant retrieve information from your
      uploaded documents and FAQ during a live call.


      ### 1. Upload a document

      See the **Knowledge Base** tag for the full 3-step upload flow. After
      upload + processing, you get a file URL.


      ### 2. Link to the assistant


      Pass the file URL under `knowledgeBase.documents` when creating or
      updating the assistant:


      ```json

      {
        "knowledgeBase": {
          "documents": [
            {
              "url": "https://storage.miraiminds.co/kb/acme-product-catalog.pdf",
              "title": "Product Catalog",
              "type": "pdf"
            }
          ],
          "faq": [
            {
              "question": "What is your return policy?",
              "answer": "We offer a 7-day return policy for unused items in original packaging."
            },
            {
              "question": "How long does shipping take?",
              "answer": "Standard shipping is 3–5 business days."
            }
          ]
        }
      }

      ```


      ### 3. Tell the assistant to use it in systemPrompt


      ```

      You are Priya, a support agent for Acme.


      When a customer asks about products, pricing, policies, or shipping:

      1. Search the knowledge base first.

      2. Use the retrieved information to answer accurately.

      3. If you cannot find the answer, say: "I don't have that detail right now
      — let me connect you with a specialist."


      Never make up information that is not in the knowledge base.

      Always greet the customer as {{customerName}}.

      ```


      ---


      ## Using analysisPlan


      `analysisPlan` instructs the AI to evaluate each call after it ends.
      Results appear in the `end-of-call` webhook event and the call dashboard.


      | Field | Type | Purpose |

      |-------|------|---------|

      | `successCriteriaPlan` | string prompt | AI returns `true`/`false` — was
      the goal achieved? |

      | `summaryPlan` | string prompt | AI returns a plain-English summary of
      the call |

      | `callInsightPlan` | object | AI returns structured key/value insights
      you define |


      ### Example — Customer Support


      ```json

      {
        "analysisPlan": {
          "successCriteriaPlan": "Return true ONLY if the customer issue was fully resolved and they expressed satisfaction before ending the call. Return false if they were still confused, frustrated, or requested a callback to a human agent.",
          "summaryPlan": "Summarize: (1) the customer issue, (2) the solution provided, (3) customer sentiment (positive/neutral/negative), and (4) any follow-up action needed.",
          "callInsightPlan": {
            "issueResolved": {
              "type": "boolean",
              "description": "Was the customer issue fully resolved during the call?",
              "required": true
            },
            "escalationRequested": {
              "type": "boolean",
              "description": "Did the customer ask to speak with a human agent?",
              "required": true
            },
            "customerSentiment": {
              "type": "string",
              "description": "Overall customer sentiment at end of call",
              "required": true,
              "enum": ["positive", "neutral", "negative"]
            }
          }
        }
      }

      ```


      ### Example — Appointment Booking


      ```json

      {
        "analysisPlan": {
          "successCriteriaPlan": "Return true ONLY if an appointment was confirmed with a specific date and time agreed by both parties. Return false for all other outcomes.",
          "summaryPlan": "Summarize: the appointment date, time, service type, and any special instructions the customer provided.",
          "callInsightPlan": {
            "appointmentBooked": {
              "type": "boolean",
              "description": "Was an appointment successfully booked?",
              "required": true
            },
            "appointmentDate": {
              "type": "string",
              "description": "The confirmed appointment date (format: YYYY-MM-DD)",
              "required": false
            }
          }
        }
      }

      ```


      ---


      ## Inbound Calls


      To handle inbound calls, assign a telephony number to `telephony.inbound`.
      When a customer calls that number, the assistant answers automatically.


      ```json

      {
        "telephony": {
          "inbound": "6700a1b2c3d4e5f600000111",
          "outbound": "6700a1b2c3d4e5f600000222"
        }
      }

      ```


      > Each inbound number can only be assigned to **one** assistant at a time.
      Assigning it to a new assistant automatically removes it from the previous
      one.
  - name: Knowledge Base
    description: >
      Upload documents so your assistant can answer questions from its own
      knowledge during a call (RAG — Retrieval-Augmented Generation).


      **Supported file types:** PDF, TXT, DOCX, Markdown

      **Max file size:** 100 MB

      **Max chunk size:** 10 MB per chunk


      ---


      ## Upload Flow (3 steps)


      Files are uploaded in chunks to handle network interruptions gracefully.


      ### Step 1 — Start an upload session


      ```bash

      curl -X POST
      https://api.voice-agents.miraiminds.co/v1/knowledge-base/upload/start \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "workspace: YOUR_WORKSPACE_ID" \
        -H "Content-Type: application/json" \
        -d '{
          "fileName": "product-catalog.pdf",
          "totalChunks": 1,
          "fileSize": 524288,
          "mimeType": "application/pdf"
        }'
      ```


      **Response:**

      ```json

      { "message": "Upload session created successfully.", "sessionId":
      "sess_abc123xyz" }

      ```


      ### Step 2 — Upload each chunk


      Repeat for each chunk (start at `chunkIndex: 0`):


      ```bash

      curl -X POST
      https://api.voice-agents.miraiminds.co/v1/knowledge-base/upload/chunk/sess_abc123xyz
      \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "workspace: YOUR_WORKSPACE_ID" \
        -F "chunk=@product-catalog.pdf" \
        -F "chunkIndex=0"
      ```


      **Response:**

      ```json

      { "message": "Chunk uploaded successfully." }

      ```


      ### Step 3 — Complete the upload


      ```bash

      curl -X POST
      https://api.voice-agents.miraiminds.co/v1/knowledge-base/upload/complete/sess_abc123xyz
      \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "workspace: YOUR_WORKSPACE_ID"
      ```


      **Response:**

      ```json

      {
        "message": "Upload completed. Processing has started in the background.",
        "sessionId": "sess_abc123xyz",
        "knowledgeBaseId": "6701a1b2c3d4e5f600000050",
        "knowledgeBaseStatus": "processing"
      }

      ```


      Processing is asynchronous. Poll `GET
      /v1/knowledge-base/files/{knowledgeBaseId}` until `status` is `ready`,
      then link the file to your assistant.


      ---


      ## What to Write in systemPrompt to Trigger Knowledge Base Retrieval


      ```

      You are a support agent for Acme.


      When a customer asks about products, pricing, policies, or shipping:

      1. Search the knowledge base first.

      2. Answer using only information found in the knowledge base.

      3. If the answer is not in the knowledge base, say:
         "I don't have that detail right now — let me connect you with a specialist."

      Never make up information. Always be accurate.

      ```
  - name: Telephony
    description: >
      Manage phone numbers for outbound and inbound calls.


      - **Outbound**: caller ID used when the assistant places a call to a
      customer

      - **Inbound**: the number customers dial to reach the assistant


      ---


      ## Using an Existing (Auto-Assigned) Number


      Every new workspace gets a default telephony number assigned automatically
      in production. Retrieve it and assign it to your assistant's
      `telephony.outbound` or `telephony.inbound`.


      ---


      ## Purchasing a New Number and Assigning to an Assistant


      ### Step 1 — Search available numbers


      ```bash

      curl
      "https://api.voice-agents.miraiminds.co/v1/number-pool/search?countryCode=US&numberType=local&limit=5"
      \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "organization: YOUR_ORG_ID"
      ```


      **Response:**

      ```json

      {
        "data": [
          { "number": "+14155550101", "countryCode": "US", "numberType": "local", "monthlyRateCents": 100 },
          { "number": "+14155550102", "countryCode": "US", "numberType": "local", "monthlyRateCents": 100 }
        ]
      }

      ```


      ### Step 2 — Purchase a number


      ```bash

      curl -X POST
      https://api.voice-agents.miraiminds.co/v1/number-pool/purchase \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "organization: YOUR_ORG_ID" \
        -H "Content-Type: application/json" \
        -d '{
          "number": "+14155550101",
          "countryCode": "US",
          "numberType": "local"
        }'
      ```


      **Response** (contains `_id` for use in assistant `telephony`):

      ```json

      {
        "data": {
          "_id": "6700a1b2c3d4e5f600000111",
          "number": "+14155550101",
          "status": "active"
        }
      }

      ```


      ### Step 3 — Assign to an assistant


      Use the `_id` from Step 2:


      ```bash

      curl -X PUT
      https://api.voice-agents.miraiminds.co/v1/admin/assistant/update/YOUR_ASSISTANT_ID
      \
        -H "x-public-key: YOUR_PUBLIC_KEY" \
        -H "x-private-key: YOUR_PRIVATE_KEY" \
        -H "workspace: YOUR_WORKSPACE_ID" \
        -H "Content-Type: application/json" \
        -d '{
          "telephony": {
            "inbound": "6700a1b2c3d4e5f600000111",
            "outbound": "6700a1b2c3d4e5f600000222"
          }
        }'
      ```


      > **Inbound exclusivity**: Each inbound number can only be held by one
      assistant at a time. Assigning it to a new assistant automatically removes
      it from the previous one.
  - name: Call
    description: >
      ## Outbound Calls


      Use `POST /v2/call/initiate` to trigger an outbound call to a customer.
      The assistant calls the number, runs the conversation, and fires webhook
      events to your `callbackUrl`.


      ---


      ## Inbound Calls


      Assign a telephony number to `telephony.inbound` on an assistant. When a
      customer dials that number, the assistant picks up automatically. No API
      call required — just the number assignment.


      ```

      Customer dials +14155550101
          → Number is linked to "Acme Support" assistant
          → Assistant picks up and follows its systemPrompt
          → Call events fire to your callbackUrl (if configured)
      ```


      ---


      ## Webhook Events Reference


      Register a `callbackUrl` on `POST /v2/call/initiate` to receive real-time
      call events.


      ### Event Payload Shape


      ```json

      {
        "event": {
          "type": "<event-type>",
          "data": { ... }
        }
      }

      ```


      ### Call Lifecycle Events


      | Event | When | What to do |

      |-------|------|-----------|

      | `call.initiate` | Call has been queued | Log that the call started |

      | `call.in-progress` | Customer answered, conversation started | Start
      session timer |

      | `call.ended` | Call hung up, analysis running | Update call record to
      pending |

      | `call.completed` | Call done + analysis complete | Read
      `analysis.success` and `analysis.summary` |

      | `call.timeout` | Call exceeded `maxCallDuration` | Flag for manual
      review |

      | `call.failed` | Network/telephony error | Retry or alert your team |

      | `call.busy` | Customer line was busy | Schedule retry |

      | `call.no-answer` | Rang with no answer | Schedule retry |

      | `call.skip` | Call skipped (outside allowed hours, etc.) | Log and
      continue |

      | `call.rescheduled` | Customer asked to be called back | Wait for next
      attempt |

      | `call.aborted` | Call cancelled via `/v2/call/abort` | Stop tracking |

      | `call.validation-failed` | Payload validation failed before calling |
      Fix payload and resubmit |

      | `call.lifecycle-ended` | All retries exhausted — call is permanently
      done | Final status update |

      | `end-of-call` | Same as `call.completed` with full analysis included |
      Primary event for reading results |

      | `action` | Assistant triggered a business action mid-call | Execute the
      action in your system |


      ### `end-of-call` Payload Example


      ```json

      {
        "event": {
          "type": "end-of-call",
          "data": {
            "call": {
              "id": "call_6701abc123",
              "status": "completed",
              "startedAt": "2026-06-30T10:00:00.000Z",
              "endedAt": "2026-06-30T10:05:32.000Z",
              "durationSeconds": 332,
              "recordingUrl": "https://storage.miraiminds.co/.../recording.wav",
              "detailUrl": "https://app.miraiminds.co/calls/call_6701abc123"
            },
            "analysis": {
              "success": true,
              "summary": "Customer called about a delayed order. Issue resolved — package was confirmed dispatched. Customer was satisfied.",
              "insights": {
                "issueResolved": true,
                "escalationRequested": false,
                "customerSentiment": "positive"
              }
            },
            "credits": {
              "used": 2.5,
              "available": 97.5
            }
          }
        }
      }

      ```


      ### `action` Event Payload Example


      ```json

      {
        "event": {
          "type": "action",
          "data": {
            "action": "create_order",
            "call": { "id": "call_6701abc123" },
            "payload": {
              "email": "alex@example.com",
              "phone": "+14155550200",
              "lineItems": [{ "title": "Blue Sneakers", "quantity": 1 }],
              "cartTotal": 99.99
            }
          }
        }
      }

      ```


      **Available action types:** `create_order`, `send_whatsapp`,
      `mark_prepaid`, `update_address`, `confirmed_address`
  - name: Setting
    description: Platform health and maintenance status.
  - name: Organization
    description: Archive and unarchive organizations and workspaces.
  - name: Voice Gallery
    description: List available AI voices for use in assistant configuration.
  - name: Showcase
    description: Real call recordings and use-case flow demos.
paths:
  /v1/knowledge-base/upload/start:
    post:
      tags:
        - Knowledge Base
      summary: Start Knowledge Base Upload Session
      description: >
        Creates an upload session for a new knowledge base document. Returns a
        `sessionId` used for the subsequent chunk upload and complete calls.


        **Supported MIME types:** `application/pdf`, `text/plain`,
        `application/vnd.openxmlformats-officedocument.wordprocessingml.document`,
        `text/markdown`


        **Max file size:** 100 MB | **Max chunk size:** 10 MB
      operationId: startKnowledgeBaseUpload
      parameters:
        - $ref: '#/components/parameters/PublicKeyHeader'
        - $ref: '#/components/parameters/PrivateKeyHeader'
        - $ref: '#/components/parameters/WorkspaceHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartUploadSessionRequest'
            example:
              fileName: product-catalog.pdf
              totalChunks: 1
              fileSize: 524288
              mimeType: application/pdf
      responses:
        '201':
          description: Upload session created
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Upload session created successfully.
                  sessionId:
                    type: string
                    example: sess_abc123xyz
              example:
                message: Upload session created successfully.
                sessionId: sess_abc123xyz
        '400':
          description: File size exceeds 100 MB limit or MIME type not supported
components:
  parameters:
    PublicKeyHeader:
      name: x-public-key
      in: header
      required: true
      schema:
        type: string
    PrivateKeyHeader:
      name: x-private-key
      in: header
      required: true
      schema:
        type: string
    WorkspaceHeader:
      name: workspace
      in: header
      required: true
      schema:
        type: string
  schemas:
    StartUploadSessionRequest:
      type: object
      required:
        - fileName
        - totalChunks
        - fileSize
      properties:
        fileName:
          type: string
          maxLength: 255
          description: Original filename including extension.
          example: product-catalog.pdf
        totalChunks:
          type: integer
          minimum: 1
          maximum: 1000
          description: >-
            Total number of chunks the file will be split into. Use 10 MB per
            chunk as the target size.
          example: 1
        fileSize:
          type: integer
          minimum: 1
          description: 'Total file size in bytes. Maximum: 104857600 (100 MB).'
          example: 524288
        mimeType:
          type: string
          description: >
            MIME type of the file. Supported values: `application/pdf`,
            `text/plain`,
            `application/vnd.openxmlformats-officedocument.wordprocessingml.document`,
            `text/markdown`.
          example: application/pdf
  securitySchemes:
    PublicKeyAuth:
      type: apiKey
      in: header
      name: x-public-key
    PrivateKeyAuth:
      type: apiKey
      in: header
      name: x-private-key

````