Skip to main content
POST
Start a contact document upload
Reserves a document slot on a contact and returns a presigned URL to upload the file to.

Overview

The same three-step flow as an agent knowledge upload, because the file bytes go straight to storage and never pass through this API.
1

Reserve a slot

POST /contacts/{id}/documents/uploads with the file’s name, MIME type and size. You get back a documentId and an uploadUrl.
sizeBytes must be the file’s exact byte count. It is signed into the upload URL, and it is also what is reserved against your company’s contact-document storage — so a larger file is refused at completion, not quietly admitted.
2

Upload the file

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

Complete the upload

POST /contacts/{id}/documents/{documentId}/complete. The stored file is verified, and only then does the document become usable on calls.

Example

Supported File Types

PDF, DOC, DOCX, TXT, MD, CSV, TSV, JSON, XML and YAML — the same set as agent knowledge.

Limits

Both the slot and the bytes are reserved the moment this call succeeds, pending uploads included. That is what stops several parallel requests from each passing the same check. An abandoned upload releases both automatically after 24 hours — or immediately, if you DELETE the document.
The storage ceiling is per company and per plan. A contact is not a document library, and the aggregate is the number that actually costs money — every byte here is stored and, once the contact is on a call, sent to the voice provider. When a reservation would take the company past its ceiling, the response is a 400 of the form:

Rate Limiting

Shares the agent knowledge upload limit: 6 requests per minute and 60 per hour per API key for this endpoint, with completion limited separately and more generously. A 429 carries a Retry-After header.

Error Scenarios

  • 400 Bad Request: Unsupported file type, a size over 20 MB, the contact already holds 5 documents, or the company is at its storage limit
  • 404 Not Found: No contact with that id belongs to your API key’s company
  • 429 Too Many Requests: Upload rate limit exceeded — wait for Retry-After seconds

Authorizations

Authorization
string
header
required

API key for authentication using Bearer scheme

Path Parameters

id
string<uuid>
required

Contact the document belongs to.

Query Parameters

companyId
string

Required for ATS API keys to specify which company to access. Ignored for standard company API keys.

Body

application/json
fileName
string
required

Name of the file being uploaded, including its extension.

Maximum string length: 255
Example:

"benefits-and-perks.pdf"

mimeType
enum<string>
required

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.

Available options:
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"

sizeBytes
integer
required

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.

Required range: 1 <= x <= 20971520
Example:

482133

title
string

Human-readable label for the document. Defaults to fileName.

Maximum string length: 255
Example:

"Benefits and perks"

Response

Slot and bytes reserved, upload URL issued

document
object
required

The reserved document, in PENDING state until the upload is completed.

uploadUrl
string
required

Presigned storage URL to PUT the file to. Carries its own authorisation — do not send your API key with it.

Example:

"https://instaview-agent-knowledge-production.s3.eu-central-1.amazonaws.com/agent-knowledge/..."

uploadMethod
enum<string>
required

HTTP method the upload URL expects.

Available options:
PUT
Example:

"PUT"

contentType
string
required

The Content-Type header the PUT must send. It is part of the URL's signature, so any other value is rejected by storage.

Example:

"application/pdf"

expiresAt
string<date-time>
required

When the upload URL stops working. The document slot outlives it — request a new upload if this expires.

Example:

"2026-08-08T10:30:00.000Z"

maxBytes
number
required

Maximum bytes the stored object may have. A larger file is rejected at completion and deleted.

Example:

20971520