Reserves a document slot on the contact — and the declared bytes against your company’s contact-document storage — and returns a presigned URL to upload the file to. The file never passes through this API.
POST this endpoint with the file’s name, MIME type and size.
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.
POST /contacts/{id}/documents/{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 both the slot and the bytes they reserved.
A contact holds at most 5 uploaded documents. The company’s total contact-document storage is capped by its plan; a request that would exceed it is refused with a 400 naming the bytes in use, the ceiling and the size requested.
This endpoint has a lower rate limit than the rest of the API.
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.
Plan-tiered; the 400 names the figures when exceeded
Upload URL validity
15 minutes
Unfinished uploads reclaimed after
24 hours
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:
Contact document storage limit reached for this company: 248MB of 250MB in use, and this file needs 3MB more.Delete contact documents or upgrade the plan.
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.
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.
Maximum bytes the stored object may have. A larger file is rejected at completion and deleted.
Example:
20971520
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"InstaView API","colors":{"primary":"#2741F9","light":"#4D5FFF","dark":"#1D34C4"},"logo":{"light":"https://mintcdn.com/instaview/srYC_WLR3UAwt0PY/logo/light.svg?fit=max\u0026auto=format\u0026n=srYC_WLR3UAwt0PY\u0026q=85\u0026s=a941bc948e20b3503a55e49b4438bfd8","dark":"https://mintcdn.com/instaview/srYC_WLR3UAwt0PY/logo/dark.svg?fit=max\u0026auto=format\u0026n=srYC_WLR3UAwt0PY\u0026q=85\u0026s=fbf32075feea3b5f404b1aef04c449ea"},"favicon":"https://mintcdn.com/instaview/srYC_WLR3UAwt0PY/favicon.svg?fit=max\u0026auto=format\u0026n=srYC_WLR3UAwt0PY\u0026q=85\u0026s=1499b591dcea46419afceafb5b77004e","api":{"playground":{}},"navbar":{"links":[{"href":"https://support.instaview.sk","label":"Support"}],"primary":{"type":"button","label":"Dashboard","href":"https://app.instaview.sk"}},"footer":{"socials":{"github":"https://github.com/StarIC-s-r-o","linkedin":"https://www.linkedin.com/company/instaviewai"}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"instaview","hasAudioNarration":false,"actualSubdomain":"instaview","customDomains":["docs.instaview.sk"],"gitSource":{"type":"github","owner":"staric-s-r-o","repo":"instaview","deployBranch":"main","contentDirectory":"apps/docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6adb630a25769d6ebcdc21d7","collectionId":"9e3238e9-e795-4633-9eb1-2fa50fb2b100","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6adb630a25769d6ebcdc21d7"},"entitlements":{},"buildId":"6adb630a25769d6ebcdc21d7","clientVersion":"0.0.3965","searchFilterCounts":[{"language":"default","tag":"API Reference","count":75},{"language":"default","tag":"Documentation","count":20},{"language":"default","tag":"Changelog","count":13},{"language":"default","tag":"Runs","count":10},{"language":"default","tag":"2026","count":10},{"language":"default","tag":"Resources","count":9},{"language":"default","tag":"Agents","count":8},{"language":"default","tag":"Conversations","count":8},{"language":"default","tag":"Sourcing","count":8},{"language":"default","tag":"Webhooks","count":7}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/contacts/documents/start-upload","slug":"/api-reference/contacts/documents/start-upload","pageMetadata":{"title":"Start Contact Document Upload","openapi":"POST /contacts/{id}/documents/uploads","description":"Reserves a document slot on the contact — and the declared bytes against your company's contact-document storage — and returns a presigned URL to upload the file to. The file never passes through this API.\n\n1. `POST` this endpoint with the file's name, MIME type and size.\n2. `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.\n3. `POST /contacts/{id}/documents/{documentId}/complete` to confirm the upload.\n\nThe 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 both the slot and the bytes they reserved.\n\nA contact holds at most 5 uploaded documents. The company's total contact-document storage is capped by its plan; a request that would exceed it is refused with a `400` naming the bytes in use, the ceiling and the size requested.\n\nThis endpoint has a lower rate limit than the rest of the API.","href":"/api-reference/contacts/documents/start-upload"},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n li: \"li\",\n ol: \"ol\",\n p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"Reserves a document slot on the contact — and the declared bytes against your company’s contact-document storage — and returns a presigned URL to upload the file to. The file never passes through this API.\"\n }), \"\\n\", _jsxs(_components.ol, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"POST\"\n }), \" this endpoint with the file’s name, MIME type and size.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"PUT\"\n }), \" the raw file bytes to the returned \", _jsx(_components.code, {\n children: \"uploadUrl\"\n }), \", sending \", _jsx(_components.code, {\n children: \"Content-Type\"\n }), \" exactly as returned in \", _jsx(_components.code, {\n children: \"contentType\"\n }), \". Do \", _jsx(_components.strong, {\n children: \"not\"\n }), \" send your API key with this request — the URL carries its own authorisation.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"POST /contacts/{id}/documents/{documentId}/complete\"\n }), \" to confirm the upload.\"]\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The document stays \", _jsx(_components.code, {\n children: \"PENDING\"\n }), \", 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 both the slot and the bytes they reserved.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"A contact holds at most 5 uploaded documents. The company’s total contact-document storage is capped by its plan; a request that would exceed it is refused with a \", _jsx(_components.code, {\n children: \"400\"\n }), \" naming the bytes in use, the ceiling and the size requested.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: \"This endpoint has a lower rate limit than the rest of the API.\"\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Info,Note,Step,Steps,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Info)_missingMdxReference(`Info`,true);if(!Note)_missingMdxReference(`Note`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`Reserves a document slot on a contact and returns a presigned URL to upload the file to.`}),`\n`,_jsx(Heading,{level:`2`,id:`overview`,children:`Overview`}),`\n`,_jsxs(_components.p,{children:[`The same three-step flow as an `,_jsx(_components.a,{href:`/api-reference/agents/knowledge/start-upload`,children:`agent knowledge upload`}),`, because the file bytes go straight to storage and never pass through this API.`]}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Reserve a slot`,children:[_jsxs(_components.p,{children:[_jsx(_components.code,{children:`POST /contacts/{id}/documents/uploads`}),` with the file’s name, MIME type and size. You get back a `,_jsx(_components.code,{children:`documentId`}),` and an `,_jsx(_components.code,{children:`uploadUrl`}),`.`]}),_jsx(Note,{children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`sizeBytes`}),` must be the file’s `,_jsx(_components.strong,{children:`exact`}),` byte count. It is signed into the upload URL, and it is\nalso what is reserved against your company’s contact-document storage — so a larger file is\nrefused at completion, not quietly admitted.`]})})]}),_jsxs(Step,{title:`Upload the file`,children:[_jsxs(_components.p,{children:[_jsx(_components.code,{children:`PUT`}),` the raw file bytes to `,_jsx(_components.code,{children:`uploadUrl`}),`, sending `,_jsx(_components.code,{children:`Content-Type`}),` exactly as returned in `,_jsx(_components.code,{children:`contentType`}),`.`]}),_jsx(Warning,{children:_jsxs(_components.p,{children:[`Do `,_jsx(_components.strong,{children:`not`}),` send your API key with this request. The upload URL carries its own authorisation.`]})})]}),_jsx(Step,{title:`Complete the upload`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`POST /contacts/{id}/documents/{documentId}/complete`}),`. The stored file is verified, and only then does the document become usable on calls.`]})})]}),`\n`,_jsx(Heading,{level:`2`,id:`example`,children:`Example`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`19`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`19`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# 1. Reserve a slot`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -X`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` POST`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://api.instaview.sk/contacts/`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$CONTACT_ID`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`/documents/uploads`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Authorization: Bearer `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$INSTAVIEW_API_KEY`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Content-Type: application/json\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -d`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"fileName\": \"cover-letter.pdf\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"mimeType\": \"application/pdf\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"sizeBytes\": 482133,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"title\": \"Cover letter\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` }'`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# 2. Upload the bytes (no API key on this request)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -X`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` PUT`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$UPLOAD_URL`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Content-Type: application/pdf\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --data-binary`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @cover-letter.pdf`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# 3. Confirm`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -X`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` POST`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://api.instaview.sk/contacts/`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$CONTACT_ID`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`/documents/`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$DOCUMENT_ID`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`/complete`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Authorization: Bearer `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$INSTAVIEW_API_KEY`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`supported-file-types`,children:`Supported File Types`}),`\n`,_jsx(_components.p,{children:`PDF, DOC, DOCX, TXT, MD, CSV, TSV, JSON, XML and YAML — the same set as agent knowledge.`}),`\n`,_jsx(Heading,{level:`2`,id:`limits`,children:`Limits`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Limit`}),_jsx(_components.th,{children:`Value`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Maximum file size`}),_jsx(_components.td,{children:`20 MiB (20,971,520 bytes)`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Uploaded documents per contact`}),_jsxs(_components.td,{children:[`5 (the `,_jsx(_components.code,{children:`CV`}),` document does not count)`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Contact-document storage per company`}),_jsxs(_components.td,{children:[`Plan-tiered; the `,_jsx(_components.code,{children:`400`}),` names the figures when exceeded`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Upload URL validity`}),_jsx(_components.td,{children:`15 minutes`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Unfinished uploads reclaimed after`}),_jsx(_components.td,{children:`24 hours`})]})]})]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[`Both the slot and the bytes are `,_jsx(_components.strong,{children:`reserved`}),` the moment this call succeeds, pending uploads included.\nThat is what stops several parallel requests from each passing the same check. An abandoned upload\nreleases both automatically after 24 hours — or immediately, if you `,_jsx(_components.code,{children:`DELETE`}),` the document.`]})}),`\n`,_jsxs(_components.p,{children:[`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 `,_jsx(_components.code,{children:`400`}),` of the form:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`3`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Contact document storage limit reached for this company: 248MB of 250MB in use, and this file needs 3MB more.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Delete contact documents or upgrade the plan.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`2`,id:`rate-limiting`,children:`Rate Limiting`}),`\n`,_jsxs(_components.p,{children:[`Shares the agent knowledge upload limit: `,_jsx(_components.strong,{children:`6 requests per minute and 60 per hour`}),` per API key for this endpoint, with completion limited separately and more generously. A `,_jsx(_components.code,{children:`429`}),` carries a `,_jsx(_components.code,{children:`Retry-After`}),` header.`]}),`\n`,_jsx(Heading,{level:`2`,id:`error-scenarios`,children:`Error Scenarios`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`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`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`404 Not Found`}),`: No contact with that id belongs to your API key’s company`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`429 Too Many Requests`}),`: Upload rate limit exceeded — wait for `,_jsx(_components.code,{children:`Retry-After`}),` seconds`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`related-resources`,children:`Related Resources`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/api-reference/contacts/documents/complete-upload`,children:`Complete Contact Document Upload`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/api-reference/contacts/documents/list-documents`,children:`List Contact Documents`})}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Start Contact Document Upload","openapi":"POST /contacts/{id}/documents/uploads","description":"Reserves a document slot on the contact — and the declared bytes against your company's contact-document storage — and returns a presigned URL to upload the file to. The file never passes through this API.\n\n1. `POST` this endpoint with the file's name, MIME type and size.\n2. `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.\n3. `POST /contacts/{id}/documents/{documentId}/complete` to confirm the upload.\n\nThe 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 both the slot and the bytes they reserved.\n\nA contact holds at most 5 uploaded documents. The company's total contact-document storage is capped by its plan; a request that would exceed it is refused with a `400` naming the bytes in use, the ceiling and the size requested.\n\nThis endpoint has a lower rate limit than the rest of the API.","href":"/api-reference/contacts/documents/start-upload"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Overview","slug":"overview","depth":2,"children":[]},{"title":"Example","slug":"example","depth":2,"children":[]},{"title":"Supported File Types","slug":"supported-file-types","depth":2,"children":[]},{"title":"Limits","slug":"limits","depth":2,"children":[]},{"title":"Rate Limiting","slug":"rate-limiting","depth":2,"children":[]},{"title":"Error Scenarios","slug":"error-scenarios","depth":2,"children":[]},{"title":"Related Resources","slug":"related-resources","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"description":"Reserves a document slot on the contact — and the declared bytes against your company's contact-document storage — and returns a presigned URL to upload the file to. The file never passes through this API.\n\n1. `POST` this endpoint with the file's name, MIME type and size.\n2. `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.\n3. `POST /contacts/{id}/documents/{documentId}/complete` to confirm the upload.\n\nThe 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 both the slot and the bytes they reserved.\n\nA contact holds at most 5 uploaded documents. The company's total contact-document storage is capped by its plan; a request that would exceed it is refused with a `400` naming the bytes in use, the ceiling and the size requested.\n\nThis endpoint has a lower rate limit than the rest of the API.","operationId":"PublicContactDocumentsController_requestUpload_v1","parameters":["d09d303d-52f0-4532-a76d-836f6e89f2ee","f1576827-e4c5-438d-a464-7f1043cc5db6"],"requestBody":"ffcb717a-e772-4a7f-b52a-81191b1f5d06","responses":{"201":"9e59d309-c92b-4d0c-977a-9a10e5ca0e00","400":"f344a8ba-59a1-4e25-8b6e-350e072fdb97","404":"362c0481-4d6e-4c02-b7fa-3b39c9efc688","429":"2f16c433-3d91-4c5f-aeea-b3842b677ab0"},"security":["e78aef83-63b8-4c2b-b0bd-95910287eaae"],"summary":"Start a contact document upload","tags":["Contacts"],"method":"post","type":"path","servers":["fefe9da2-a252-4644-8424-0eaff357a7a8"],"path":"/contacts/{id}/documents/uploads","baseUrlOptions":["https://api.instaview.sk"],"title":"Start a contact document upload","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"d09d303d-52f0-4532-a76d-836f6e89f2ee":{"name":"id","required":true,"in":"path","description":"Contact the document belongs to.","schema":{"type":"string","format":"uuid","isRequired":true,"description":"Contact the document belongs to.","uniqueKey":"","typeLabel":"string\u003cuuid>"}},"f1576827-e4c5-438d-a464-7f1043cc5db6":{"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","isRequired":false,"description":"Required for ATS API keys to specify which company to access. Ignored for standard company API keys.","uniqueKey":"","typeLabel":"string"}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"fileName":{"type":"string","maxLength":255,"example":"benefits-and-perks.pdf","description":"Name of the file being uploaded, including its extension.","isRequired":true,"uniqueKey":"fileName","typeLabel":"string"},"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.","isRequired":true,"uniqueKey":"mimeType","typeLabel":"enum\u003cstring>"},"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.","isRequired":true,"uniqueKey":"sizeBytes","typeLabel":"integer"},"title":{"type":"string","maxLength":255,"example":"Benefits and perks","description":"Human-readable label for the document. Defaults to `fileName`.","uniqueKey":"title","typeLabel":"string"}},"required":["fileName","mimeType","sizeBytes"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"fileName":"benefits-and-perks.pdf","mimeType":"application/pdf","sizeBytes":482133,"title":"Benefits and perks"}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"9e59d309-c92b-4d0c-977a-9a10e5ca0e00":{"description":"Slot and bytes reserved, upload URL issued","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"object","description":"The reserved document, in PENDING state until the upload is completed.","required":["id","title","status","isActive","source","createdAt"],"properties":{"id":{"type":"string","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000","description":"Document ID","isRequired":true,"uniqueKey":"document.id","typeLabel":"string\u003cuuid>"},"title":{"type":"string","example":"Benefits and perks","description":"Human-readable label for the document","isRequired":true,"uniqueKey":"document.title","typeLabel":"string"},"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.","isRequired":true,"uniqueKey":"document.status","typeLabel":"enum\u003cstring>"},"isActive":{"type":"boolean","example":true,"description":"Whether the agent may consult this document during a call. Always false while the upload is PENDING.","isRequired":true,"uniqueKey":"document.isActive","typeLabel":"boolean"},"source":{"type":"string","enum":["UPLOAD","CV"],"example":"UPLOAD","description":"`UPLOAD` for a file attached through the API or the dashboard. `CV` for the document the platform produces from a contact's processed CV (contacts only); a `CV` document can be deactivated but not renamed or deleted. Always `UPLOAD` on an agent's knowledge base.","isRequired":true,"uniqueKey":"document.source","typeLabel":"enum\u003cstring>"},"createdAt":{"format":"date-time","type":"string","example":"2026-08-08T10:15:00.000Z","description":"When the document was created","isRequired":true,"uniqueKey":"document.createdAt","typeLabel":"string\u003cdate-time>"},"fileName":{"type":"string","example":"benefits-and-perks.pdf","description":"Original file name as uploaded","uniqueKey":"document.fileName","typeLabel":"string"},"mimeType":{"type":"string","example":"application/pdf","description":"MIME type of the stored file","uniqueKey":"document.mimeType","typeLabel":"string"},"sizeBytes":{"type":"number","example":482133,"description":"Size of the stored file in bytes, as verified against storage. Absent until the upload is READY.","uniqueKey":"document.sizeBytes","typeLabel":"number"}},"isRequired":true,"uniqueKey":"document","typeLabel":"object"},"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.","isRequired":true,"uniqueKey":"uploadUrl","typeLabel":"string"},"uploadMethod":{"type":"string","enum":["PUT"],"example":"PUT","description":"HTTP method the upload URL expects.","isRequired":true,"uniqueKey":"uploadMethod","typeLabel":"enum\u003cstring>"},"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.","isRequired":true,"uniqueKey":"contentType","typeLabel":"string"},"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.","isRequired":true,"uniqueKey":"expiresAt","typeLabel":"string\u003cdate-time>"},"maxBytes":{"type":"number","example":20971520,"description":"Maximum bytes the stored object may have. A larger file is rejected at completion and deleted.","isRequired":true,"uniqueKey":"maxBytes","typeLabel":"number"}},"required":["document","uploadUrl","uploadMethod","contentType","expiresAt","maxBytes"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"document":{"id":"123e4567-e89b-12d3-a456-426614174000","title":"Benefits and perks","status":"READY","isActive":true,"source":"UPLOAD","createdAt":"2026-08-08T10:15:00.000Z","fileName":"benefits-and-perks.pdf","mimeType":"application/pdf","sizeBytes":482133},"uploadUrl":"https://instaview-agent-knowledge-production.s3.eu-central-1.amazonaws.com/agent-knowledge/...","uploadMethod":"PUT","contentType":"application/pdf","expiresAt":"2026-08-08T10:30:00.000Z","maxBytes":20971520}}},"exampleType":"generated"}},"exampleType":"generated"},"f344a8ba-59a1-4e25-8b6e-350e072fdb97":{"description":"Unsupported file type, a size over the limit, the contact already holds 5 documents, or the company is at its contact-document storage limit (the message names the figures).","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"362c0481-4d6e-4c02-b7fa-3b39c9efc688":{"description":"No contact with that id belongs to the API key's company.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"2f16c433-3d91-4c5f-aeea-b3842b677ab0":{"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.","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}}},"security":{"e78aef83-63b8-4c2b-b0bd-95910287eaae":{"bearer":{"type":"http","scheme":"bearer","description":"API key for authentication using Bearer scheme","scopes":[],"schemeName":"bearer"}}},"servers":{"fefe9da2-a252-4644-8424-0eaff357a7a8":{"url":"https://api.instaview.sk","description":"Production API Gateway"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","description":"API key for authentication using Bearer scheme","scopes":[],"schemeName":"bearer"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"API key for authentication using Bearer scheme","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearer","name":"Authorization"}],"title":"bearer"}]},"originalFileLocation":"api-reference/openapi.json"},"subdomain":"instaview","siteName":"InstaView API","title":"Start Contact Document Upload - InstaView API","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-06T20:17:57.355Z","originalFileLocation":"api-reference/contacts/documents/start-upload.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Reserves a document slot on the contact — and the declared bytes against your company\u0026#x27;s contact-document storage — and returns a presigned URL to upload the file to. The file never passes through this API. 1. POST this endpoint with the file\u0026#x27;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 /contacts/{id}/documents/{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 both the slot and the bytes they reserved. A contact holds at most 5 uploaded documents. The company\u0026#x27;s total contact-document storage is capped by its plan; a request that would exceed it is refused with a 400 naming the bytes in use, the ceiling and the size requested. This endpoint has a lower rate limit than the rest of the API.\">\u003cmeta data-mint-head name=\"application-name\" content=\"InstaView API\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Start Contact Document Upload - InstaView API\">\u003cmeta data-mint-head property=\"og:description\" content=\"Reserves a document slot on the contact — and the declared bytes against your company\u0026#x27;s contact-document storage — and returns a presigned URL to upload the file to. The file never passes through this API. 1. POST this endpoint with the file\u0026#x27;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 /contacts/{id}/documents/{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 both the slot and the bytes they reserved. A contact holds at most 5 uploaded documents. The company\u0026#x27;s total contact-document storage is capped by its plan; a request that would exceed it is refused with a 400 naming the bytes in use, the ceiling and the size requested. This endpoint has a lower rate limit than the rest of the API.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"InstaView API\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://instaview.mintlify.app/_mintlify/api/og/v2?division=Contact+Documents\u0026amp;title=Start+Contact+Document+Upload\u0026amp;description=Reserves+a+document+slot+on+the+contact+%E2%80%94+and+the+declared+bytes+against+your+company%27s+contact-document+storage+%E2%80%94+and+returns+a+presigned+URL+to+upload+the+fil\u0026amp;theme=1444b1b95306a409923bc3c0\u0026amp;signature=349fa7f694e02f7fe419466652209e4a16f407177b40ee59d561901ed78a1540\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Start Contact Document Upload - InstaView API\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Reserves a document slot on the contact — and the declared bytes against your company\u0026#x27;s contact-document storage — and returns a presigned URL to upload the file to. The file never passes through this API. 1. POST this endpoint with the file\u0026#x27;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 /contacts/{id}/documents/{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 both the slot and the bytes they reserved. A contact holds at most 5 uploaded documents. The company\u0026#x27;s total contact-document storage is capped by its plan; a request that would exceed it is refused with a 400 naming the bytes in use, the ceiling and the size requested. This endpoint has a lower rate limit than the rest of the API.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://instaview.mintlify.app/_mintlify/api/og/v2?division=Contact+Documents\u0026amp;title=Start+Contact+Document+Upload\u0026amp;description=Reserves+a+document+slot+on+the+contact+%E2%80%94+and+the+declared+bytes+against+your+company%27s+contact-document+storage+%E2%80%94+and+returns+a+presigned+URL+to+upload+the+fil\u0026amp;theme=1444b1b95306a409923bc3c0\u0026amp;signature=349fa7f694e02f7fe419466652209e4a16f407177b40ee59d561901ed78a1540\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/instaview/FzS1-dDCztzdlzmX/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"InstaView API\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#2741F9\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/contacts/documents/start-upload.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.instaview.sk/#organization\",\"name\":\"InstaView API\",\"url\":\"https://docs.instaview.sk\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/instaview/srYC_WLR3UAwt0PY/logo/light.svg?fit=max\u0026auto=format\u0026n=srYC_WLR3UAwt0PY\u0026q=85\u0026s=a941bc948e20b3503a55e49b4438bfd8\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.instaview.sk#website\",\"name\":\"InstaView API\",\"url\":\"https://docs.instaview.sk\",\"publisher\":{\"@id\":\"https://docs.instaview.sk/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload#webpage\",\"url\":\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload\",\"name\":\"Start Contact Document Upload\",\"description\":\"Reserves a document slot on the contact — and the declared bytes against your company's contact-document storage — 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 /contacts/{id}/documents/{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 both the slot and the bytes they reserved. A contact holds at most 5 uploaded documents. The company's total contact-document storage is capped by its plan; a request that would exceed it is refused with a 400 naming the bytes in use, the ceiling and the size requested. This endpoint has a lower rate limit than the rest of the API.\",\"dateModified\":\"2026-09-06T20:17:57.355Z\",\"isPartOf\":{\"@id\":\"https://docs.instaview.sk#website\"},\"breadcrumb\":{\"@id\":\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Contact Documents\",\"item\":\"https://docs.instaview.sk/api-reference/contacts/documents/list-documents\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Start Contact Document Upload\",\"item\":\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload#apireference\",\"headline\":\"Start Contact Document Upload\",\"name\":\"Start Contact Document Upload\",\"description\":\"Reserves a document slot on the contact — and the declared bytes against your company's contact-document storage — 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 /contacts/{id}/documents/{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 both the slot and the bytes they reserved. A contact holds at most 5 uploaded documents. The company's total contact-document storage is capped by its plan; a request that would exceed it is refused with a 400 naming the bytes in use, the ceiling and the size requested. This endpoint has a lower rate limit than the rest of the API.\",\"url\":\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload\",\"mainEntityOfPage\":{\"@id\":\"https://docs.instaview.sk/api-reference/contacts/documents/start-upload#webpage\"},\"dateModified\":\"2026-09-06T20:17:57.355Z\",\"publisher\":{\"@id\":\"https://docs.instaview.sk/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.instaview.sk#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"InstaView API\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"InstaView API","nav":{"global":null,"tabs":[{"tab":"Documentation","icon":"book","pages":[{"title":"Documentation","href":"/introduction"}]},{"tab":"API Reference","icon":"code","groups":[{"group":"Overview","pages":[{"title":"API Reference","href":"/api-reference/introduction"}]},{"group":"Agents","pages":[{"title":"List Agents","openapi":"GET /agents","href":"/api-reference/agents/list-agents"},{"title":"Design an Agent","openapi":"POST /agents/composer","href":"/api-reference/agents/compose-agent"},{"title":"Refine a Composed Agent","openapi":"POST /agents/composer/{sessionId}/messages","href":"/api-reference/agents/refine-agent"},{"title":"Poll a Composer Session","openapi":"GET /agents/composer/{sessionId}","href":"/api-reference/agents/get-composer-session"},{"title":"Create Agent","openapi":"POST /agents","href":"/api-reference/agents/create-agent"},{"title":"Get Agent","openapi":"GET /agents/{id}","href":"/api-reference/agents/get-agent"},{"title":"Update Agent","openapi":"PATCH /agents/{id}","href":"/api-reference/agents/update-agent"},{"title":"Delete Agent","openapi":"DELETE /agents/{id}","href":"/api-reference/agents/delete-agent"}]},{"group":"Agent Knowledge Base","pages":[{"title":"List Knowledge Documents","openapi":"GET /agents/{id}/knowledge","href":"/api-reference/agents/knowledge/list-knowledge"},{"title":"Start Knowledge Upload","openapi":"POST /agents/{id}/knowledge","href":"/api-reference/agents/knowledge/start-upload"},{"title":"Complete Knowledge Upload","openapi":"POST /agents/{id}/knowledge/{documentId}/complete","href":"/api-reference/agents/knowledge/complete-upload"},{"title":"Update Knowledge Document","openapi":"PATCH /agents/{id}/knowledge/{documentId}","href":"/api-reference/agents/knowledge/update-knowledge"},{"title":"Delete Knowledge Document","openapi":"DELETE /agents/{id}/knowledge/{documentId}","href":"/api-reference/agents/knowledge/delete-knowledge"}]},{"group":"Jobs","pages":[{"title":"List Jobs","openapi":"GET /jobs","href":"/api-reference/jobs/list-jobs"},{"title":"Create Job","openapi":"POST /jobs","href":"/api-reference/jobs/create-job"},{"title":"Create Job from URL","openapi":"POST /jobs/url","href":"/api-reference/jobs/create-job-from-url"},{"title":"Get Job","openapi":"GET /jobs/{id}","href":"/api-reference/jobs/get-job"},{"title":"Update Job","openapi":"PATCH /jobs/{id}","href":"/api-reference/jobs/update-job"},{"title":"Delete Job","openapi":"DELETE /jobs/{id}","href":"/api-reference/jobs/delete-job"}]},{"group":"Contacts","pages":[{"title":"List Contacts","openapi":"GET /contacts","href":"/api-reference/contacts/list-contacts"},{"title":"Create Contact","openapi":"POST /contacts","href":"/api-reference/contacts/create-contact"},{"title":"Get Contact","openapi":"GET /contacts/{id}","href":"/api-reference/contacts/get-contact"},{"title":"Update Contact","openapi":"PATCH /contacts/{id}","href":"/api-reference/contacts/update-contact"},{"title":"Delete Contact","openapi":"DELETE /contacts/{id}","href":"/api-reference/contacts/delete-contact"}]},{"group":"Contact Documents","pages":[{"title":"List Contact Documents","openapi":"GET /contacts/{id}/documents","description":"Lists every document on the contact: the processed CV (`source: CV`), completed uploads, and uploads that have not been completed yet (`status: PENDING`).\n\nWhether any of these documents reaches a call is a separate decision: the agent must have `contextConfig.useContactContext` enabled.","href":"/api-reference/contacts/documents/list-documents"},{"title":"Start Contact Document Upload","openapi":"POST /contacts/{id}/documents/uploads","href":"/api-reference/contacts/documents/start-upload"},{"title":"Complete Contact Document Upload","openapi":"POST /contacts/{id}/documents/{documentId}/complete","description":"Confirms the file was uploaded to the presigned URL. The stored object is verified — it must exist, be within the size limit, be no larger than the size declared when the upload was started, and carry the content type the URL was issued for — and only then does the document become usable on calls. A file that fails verification is deleted and its reservation released. Safe to retry: completing an already-completed document returns it unchanged.","href":"/api-reference/contacts/documents/complete-upload"},{"title":"Update Contact Document","openapi":"PATCH /contacts/{id}/documents/{documentId}","href":"/api-reference/contacts/documents/update-document"},{"title":"Delete Contact Document","openapi":"DELETE /contacts/{id}/documents/{documentId}","href":"/api-reference/contacts/documents/delete-document"}]},{"group":"Contact Fields","pages":[{"title":"List Contact Fields","openapi":"GET /contact-fields","href":"/api-reference/contact-fields/list-contact-fields"},{"title":"Create Contact Field","openapi":"POST /contact-fields","href":"/api-reference/contact-fields/create-contact-field"},{"title":"Update Contact Field","openapi":"PATCH /contact-fields/{id}","href":"/api-reference/contact-fields/update-contact-field"},{"title":"Delete Contact Field","openapi":"DELETE /contact-fields/{id}","href":"/api-reference/contact-fields/delete-contact-field"}]},{"group":"Companies","pages":[{"title":"List Companies","openapi":"GET /company","href":"/api-reference/companies/list-companies"},{"title":"Create Company","openapi":"POST /company","href":"/api-reference/companies/create-company"},{"title":"Get Company","openapi":"GET /company/{id}","href":"/api-reference/companies/get-company"},{"title":"Update Company","openapi":"PATCH /company/{id}","href":"/api-reference/companies/update-company"},{"title":"Delete Company","openapi":"DELETE /company/{id}","href":"/api-reference/companies/delete-company"}]},{"group":"Conversations","pages":[{"title":"List Conversations","openapi":"GET /conversations","href":"/api-reference/conversations/list-conversations"},{"title":"Create Conversation","openapi":"POST /conversations","href":"/api-reference/conversations/create-conversation"},{"title":"Get Conversation","openapi":"GET /conversations/{id}","href":"/api-reference/conversations/get-conversation"},{"title":"Get Conversation Analysis PDF","openapi":"GET /conversations/{id}/analysis-pdf","href":"/api-reference/conversations/get-conversation-analysis-pdf"},{"title":"Invoke New Call Attempt","openapi":"POST /conversations/{id}/call-attempts","href":"/api-reference/conversations/invoke-call-attempt"},{"title":"Reschedule Call Attempt","openapi":"PATCH /conversations/{id}/call-attempts/{attemptId}","href":"/api-reference/conversations/reschedule-call-attempt"},{"title":"Delete Call Attempt","openapi":"DELETE /conversations/{id}/call-attempts/{attemptId}","href":"/api-reference/conversations/delete-call-attempt"},{"title":"Delete Conversation","openapi":"DELETE /conversations/{id}","href":"/api-reference/conversations/delete-conversation"}]},{"group":"Runs","pages":[{"title":"Create Run","openapi":"POST /runs","href":"/api-reference/runs/create-run"},{"title":"Get Run","openapi":"GET /runs/{id}","href":"/api-reference/runs/get-run"},{"title":"List Run Conversations","openapi":"GET /runs/{id}/conversations","href":"/api-reference/runs/list-run-conversations"},{"title":"Attach Contacts","openapi":"POST /runs/{id}/contacts","href":"/api-reference/runs/attach-run-contacts"},{"title":"Detach Contact","openapi":"DELETE /runs/{id}/contacts/{contactId}","href":"/api-reference/runs/detach-run-contact"},{"title":"Launch Run","openapi":"POST /runs/{id}/launch","href":"/api-reference/runs/launch-run"},{"title":"Pause Run","openapi":"POST /runs/{id}/pause","href":"/api-reference/runs/pause-run"},{"title":"Resume Run","openapi":"POST /runs/{id}/resume","href":"/api-reference/runs/resume-run"},{"title":"Cancel Run","openapi":"POST /runs/{id}/cancel","href":"/api-reference/runs/cancel-run"},{"title":"Delete Run","openapi":"DELETE /runs/{id}","href":"/api-reference/runs/delete-run"}]},{"group":"Billing","pages":[{"title":"Get Usage Statistics","openapi":"GET /billing/usage","href":"/api-reference/billing/get-usage"}]},{"group":"Voice","pages":[{"title":"Generate Audio","openapi":"POST /voice","href":"/api-reference/voice/generate-audio"}]},{"group":"Webhooks","pages":[{"title":"List Webhooks","api":"GET /webhooks","href":"/api-reference/webhooks/list-webhooks"},{"title":"Create Webhook","api":"POST /webhooks","href":"/api-reference/webhooks/create-webhook"},{"title":"Get Webhook","api":"GET /webhooks/{id}","href":"/api-reference/webhooks/get-webhook"},{"title":"Update Webhook","api":"PATCH /webhooks/{id}","href":"/api-reference/webhooks/update-webhook"},{"title":"Delete Webhook","api":"DELETE /webhooks/{id}","href":"/api-reference/webhooks/delete-webhook"},{"title":"Test Webhook","api":"POST /webhooks/{id}/test","href":"/api-reference/webhooks/test-webhook"},{"title":"Reset Circuit Breaker","api":"POST /webhooks/{id}/reset-circuit","href":"/api-reference/webhooks/reset-circuit"}]},{"group":"Sourcing","pages":[{"title":"Initiate Sourcing Run","openapi":"POST /sourcing","href":"/api-reference/sourcing/initiate-sourcing"},{"title":"Initiate Sourcing Preview Run","openapi":"POST /sourcing/preview","href":"/api-reference/sourcing/initiate-sourcing-preview"},{"title":"Get Sourcing Preview Results","openapi":"GET /sourcing/preview/{id}/results","href":"/api-reference/sourcing/get-sourcing-preview-results"},{"title":"Patch Sourcing Run","openapi":"PATCH /sourcing/{id}","href":"/api-reference/sourcing/patch-sourcing"},{"title":"Get Sourcing Results","openapi":"GET /sourcing/{id}/results","href":"/api-reference/sourcing/get-sourcing-results"},{"title":"Initiate Enrichment Run","openapi":"POST /sourcing/enrich","href":"/api-reference/sourcing/initiate-enrichment"},{"title":"Get Enrichment Results","openapi":"GET /sourcing/enrich/{id}/results","href":"/api-reference/sourcing/get-enrich-results"},{"title":"Render HTML Candidate Cards","openapi":"POST /sourcing/render-html","href":"/api-reference/sourcing/render-html"}]},{"group":"Phone Numbers","pages":[{"title":"List Phone Numbers","openapi":"GET /phone-numbers","href":"/api-reference/phone-numbers/list-phone-numbers"}]}]},{"tab":"Changelog","icon":"clock","pages":[{"title":"Changelog","href":"/changelog/introduction"}]}]},"title":"Start Contact Document Upload - InstaView API","buildId":"dpl_849ArpqvBiCczQiT1Y1stNGpbqHT","deploymentId":"dpl_849ArpqvBiCczQiT1Y1stNGpbqHT","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-Bbp7I60D.js","utils-C3RIvJha.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DqD-vLt8.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-B31Loprg.js","snippetPresets-DKpk-b8t.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-Cj65AhOR.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BXtn5gcC.js","shallow-RY2b03Cp.js","getApiPlaygroundDisplay-B0jeiPk3.js","CodeSnippet-CYgBjjwn.js","CodeSnippets-DOngDrYB.js","Page-n7I5XbKb.js","getPastedJson-DRQbJx-T.js","icon-CQiQCicY.js","MethodPill-BKTLdNtu.js","DuplicateIcon-B9jpAdat.js","createIcon-DCddRrXv.js","DynamicMarkdown-a8hUKrw6.js","SectionHeading-eECVV2eH.js","axios-vUo_bRtp.js","Markdown--GF7ZIpf.js","clsx-DZLdJUrt.js","lib--scc4DXi.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-2LoAhjKH.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-Zwc0ZncM.js"]}