{
"detail": "You've reached your storage limit of 100 images. Upgrade to store more."
}
{
"detail": "Image with id 3fa85f64-5717-4562-b3fc-2c963f66afa6 not found"
}
upload
Upload an image
Get a microscopy image into HalfPage. How the request is sent decides
which of the two modes you get:
One request: send multipart/form-data with a file part. The file is
streamed to storage and converted before the response returns, so the
returned image is already ready and its id can go straight into
POST /predict. Simplest, and the right choice up to a few hundred MB.
Resumable: send application/json with {"name": ..., "size": ...}
instead of a file. No bytes are sent on this request; the response carries
upload with presigned part URLs. PUT each chunk directly to its url (in
part order), call POST /upload/{image_id}/complete, then poll
GET /upload/{image_id} until upload_status is ready. Use this for
large files or unreliable connections, since an interrupted part can be
retried on its own instead of restarting the whole transfer.
Either way the image counts against your plan’s storage cap, so both modes
return 402 once that cap is reached.
{
"detail": "You've reached your storage limit of 100 images. Upgrade to store more."
}
{
"detail": "Image with id 3fa85f64-5717-4562-b3fc-2c963f66afa6 not found"
}
Authorizations
Authorization
string
header
required
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
multipart/form-dataapplication/json
Send the whole file in one request. The response returns the image already ready.
file
file
required
The microscopy image to upload (TIFF). Up to 4 GB.
Response
The file was stored (upload is null, the image is ready), or a resumable upload was opened (upload carries the presigned plan).
The image the pixels landed on (or will land on).
After a single-request upload upload is null and image.upload_status
is already ready, so the image.id can go straight into POST /predict.
After a resumable upload was opened, upload carries the presigned plan and
image.upload_status is uploading until you complete it.
image
ImageStatusResponse · object
required
An image's upload lifecycle and metadata: enough to know when a freshly
uploaded image is ready to run a prediction against.
The presigned multipart plan: PUT each chunk of the file to its url
(in part order), then call POST /upload/{image_id}/complete. No body is
needed: the server verifies the uploaded parts with storage directly.
The internal storage object key is deliberately not exposed: the presigned
urls already encode everything the client needs, and the key layout is a
server-side implementation detail we keep off the public contract.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"HalfPage API","description":"Programmatic cell segmentation for microscopy images. Upload, predict, and export ROIs and measurements.","colors":{"primary":"#2563eb","light":"#3b82f6","dark":"#1d4ed8"},"logo":{"light":"https://mintcdn.com/halfpage/rhKdEUCb6V98b2yX/logo/light.svg?fit=max\u0026auto=format\u0026n=rhKdEUCb6V98b2yX\u0026q=85\u0026s=667c16283d8ca68ed577d207d7ce5249","dark":"https://mintcdn.com/halfpage/rhKdEUCb6V98b2yX/logo/dark.svg?fit=max\u0026auto=format\u0026n=rhKdEUCb6V98b2yX\u0026q=85\u0026s=9ac7795cbf02e29170c3287b7fe36264","href":"https://halfpagetechnologies.com"},"favicon":"https://mintcdn.com/halfpage/InD3syZckE7RxDls/favicon.svg?fit=max\u0026auto=format\u0026n=InD3syZckE7RxDls\u0026q=85\u0026s=2da132f5329697949c5eb7aca663000f","navbar":{"links":[{"href":"https://github.com/mdylan2/halfpage","type":"github"}],"primary":{"type":"button","label":"Dashboard","href":"https://halfpagetechnologies.com"}},"footer":{"socials":{"github":"https://github.com/mdylan2/halfpage","website":"https://halfpagetechnologies.com"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"halfpage","hasAudioNarration":false,"actualSubdomain":"halfpage","customDomains":["docs.halfpagetechnologies.com"],"gitSource":{"type":"github","owner":"mdylan2","repo":"halfpage","deployBranch":"production","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6af714e9206816990b8bba5c","clientVersion":"0.0.4128","searchFilterCounts":[{"language":"default","tag":"API reference","count":15},{"language":"default","tag":"Guides","count":5},{"language":"default","tag":"Get started","count":4},{"language":"default","tag":"export","count":4},{"language":"default","tag":"shares","count":4},{"language":"default","tag":"upload","count":4},{"language":"default","tag":"predict","count":2},{"language":"default","tag":"AI \u0026 agents","count":1},{"language":"default","tag":"models","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","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":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","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":"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":"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":"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":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","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":"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":"workos-sso-scim","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},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","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}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/upload/upload-an-image","slug":"/api-reference/upload/upload-an-image","pageMetadata":{"title":"Upload an image","description":"Get a microscopy image into HalfPage. How the request is sent decides\nwhich of the two modes you get:\n\n**One request:** send `multipart/form-data` with a `file` part. The file is\nstreamed to storage and converted before the response returns, so the\nreturned `image` is already `ready` and its `id` can go straight into\n`POST /predict`. Simplest, and the right choice up to a few hundred MB.\n\n**Resumable:** send `application/json` with `{\"name\": ..., \"size\": ...}`\ninstead of a file. No bytes are sent on this request; the response carries\n`upload` with presigned part URLs. PUT each chunk directly to its `url` (in\npart order), call `POST /upload/{image_id}/complete`, then poll\n`GET /upload/{image_id}` until `upload_status` is `ready`. Use this for\nlarge files or unreliable connections, since an interrupted part can be\nretried on its own instead of restarting the whole transfer.\n\nEither way the image counts against your plan's storage cap, so both modes\nreturn `402` once that cap is reached.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/v1/upload","href":"/api-reference/upload/upload-an-image","autogeneratedByOpenApi":true},"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 p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"Get a microscopy image into HalfPage. How the request is sent decides\\nwhich of the two modes you get:\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"One request:\"\n }), \" send \", _jsx(_components.code, {\n children: \"multipart/form-data\"\n }), \" with a \", _jsx(_components.code, {\n children: \"file\"\n }), \" part. The file is\\nstreamed to storage and converted before the response returns, so the\\nreturned \", _jsx(_components.code, {\n children: \"image\"\n }), \" is already \", _jsx(_components.code, {\n children: \"ready\"\n }), \" and its \", _jsx(_components.code, {\n children: \"id\"\n }), \" can go straight into\\n\", _jsx(_components.code, {\n children: \"POST /predict\"\n }), \". Simplest, and the right choice up to a few hundred MB.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Resumable:\"\n }), \" send \", _jsx(_components.code, {\n children: \"application/json\"\n }), \" with \", _jsx(_components.code, {\n children: \"{\\\"name\\\": ..., \\\"size\\\": ...}\"\n }), \"\\ninstead of a file. No bytes are sent on this request; the response carries\\n\", _jsx(_components.code, {\n children: \"upload\"\n }), \" with presigned part URLs. PUT each chunk directly to its \", _jsx(_components.code, {\n children: \"url\"\n }), \" (in\\npart order), call \", _jsx(_components.code, {\n children: \"POST /upload/{image_id}/complete\"\n }), \", then poll\\n\", _jsx(_components.code, {\n children: \"GET /upload/{image_id}\"\n }), \" until \", _jsx(_components.code, {\n children: \"upload_status\"\n }), \" is \", _jsx(_components.code, {\n children: \"ready\"\n }), \". Use this for\\nlarge files or unreliable connections, since an interrupted part can be\\nretried on its own instead of restarting the whole transfer.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Either way the image counts against your plan’s storage cap, so both modes\\nreturn \", _jsx(_components.code, {\n children: \"402\"\n }), \" once that cap is reached.\"]\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}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Upload an image","description":"Get a microscopy image into HalfPage. How the request is sent decides\nwhich of the two modes you get:\n\n**One request:** send `multipart/form-data` with a `file` part. The file is\nstreamed to storage and converted before the response returns, so the\nreturned `image` is already `ready` and its `id` can go straight into\n`POST /predict`. Simplest, and the right choice up to a few hundred MB.\n\n**Resumable:** send `application/json` with `{\"name\": ..., \"size\": ...}`\ninstead of a file. No bytes are sent on this request; the response carries\n`upload` with presigned part URLs. PUT each chunk directly to its `url` (in\npart order), call `POST /upload/{image_id}/complete`, then poll\n`GET /upload/{image_id}` until `upload_status` is `ready`. Use this for\nlarge files or unreliable connections, since an interrupted part can be\nretried on its own instead of restarting the whole transfer.\n\nEither way the image counts against your plan's storage cap, so both modes\nreturn `402` once that cap is reached.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/v1/upload","href":"/api-reference/upload/upload-an-image","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"tags":["upload"],"summary":"Upload an image","description":"Get a microscopy image into HalfPage. How the request is sent decides\nwhich of the two modes you get:\n\n**One request:** send `multipart/form-data` with a `file` part. The file is\nstreamed to storage and converted before the response returns, so the\nreturned `image` is already `ready` and its `id` can go straight into\n`POST /predict`. Simplest, and the right choice up to a few hundred MB.\n\n**Resumable:** send `application/json` with `{\"name\": ..., \"size\": ...}`\ninstead of a file. No bytes are sent on this request; the response carries\n`upload` with presigned part URLs. PUT each chunk directly to its `url` (in\npart order), call `POST /upload/{image_id}/complete`, then poll\n`GET /upload/{image_id}` until `upload_status` is `ready`. Use this for\nlarge files or unreliable connections, since an interrupted part can be\nretried on its own instead of restarting the whole transfer.\n\nEither way the image counts against your plan's storage cap, so both modes\nreturn `402` once that cap is reached.","operationId":"upload_api_v1_upload_post","requestBody":"3e2ea8cb-6d3f-4d39-b415-88e03dd451e0","responses":{"200":"7d429550-ad5d-4364-8426-9a9fcc9981b3","401":"5c4713cc-fd28-4262-b941-02a2e41a52dd","402":"b3d13e64-6dde-441c-8aa3-6a10ec11c901","404":"822a43a2-1300-46f6-af24-011e8c2d5c39","413":"06a9846a-b3ce-48be-8573-6d39cf5d2dc9","422":"cac6efc0-dba0-47f4-83f7-fccb3d8cf5b0","501":"252e5714-0570-47b6-af84-d2852393960b"},"security":["4e82b869-82c7-4256-80be-804109531319"],"method":"post","type":"path","servers":["479f4945-1cfc-49e3-9171-174aedcb516d","a6585785-966f-49c2-8a2b-d9469c88a061"],"path":"/api/v1/upload","baseUrlOptions":["https://api.halfpagetechnologies.com/backend","https://staging-api.halfpagetechnologies.com/backend"],"title":"Upload an image","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"type":"string","format":"binary","description":"The microscopy image to upload (TIFF). Up to 4 GB.","isRequired":true,"uniqueKey":"file","typeLabel":"file"}},"type":"object","required":["file"],"title":"SingleRequestUpload","description":"Send the whole file in one request. The response returns the image already `ready`.","uniqueKey":"","typeLabel":"SingleRequestUpload · object"},"examples":{"Example":{"title":"Example","value":{"file":"\u003cstring>"}}},"exampleType":"generated"},"application/json":{"schema":{"properties":{"name":{"type":"string","title":"Name","description":"Filename or label for the image.","examples":["sample.tif"],"isRequired":true,"uniqueKey":"name","typeLabel":"string"},"size":{"type":"integer","title":"Size","description":"Exact total size of the file in bytes.","examples":[104857600],"isRequired":true,"uniqueKey":"size","typeLabel":"integer"},"additional_info":{"additionalProperties":true,"type":"object","title":"Additional Info","description":"Arbitrary JSON metadata to store alongside the image.","uniqueKey":"additional_info","typeLabel":"Additional Info · object"}},"type":"object","required":["name","size"],"title":"ResumableUploadRequest","description":"Open a resumable upload for a file you are about to send in parts.\n\n`size` must be the file's exact byte size, because the part plan is computed\nfrom it.","uniqueKey":"","typeLabel":"ResumableUploadRequest · object"},"example":{"name":"sample.tif","size":104857600},"examples":{"Example":{"title":"Example","value":{"name":"sample.tif","size":104857600}}},"exampleType":"examples"}},"required":true,"exampleType":"examples"},"responses":{"7d429550-ad5d-4364-8426-9a9fcc9981b3":{"description":"The file was stored (`upload` is `null`, the image is `ready`), or a resumable upload was opened (`upload` carries the presigned plan).","content":{"application/json":{"schema":{"properties":{"image":{"properties":{"name":{"type":"string","title":"Name","description":"Filename or label for the image.","examples":["sample.tif"],"isRequired":true,"uniqueKey":"image.name","typeLabel":"string"},"size":{"type":"integer","title":"Size","description":"Total size of the image file in bytes.","examples":[4194304],"isRequired":true,"uniqueKey":"image.size","typeLabel":"integer"},"id":{"type":"string","title":"Id","isRequired":true,"uniqueKey":"image.id","typeLabel":"string"},"created_at":{"type":"string","format":"date-time","title":"Created At","isRequired":true,"uniqueKey":"image.created_at","typeLabel":"string\u003cdate-time>"},"upload_status":{"type":"string","enum":["uploading","processing","ready","failed"],"title":"UploadStatus","description":"Lifecycle of a resumable S3 multipart image upload.\n\nuploading -> row created, bytes still being PUT directly to S3\nprocessing -> object landed in S3, backend is converting it off the event loop\nready -> conversion done, `shape` populated, image is usable\nfailed -> aborted or conversion failed (orphan-sweep cron will reap it)","isRequired":true,"uniqueKey":"image.upload_status","typeLabel":"enum\u003cstring>"},"image_type":{"type":"string","enum":["TIFF"],"title":"ImageType","description":"Image format. Only `TIFF` is currently supported.","default":"TIFF","uniqueKey":"image.image_type","typeLabel":"enum\u003cstring>"},"additional_info":{"additionalProperties":true,"type":"object","title":"Additional Info","description":"Arbitrary JSON metadata to store alongside the image.","uniqueKey":"image.additional_info","typeLabel":"Additional Info · object"},"folder_id":{"oneOf":[{"type":"string","title":"Folder Id","description":"The folder the image is in, if any; it must belong to your organization. API clients typically have no folders and omit this.","format":"uuid","uniqueKey":"image.folder_id.oneOf.0","typeLabel":"string\u003cuuid>"},{"type":"null","title":"Folder Id","description":"The folder the image is in, if any; it must belong to your organization. API clients typically have no folders and omit this.","uniqueKey":"image.folder_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"image.folder_id","typeLabel":"string\u003cuuid> | null"},"shape":{"oneOf":[{"type":"array","items":{"type":"integer","uniqueKey":"image.shape.oneOf.0.items.[INDEX]","typeLabel":"integer"},"title":"Shape","uniqueKey":"image.shape.oneOf.0","typeLabel":"integer[]"},{"type":"null","title":"Shape","uniqueKey":"image.shape.oneOf.1","typeLabel":"null"}],"uniqueKey":"image.shape","typeLabel":"integer[] | null"},"processed_at":{"oneOf":[{"type":"string","title":"Processed At","format":"date-time","uniqueKey":"image.processed_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","title":"Processed At","uniqueKey":"image.processed_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"image.processed_at","typeLabel":"string\u003cdate-time> | null"},"upload_error":{"oneOf":[{"type":"string","title":"Upload Error","uniqueKey":"image.upload_error.oneOf.0","typeLabel":"string"},{"type":"null","title":"Upload Error","uniqueKey":"image.upload_error.oneOf.1","typeLabel":"null"}],"uniqueKey":"image.upload_error","typeLabel":"string | null"}},"type":"object","required":["name","size","id","created_at","upload_status"],"title":"ImageStatusResponse","description":"An image's upload lifecycle and metadata: enough to know when a freshly\nuploaded image is `ready` to run a prediction against.","examples":[{"additional_info":{},"created_at":"2026-07-01T12:00:00Z","id":"3fa85f64-5717-4562-b3fc-2c963f66afa6","image_type":"TIFF","name":"sample.tif","processed_at":"2026-07-01T12:00:05Z","shape":[512,512,3],"size":4194304,"upload_status":"ready"}],"isRequired":true,"uniqueKey":"image","typeLabel":"ImageStatusResponse · object"},"success":{"type":"boolean","title":"Success","default":true,"uniqueKey":"success","typeLabel":"boolean"},"upload":{"oneOf":[{"type":"object","title":"UploadPlan","description":"The presigned multipart plan: PUT each chunk of the file to its `url`\n(in part order), then call `POST /upload/{image_id}/complete`. No body is\nneeded: the server verifies the uploaded parts with storage directly.\n\nThe internal storage object key is deliberately not exposed: the presigned\n`url`s already encode everything the client needs, and the key layout is a\nserver-side implementation detail we keep off the public contract.","required":["upload_id","part_size","urls"],"example":{"part_size":33554432,"upload_id":"2~aBcD3fGhIjKlMnOpQrStUvWxYz","urls":[{"part_number":1,"url":"https://halfpage.s3.amazonaws.com/...\u0026partNumber=1"},{"part_number":2,"url":"https://halfpage.s3.amazonaws.com/...\u0026partNumber=2"}]},"properties":{"upload_id":{"type":"string","title":"Upload Id","isRequired":true,"uniqueKey":"upload.oneOf.0.upload_id","typeLabel":"string"},"part_size":{"type":"integer","title":"Part Size","isRequired":true,"uniqueKey":"upload.oneOf.0.part_size","typeLabel":"integer"},"urls":{"items":{"properties":{"part_number":{"type":"integer","title":"Part Number","isRequired":true,"uniqueKey":"upload.oneOf.0.urls.items.[INDEX].part_number","typeLabel":"integer"},"url":{"type":"string","title":"Url","isRequired":true,"uniqueKey":"upload.oneOf.0.urls.items.[INDEX].url","typeLabel":"string"}},"type":"object","required":["part_number","url"],"title":"PartUrlOut","uniqueKey":"upload.oneOf.0.urls.items.[INDEX]","typeLabel":"PartUrlOut · object"},"type":"array","title":"Urls","isRequired":true,"uniqueKey":"upload.oneOf.0.urls","typeLabel":"PartUrlOut · object[]"}},"uniqueKey":"upload.oneOf.0","typeLabel":"UploadPlan · object"},{"type":"null","uniqueKey":"upload.oneOf.1","typeLabel":"null"}],"uniqueKey":"upload","typeLabel":"UploadPlan · object | null"}},"type":"object","required":["image"],"title":"UploadResult","description":"The image the pixels landed on (or will land on).\n\nAfter a single-request upload `upload` is `null` and `image.upload_status`\nis already `ready`, so the `image.id` can go straight into `POST /predict`.\nAfter a resumable upload was opened, `upload` carries the presigned plan and\n`image.upload_status` is `uploading` until you complete it.","uniqueKey":"","typeLabel":"UploadResult · object"},"examples":{"Example":{"title":"Example","value":{"image":{"additional_info":{},"created_at":"2026-07-01T12:00:00Z","id":"3fa85f64-5717-4562-b3fc-2c963f66afa6","image_type":"TIFF","name":"sample.tif","processed_at":"2026-07-01T12:00:05Z","shape":[512,512,3],"size":4194304,"upload_status":"ready"},"success":true,"upload":{"part_size":33554432,"upload_id":"2~aBcD3fGhIjKlMnOpQrStUvWxYz","urls":[{"part_number":1,"url":"https://halfpage.s3.amazonaws.com/...\u0026partNumber=1"},{"part_number":2,"url":"https://halfpage.s3.amazonaws.com/...\u0026partNumber=2"}]}}}},"exampleType":"generated"}},"exampleType":"generated"},"5c4713cc-fd28-4262-b941-02a2e41a52dd":{"description":"Missing or invalid credentials. Supply a valid `Authorization: Bearer hp_live_...` API key.","content":{"application/json":{"schema":{"properties":{"detail":{"type":"string","title":"Detail","examples":["Job with id 11111111-1111-1111-1111-111111111111 not found"],"isRequired":true,"uniqueKey":"detail","typeLabel":"string"}},"type":"object","required":["detail"],"title":"ErrorResponse","description":"The body returned for a handled error: a single human-readable\n``detail`` string.","uniqueKey":"","typeLabel":"ErrorResponse · object"},"example":{"detail":"Requires authentication"},"examples":{"Example":{"title":"Example","value":{"detail":"Requires authentication"}}},"exampleType":"examples"}},"exampleType":"examples"},"b3d13e64-6dde-441c-8aa3-6a10ec11c901":{"description":"Image storage quota exceeded for your plan. Upgrade to store more images.","content":{"application/json":{"schema":{"properties":{"detail":{"type":"string","title":"Detail","examples":["Job with id 11111111-1111-1111-1111-111111111111 not found"],"isRequired":true,"uniqueKey":"detail","typeLabel":"string"}},"type":"object","required":["detail"],"title":"ErrorResponse","description":"The body returned for a handled error: a single human-readable\n``detail`` string.","uniqueKey":"","typeLabel":"ErrorResponse · object"},"example":{"detail":"You've reached your storage limit of 100 images. Upgrade to store more."},"examples":{"Example":{"title":"Example","value":{"detail":"You've reached your storage limit of 100 images. Upgrade to store more."}}},"exampleType":"examples"}},"exampleType":"examples"},"822a43a2-1300-46f6-af24-011e8c2d5c39":{"description":"The resource does not exist, or is not in your organization.","content":{"application/json":{"schema":{"properties":{"detail":{"type":"string","title":"Detail","examples":["Job with id 11111111-1111-1111-1111-111111111111 not found"],"isRequired":true,"uniqueKey":"detail","typeLabel":"string"}},"type":"object","required":["detail"],"title":"ErrorResponse","description":"The body returned for a handled error: a single human-readable\n``detail`` string.","uniqueKey":"","typeLabel":"ErrorResponse · object"},"example":{"detail":"Image with id 3fa85f64-5717-4562-b3fc-2c963f66afa6 not found"},"examples":{"Example":{"title":"Example","value":{"detail":"Image with id 3fa85f64-5717-4562-b3fc-2c963f66afa6 not found"}}},"exampleType":"examples"}},"exampleType":"examples"},"06a9846a-b3ce-48be-8573-6d39cf5d2dc9":{"description":"The uploaded file exceeds the 4 GB size limit, or decodes to more than 250 million pixel values (height × width × channels).","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"cac6efc0-dba0-47f4-83f7-fccb3d8cf5b0":{"description":"The `file` part is missing or can't be read as an image, or the JSON body is invalid (bad `name`/`size`).","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}},"252e5714-0570-47b6-af84-d2852393960b":{"description":"A resumable upload was requested but storage does not support it (local dev only).","content":{"_mintlify/placeholder":{"schema":{"type":"object","description":""}}}}},"security":{"4e82b869-82c7-4256-80be-804109531319":{"HTTPBearer":{"type":"http","scheme":"bearer","scopes":[],"schemeName":"HTTPBearer"}}},"servers":{"479f4945-1cfc-49e3-9171-174aedcb516d":{"url":"https://api.halfpagetechnologies.com/backend","description":"Production"},"a6585785-966f-49c2-8a2b-d9469c88a061":{"url":"https://staging-api.halfpagetechnologies.com/backend","description":"Staging"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","scopes":[],"schemeName":"HTTPBearer"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Bearer authentication header of the form `Bearer \u003ctoken>`, where `\u003ctoken>` is your auth token.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"HTTPBearer","name":"Authorization"}],"title":"HTTPBearer"}]},"originalFileLocation":"api-reference/openapi.json"},"subdomain":"halfpage","siteName":"HalfPage API","title":"Upload an image - HalfPage API","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-13T13:47:24.798Z","originalFileLocation":"api-reference/upload/upload-an-image.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=\"Get a microscopy image into HalfPage. How the request is sent decides which of the two modes you get: One request: send multipart/form-data with a file part. The file is streamed to storage and converted before the response returns, so the returned image is already ready and its id can go straight into POST /predict. Simplest, and the right choice up to a few hundred MB. Resumable: send application/json with {\u0026quot;name\u0026quot;: ..., \u0026quot;size\u0026quot;: ...} instead of a file. No bytes are sent on this request; the response carries upload with presigned part URLs. PUT each chunk directly to its url (in part order), call POST /upload/{image_id}/complete, then poll GET /upload/{image_id} until upload_status is ready. Use this for large files or unreliable connections, since an interrupted part can be retried on its own instead of restarting the whole transfer. Either way the image counts against your plan\u0026#x27;s storage cap, so both modes return 402 once that cap is reached.\">\u003cmeta data-mint-head name=\"application-name\" content=\"HalfPage 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/halfpage/xwTInuIADjWWIjil/_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/halfpage/xwTInuIADjWWIjil/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/halfpage/xwTInuIADjWWIjil/_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/halfpage/xwTInuIADjWWIjil/_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/halfpage/xwTInuIADjWWIjil/_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/halfpage/xwTInuIADjWWIjil/_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/halfpage/xwTInuIADjWWIjil/_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/halfpage/xwTInuIADjWWIjil/_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/halfpage/xwTInuIADjWWIjil/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Upload an image - HalfPage API\">\u003cmeta data-mint-head property=\"og:description\" content=\"Get a microscopy image into HalfPage. How the request is sent decides which of the two modes you get: One request: send multipart/form-data with a file part. The file is streamed to storage and converted before the response returns, so the returned image is already ready and its id can go straight into POST /predict. Simplest, and the right choice up to a few hundred MB. Resumable: send application/json with {\u0026quot;name\u0026quot;: ..., \u0026quot;size\u0026quot;: ...} instead of a file. No bytes are sent on this request; the response carries upload with presigned part URLs. PUT each chunk directly to its url (in part order), call POST /upload/{image_id}/complete, then poll GET /upload/{image_id} until upload_status is ready. Use this for large files or unreliable connections, since an interrupted part can be retried on its own instead of restarting the whole transfer. Either way the image counts against your plan\u0026#x27;s storage cap, so both modes return 402 once that cap is reached.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"HalfPage API\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://halfpage.mintlify.site/_mintlify/api/og/v2?division=upload\u0026amp;title=Upload+an+image\u0026amp;description=Get+a+microscopy+image+into+HalfPage.+How+the+request+is+sent+decides%0Awhich+of+the+two+modes+you+get%3A%0A%0A**One+request%3A**+send+%60multipart%2Fform-data%60+with+a+%60file%60\u0026amp;theme=51dfeddd43e2841de8834c15\u0026amp;signature=01e53c9af2e6f1ecf5e6d492953a1a9459bb2a2231c76e481df4c635ff4ebf19\">\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=\"Upload an image - HalfPage API\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Get a microscopy image into HalfPage. How the request is sent decides which of the two modes you get: One request: send multipart/form-data with a file part. The file is streamed to storage and converted before the response returns, so the returned image is already ready and its id can go straight into POST /predict. Simplest, and the right choice up to a few hundred MB. Resumable: send application/json with {\u0026quot;name\u0026quot;: ..., \u0026quot;size\u0026quot;: ...} instead of a file. No bytes are sent on this request; the response carries upload with presigned part URLs. PUT each chunk directly to its url (in part order), call POST /upload/{image_id}/complete, then poll GET /upload/{image_id} until upload_status is ready. Use this for large files or unreliable connections, since an interrupted part can be retried on its own instead of restarting the whole transfer. Either way the image counts against your plan\u0026#x27;s storage cap, so both modes return 402 once that cap is reached.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://halfpage.mintlify.site/_mintlify/api/og/v2?division=upload\u0026amp;title=Upload+an+image\u0026amp;description=Get+a+microscopy+image+into+HalfPage.+How+the+request+is+sent+decides%0Awhich+of+the+two+modes+you+get%3A%0A%0A**One+request%3A**+send+%60multipart%2Fform-data%60+with+a+%60file%60\u0026amp;theme=51dfeddd43e2841de8834c15\u0026amp;signature=01e53c9af2e6f1ecf5e6d492953a1a9459bb2a2231c76e481df4c635ff4ebf19\">\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/halfpage/xwTInuIADjWWIjil/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"HalfPage API\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#2563eb\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/upload/upload-an-image.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.halfpagetechnologies.com/#organization\",\"name\":\"HalfPage API\",\"url\":\"https://docs.halfpagetechnologies.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/halfpage/rhKdEUCb6V98b2yX/logo/light.svg?fit=max\u0026auto=format\u0026n=rhKdEUCb6V98b2yX\u0026q=85\u0026s=667c16283d8ca68ed577d207d7ce5249\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.halfpagetechnologies.com#website\",\"name\":\"HalfPage API\",\"url\":\"https://docs.halfpagetechnologies.com\",\"publisher\":{\"@id\":\"https://docs.halfpagetechnologies.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image#webpage\",\"url\":\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image\",\"name\":\"Upload an image\",\"description\":\"Get a microscopy image into HalfPage. How the request is sent decides which of the two modes you get: One request: send multipart/form-data with a file part. The file is streamed to storage and converted before the response returns, so the returned image is already ready and its id can go straight into POST /predict. Simplest, and the right choice up to a few hundred MB. Resumable: send application/json with {\\\"name\\\": ..., \\\"size\\\": ...} instead of a file. No bytes are sent on this request; the response carries upload with presigned part URLs. PUT each chunk directly to its url (in part order), call POST /upload/{image_id}/complete, then poll GET /upload/{image_id} until upload_status is ready. Use this for large files or unreliable connections, since an interrupted part can be retried on its own instead of restarting the whole transfer. Either way the image counts against your plan's storage cap, so both modes return 402 once that cap is reached.\",\"dateModified\":\"2026-11-13T13:47:24.798Z\",\"isPartOf\":{\"@id\":\"https://docs.halfpagetechnologies.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"HalfPage API\",\"item\":\"https://docs.halfpagetechnologies.com\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Upload an image\",\"item\":\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image#apireference\",\"headline\":\"Upload an image\",\"name\":\"Upload an image\",\"description\":\"Get a microscopy image into HalfPage. How the request is sent decides which of the two modes you get: One request: send multipart/form-data with a file part. The file is streamed to storage and converted before the response returns, so the returned image is already ready and its id can go straight into POST /predict. Simplest, and the right choice up to a few hundred MB. Resumable: send application/json with {\\\"name\\\": ..., \\\"size\\\": ...} instead of a file. No bytes are sent on this request; the response carries upload with presigned part URLs. PUT each chunk directly to its url (in part order), call POST /upload/{image_id}/complete, then poll GET /upload/{image_id} until upload_status is ready. Use this for large files or unreliable connections, since an interrupted part can be retried on its own instead of restarting the whole transfer. Either way the image counts against your plan's storage cap, so both modes return 402 once that cap is reached.\",\"url\":\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image\",\"mainEntityOfPage\":{\"@id\":\"https://docs.halfpagetechnologies.com/api-reference/upload/upload-an-image#webpage\"},\"dateModified\":\"2026-11-13T13:47:24.798Z\",\"publisher\":{\"@id\":\"https://docs.halfpagetechnologies.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.halfpagetechnologies.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"HalfPage API\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"HalfPage API\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/api-reference/upload/upload-an-image.md","siteName":"HalfPage API","nav":{"global":null,"tabs":[{"tab":"Guides","pages":[{"title":"Guides","href":"/introduction"}]},{"tab":"API reference","groups":[{"group":"upload","pages":[{"title":"Upload an image","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/v1/upload","href":"/api-reference/upload/upload-an-image"},{"title":"Finish a resumable upload","description":"Assemble a resumable upload from its uploaded parts, mark the image\n`processing`, and kick off async conversion. Returns `202`. Conversion runs\noff the request path, so poll `GET /upload/{image_id}` until `ready`.\n\nNo body is needed: the server discovers the uploaded parts (and their ETags)\nfrom storage. Pass `parts` only to assemble an explicit subset.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/v1/upload/{image_id}/complete","href":"/api-reference/upload/finish-a-resumable-upload"},{"title":"Get upload status","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/upload/{image_id}","href":"/api-reference/upload/get-upload-status"},{"title":"Delete an image","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /api/v1/upload/{image_id}","href":"/api-reference/upload/delete-an-image"}]},{"group":"predict","pages":[{"title":"Run a prediction","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/v1/predict","href":"/api-reference/predict/run-a-prediction"},{"title":"Get prediction status","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/predict/{prediction_id}","href":"/api-reference/predict/get-prediction-status"}]},{"group":"export","pages":[{"title":"Export measurements (CSV)","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/export/{image_id}/measurements.csv","href":"/api-reference/export/export-measurements-csv"},{"title":"Export ROIs (GeoJSON)","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/export/{image_id}/rois.geojson","href":"/api-reference/export/export-rois-geojson"},{"title":"Export image with mask overlay (PNG)","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/export/{image_id}/overlay.png","href":"/api-reference/export/export-image-with-mask-overlay-png"},{"title":"Export ROIs (ImageJ ZIP)","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/export/{image_id}/rois.zip","href":"/api-reference/export/export-rois-imagej-zip"}]},{"group":"models","pages":[{"title":"List available models","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/models","href":"/api-reference/models/list-available-models"}]},{"group":"shares","pages":[{"title":"List shares","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/shares","href":"/api-reference/shares/list-shares"},{"title":"Share an image","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /api/v1/shares","href":"/api-reference/shares/share-an-image"},{"title":"Get a share","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /api/v1/shares/{share_id}","href":"/api-reference/shares/get-a-share"},{"title":"Revoke a share","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /api/v1/shares/{share_id}","href":"/api-reference/shares/revoke-a-share"}]}]}]},"basePath":"","title":"Upload an image - HalfPage API","buildId":"dpl_5tKr6cUUeuVJdEZ9JAEY3h4soMJ8","deploymentId":"dpl_5tKr6cUUeuVJdEZ9JAEY3h4soMJ8","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-DbeN8Wo6.js","utils-CwSb5Doc.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-BmREeM3N.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-AYjWerCj.js","snippetPresets-QD4ULQlp.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-Digj5cjF.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-CiHrzluR.js","shallow-D7h7pFGg.js","getApiPlaygroundDisplay-mlxkpAUf.js","CodeSnippet-D2rH5lZI.js","CodeSnippets-B53ulOaL.js","Page-CqcDm2To.js","getPastedJson-DxGeNMih.js","icon-BHbyrebp.js","MethodPill-C7F_KEEJ.js","DuplicateIcon-j3c5-73z.js","createIcon-OvCnyFqD.js","DynamicMarkdown-DpAS3GCb.js","SectionHeading-DMPpdrvW.js","axios-vUo_bRtp.js","Markdown-D7pDRguu.js","clsx-2_c6mSt_.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-Cu7_SikL.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-ydqCcy4b.js"]}