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

# Start Knowledge Upload

> Reserves a document slot on the agent and returns a presigned URL to upload the file to. The file never passes through this API.

1. `POST` this endpoint with the file's name, MIME type and size.
2. `PUT` the raw file bytes to the returned `uploadUrl`, sending `Content-Type` exactly as returned in `contentType`. Do **not** send your API key with this request — the URL carries its own authorisation.
3. `POST /agents/{id}/knowledge/{documentId}/complete` to confirm the upload.

The document stays `PENDING`, and is never used on a call, until step 3 succeeds. Uploads that are never completed are cleaned up automatically after 24 hours and release the slot they held.

This endpoint has a lower rate limit than the rest of the API.

Reserves a slot in an agent's knowledge base and returns a presigned URL to upload the file to.

## Overview

A knowledge base is a set of documents the agent can look up mid-call — a job spec, a benefits summary, a pricing sheet, an FAQ. Attaching one is a three-step flow, because the file bytes go straight to storage and never pass through this API.

<Steps>
  <Step title="Reserve a slot">
    `POST /agents/{id}/knowledge` with the file's name, MIME type and size. You get back a `documentId` and an `uploadUrl`.

    <Note>
      `sizeBytes` must be the file's **exact** byte count, not an estimate. Both it and the MIME type are signed into the upload URL.
    </Note>
  </Step>

  <Step title="Upload the file">
    `PUT` the raw file bytes to `uploadUrl`, sending `Content-Type` exactly as returned in `contentType`.

    <Warning>
      Do **not** send your API key with this request. The upload URL carries its own authorisation, and adding an `Authorization` header will cause storage to reject the upload.
    </Warning>

    Storage rejects the `PUT` with `403` if the `Content-Type` or the `Content-Length` differs from what was signed — so a file whose real size does not match the `sizeBytes` you declared will not upload. Most HTTP clients set `Content-Length` for you from the body.
  </Step>

  <Step title="Complete the upload">
    `POST /agents/{id}/knowledge/{documentId}/complete`. The stored file is verified, and only then does the document become usable on calls.
  </Step>
</Steps>

## Example

```bash theme={null}
# 1. Reserve a slot
curl -X POST https://api.instaview.sk/agents/$AGENT_ID/knowledge \
  -H "Authorization: Bearer $INSTAVIEW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "benefits-and-perks.pdf",
    "mimeType": "application/pdf",
    "sizeBytes": 482133,
    "title": "Benefits and perks"
  }'

# 2. Upload the bytes (no API key on this request)
#    curl sets Content-Length from the file; it must match the sizeBytes you declared.
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/pdf" \
  --data-binary @benefits-and-perks.pdf

# 3. Confirm
curl -X POST https://api.instaview.sk/agents/$AGENT_ID/knowledge/$DOCUMENT_ID/complete \
  -H "Authorization: Bearer $INSTAVIEW_API_KEY"
```

## Supported File Types

PDF, DOC, DOCX, TXT, MD, CSV, TSV, JSON, XML and YAML. Files are stored in the format you upload them in — there is no conversion step, so nothing is lost in translation.

## Limits

| Limit                              | Value                     |
| ---------------------------------- | ------------------------- |
| Maximum file size                  | 20 MiB (20,971,520 bytes) |
| Documents per agent                | 10                        |
| Upload URL validity                | 15 minutes                |
| Unfinished uploads reclaimed after | 24 hours                  |

<Info>
  A reserved slot counts against the per-agent document limit even before the
  file is uploaded. If you abandon an upload, the slot is released automatically
  after 24 hours — or immediately, if you `DELETE` the document.
</Info>

## Rate Limiting

This endpoint has a **lower rate limit than the rest of the API** — 6 requests per minute and 60 per hour, per API key — because each call reserves a document slot and, once completed, a stored file.

A `429` response carries a `Retry-After` header with the number of seconds to wait. Completing an upload is limited separately and more generously, so retrying a failed completion is cheap.

## Error Scenarios

* **400 Bad Request**: Unsupported file type, a size over 20 MB, or the agent already holds 10 documents
* **404 Not Found**: No agent with that id belongs to your API key's company
* **429 Too Many Requests**: Upload rate limit exceeded — wait for `Retry-After` seconds

## Related Resources

* [Complete Knowledge Upload](/api-reference/agents/knowledge/complete-upload)
* [List Knowledge Documents](/api-reference/agents/knowledge/list-knowledge)
* [Agents Guide](/guides/resources/agents)


## OpenAPI

````yaml POST /agents/{id}/knowledge
openapi: 3.0.0
info:
  title: InstaView API
  description: |-
    InstaView API Documentation

    ## Authentication

    All endpoints require API key authentication using Bearer token:
    ```
    Authorization: Bearer sk_your_api_key_here
    ```

    ## API Key Management

    The API Key module provides comprehensive key management for:
    - **Direct Client Keys**: Company-scoped keys for your applications
    - **ATS Partner Keys**: Resource-scoped keys for ATS integrations

    ### Key Features
    - HMAC-SHA256 hashing for API key storage
    - Configurable rate limiting
    - Comprehensive audit logging
    - Company-level isolation
    - Resource scoping for ATS partners
  version: 1.0.0
  contact: {}
servers:
  - url: https://api.instaview.sk
    description: Production API Gateway
security: []
tags: []
paths:
  /agents/{id}/knowledge:
    post:
      tags:
        - Agents
      summary: Start a knowledge base upload
      description: >-
        Reserves a document slot on the agent and returns a presigned URL to
        upload the file to. The file never passes through this API.


        1. `POST` this endpoint with the file's name, MIME type and size.

        2. `PUT` the raw file bytes to the returned `uploadUrl`, sending
        `Content-Type` exactly as returned in `contentType`. Do **not** send
        your API key with this request — the URL carries its own authorisation.

        3. `POST /agents/{id}/knowledge/{documentId}/complete` to confirm the
        upload.


        The document stays `PENDING`, and is never used on a call, until step 3
        succeeds. Uploads that are never completed are cleaned up automatically
        after 24 hours and release the slot they held.


        This endpoint has a lower rate limit than the rest of the API.
      operationId: PublicAgentKnowledgeController_requestUpload_v1
      parameters:
        - name: id
          required: true
          in: path
          description: Agent the knowledge base belongs to.
          schema:
            type: string
            format: uuid
        - name: companyId
          required: false
          in: query
          description: >-
            Required for ATS API keys to specify which company to access.
            Ignored for standard company API keys.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicCreateKnowledgeUploadDto'
      responses:
        '201':
          description: Slot reserved and upload URL issued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicKnowledgeUploadTicketDto'
        '400':
          description: >-
            Unsupported file type, a size over the limit, or the agent already
            holds the maximum number of documents.
        '404':
          description: >-
            No agent with that id belongs to the API key's company. An id that
            exists nowhere and an id that belongs to another company answer
            identically — same status, same body — on purpose, so the response
            cannot be used to tell them apart.
        '429':
          description: >-
            Upload rate limit exceeded. This endpoint has a lower limit than the
            rest of the API — wait for the number of seconds in the
            `Retry-After` header before retrying.
      security:
        - bearer: []
components:
  schemas:
    PublicCreateKnowledgeUploadDto:
      type: object
      properties:
        fileName:
          type: string
          maxLength: 255
          example: benefits-and-perks.pdf
          description: Name of the file being uploaded, including its extension.
        mimeType:
          type: string
          enum:
            - application/pdf
            - application/msword
            - >-
              application/vnd.openxmlformats-officedocument.wordprocessingml.document
            - text/plain
            - text/markdown
            - text/csv
            - text/tab-separated-values
            - application/json
            - application/xml
            - text/xml
            - application/yaml
            - text/yaml
          example: application/pdf
          description: >-
            MIME type of the file. The returned upload URL is signed for this
            exact type, so the PUT must send it back as its `Content-Type`
            header verbatim.
        sizeBytes:
          type: integer
          minimum: 1
          maximum: 20971520
          example: 482133
          description: >-
            Exact size of the file in bytes. This is binding, not an estimate:
            it is signed into the upload URL, so the `PUT` must send precisely
            this many bytes and storage rejects anything else with a 403. Send
            the real byte count of the file you are about to upload; most HTTP
            clients set `Content-Length` for you from the body. Checked again
            against the stored object at completion.
        title:
          type: string
          maxLength: 255
          example: Benefits and perks
          description: Human-readable label for the document. Defaults to `fileName`.
      required:
        - fileName
        - mimeType
        - sizeBytes
    PublicKnowledgeUploadTicketDto:
      type: object
      properties:
        document:
          description: >-
            The reserved document, in PENDING state until the upload is
            completed.
          allOf:
            - $ref: '#/components/schemas/PublicKnowledgeDocumentDto'
        uploadUrl:
          type: string
          example: >-
            https://instaview-agent-knowledge-production.s3.eu-central-1.amazonaws.com/agent-knowledge/...
          description: >-
            Presigned storage URL to PUT the file to. Carries its own
            authorisation — do not send your API key with it.
        uploadMethod:
          type: string
          enum:
            - PUT
          example: PUT
          description: HTTP method the upload URL expects.
        contentType:
          type: string
          example: application/pdf
          description: >-
            The `Content-Type` header the PUT must send. It is part of the URL's
            signature, so any other value is rejected by storage.
        expiresAt:
          format: date-time
          type: string
          example: '2026-08-08T10:30:00.000Z'
          description: >-
            When the upload URL stops working. The document slot outlives it —
            request a new upload if this expires.
        maxBytes:
          type: number
          example: 20971520
          description: >-
            Maximum bytes the stored object may have. A larger file is rejected
            at completion and deleted.
      required:
        - document
        - uploadUrl
        - uploadMethod
        - contentType
        - expiresAt
        - maxBytes
    PublicKnowledgeDocumentDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
          description: Document ID
        title:
          type: string
          example: Benefits and perks
          description: Human-readable label for the document
        fileName:
          type: string
          example: benefits-and-perks.pdf
          description: Original file name as uploaded
        mimeType:
          type: string
          example: application/pdf
          description: MIME type of the stored file
        sizeBytes:
          type: number
          example: 482133
          description: >-
            Size of the stored file in bytes, as verified against storage.
            Absent until the upload is READY.
        status:
          type: string
          enum:
            - PENDING
            - READY
          example: READY
          description: >-
            `PENDING` while waiting for the file to be uploaded to the presigned
            URL and the upload to be completed; `READY` once the file is
            confirmed stored. Only READY documents are attached to calls.
        isActive:
          type: boolean
          example: true
          description: >-
            Whether the agent may consult this document during a call. Always
            false while the upload is PENDING.
        createdAt:
          format: date-time
          type: string
          example: '2026-08-08T10:15:00.000Z'
          description: When the document was created
      required:
        - id
        - title
        - status
        - isActive
        - createdAt
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      description: API key for authentication using Bearer scheme

````