{"openapi":"3.1.0","info":{"title":"PropertyPixel API","version":"1.0.0","summary":"Enhance, stage and animate real estate photos.","description":"The PropertyPixel REST API does what the Studio does: create projects, add photos, enhance and stage them, make videos, and download the results. The MCP server at `https://mcp.propertypixel.app` exposes the same operations as tools.\n\nAuthenticate with an API key (`Authorization: Bearer pp_live_…`) created in Settings → Developers, or with an OAuth access token. Each credential is bound to one workspace and spends that workspace's credits.\n\nOperations that spend credits use a quote → confirm flow. Errors are `application/problem+json` with a stable `code`. Guides: https://docs.propertypixel.app.","termsOfService":"https://propertypixel.app/terms","contact":{"name":"PropertyPixel support","email":"hello@propertypixel.app","url":"https://docs.propertypixel.app"},"x-logo":{"url":"https://propertypixel.app/branding/logo-full-teal.svg","altText":"PropertyPixel","href":"https://propertypixel.app"}},"servers":[{"url":"https://api.propertypixel.app/v1","description":"This deployment"}],"tags":[{"name":"Account","description":"The workspace this credential is connected to, its plan and credit balance."},{"name":"Projects","description":"Properties. Each project holds the photos and results for one listing."},{"name":"Photos","description":"Source photos in a project."},{"name":"Uploads","description":"Signed uploads from a script, and no-login upload links for a phone."},{"name":"Edit options","description":"The enhancement types, design styles and video settings you can request."},{"name":"Editing","description":"Photo enhancement and virtual staging. Spends credits."},{"name":"Video","description":"Photo to Video clips and Listing Tours. Spends credits."},{"name":"Recommendations","description":"Suggested edits for each photo (free), and applying them (spends credits)."},{"name":"Jobs","description":"Status, results and picks of enhancement, staging and video jobs."},{"name":"Downloads","description":"Signed download links and zip archives."},{"name":"Quotes","description":"Price a spending request before running it."}],"security":[{"bearerAuth":[]},{"oauth2":[]}],"externalDocs":{"description":"Guides and quickstarts","url":"https://docs.propertypixel.app"},"x-rate-limits":{"read":"120 requests per 60s per connection","write":"20 requests per 60s per connection"},"paths":{"/account":{"get":{"operationId":"get_account","summary":"Get account","description":"Get the connected PropertyPixel account: the workspace and the user's role in it, whether this connection can make changes, the credit balance (100 credits = one photo enhancement), the plan, and whether results are watermarked (trial). Call this before spending to check the balance, or when the user asks about their credits or plan.\n\nWorks with view-only access.","tags":["Account"],"x-required-scope":"read","responses":{"200":{"description":"Get account","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects":{"get":{"operationId":"list_projects","summary":"List projects","description":"List the property projects in the connected workspace, newest first by default. Each project groups the photos of one listing. Use `search` to find a project by name or address before asking the user for an ID. Returns project IDs, photo counts, a cover image and a Studio link; page with `next_cursor`.\n\nWorks with view-only access.","tags":["Projects"],"x-required-scope":"read","parameters":[{"in":"query","name":"search","schema":{"description":"Case-insensitive match on project name or address.","type":"string","maxLength":200},"description":"Case-insensitive match on project name or address."},{"in":"query","name":"sort","schema":{"default":"newest","description":"Sort order.","type":"string","enum":["newest","oldest","name_asc","name_desc"]},"description":"Sort order."},{"in":"query","name":"cursor","schema":{"description":"Opaque cursor from a previous page's next_cursor.","type":"string"},"description":"Opaque cursor from a previous page's next_cursor."},{"in":"query","name":"limit","schema":{"default":25,"description":"Page size (1–100).","type":"integer","minimum":1,"maximum":100},"description":"Page size (1–100)."}],"responses":{"200":{"description":"List projects","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"next_cursor":{"type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"operationId":"create_project","summary":"Create a project","description":"Create a new, empty project for one property listing. Name it after the address or listing so the user can find it later. Then add photos with add_photos or create_upload_link.\n\nRequires a connection with edit access.","tags":["Projects"],"x-required-scope":"write","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Project name, e.g. the street address."},"address":{"description":"Property address.","type":"string","maxLength":500},"property_type":{"description":"Kind of property.","type":"string","enum":["house","apartment","condo","townhouse","villa","land","commercial","office","retail","industrial","other"]}},"required":["name"]}}}},"responses":{"201":{"description":"Create a project","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}":{"get":{"operationId":"get_project","summary":"Get a project","description":"Get one project with all its photos (IDs, room types, signed preview URLs) and the status of its most recent upload link (waiting, receiving, done or expired). Use the photo IDs with enhance_photos, stage_photos or create_video. To see finished edits, call show_results instead.\n\nWorks with view-only access.","tags":["Projects"],"x-required-scope":"read","parameters":[{"in":"path","name":"id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Project ID."},"required":true,"description":"Project ID."}],"responses":{"200":{"description":"Get a project","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDetail"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"operationId":"delete_project","summary":"Delete a project","description":"Delete a project with all its photos and edited results. Only do this when the user explicitly asks to delete that project; confirm the project name with them first. It disappears from the Studio immediately.\n\nRequires a connection with edit access.","tags":["Projects"],"x-required-scope":"write","parameters":[{"in":"path","name":"id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Project ID."},"required":true,"description":"Project ID."},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Delete a project","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedProject"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{id}/results":{"get":{"operationId":"show_results","summary":"Show results","description":"Show a project's edited results: what is still processing, the newest finished version of each photo and each video, and the versions the user picked. Use this when the user wants to see or review their results. Result URLs are signed for 1 hour.\n\nWorks with view-only access.","tags":["Projects"],"x-required-scope":"read","parameters":[{"in":"path","name":"id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Project ID."},"required":true,"description":"Project ID."}],"responses":{"200":{"description":"Show results","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Results"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{project_id}/photos":{"post":{"operationId":"add_photos","summary":"Add photos to a project","description":"Add photos to a project from public https image URLs (`image_urls`) or from files the user attached in ChatGPT (`files`). Up to 25 photos per call; a project holds at most 100. Each file must be JPEG, PNG, WebP, HEIC or HEIF and at most 25 MB. Dropbox and Google Drive share links work if they are shared publicly. HEIC is converted to JPEG and large photos are downscaled to a 2048px long edge, like the web app. Returns the new photos (use their IDs with enhance_photos, stage_photos or create_video) and a `failed` list with a reason per source; report failures to the user rather than retrying blindly. If the user has photos on their phone or computer and no links, call create_upload_link instead.\n\nRequires a connection with edit access.","tags":["Photos"],"x-required-scope":"write","parameters":[{"in":"path","name":"project_id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The project to add photos to."},"required":true,"description":"The project to add photos to."},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"image_urls":{"description":"Public https image URLs (max 25).","maxItems":25,"type":"array","items":{"type":"string","format":"uri","description":"A public https:// image URL."}},"files":{"description":"Files the user attached in ChatGPT.","maxItems":25,"type":"array","items":{"$ref":"#/components/schemas/ChatGptFile"}}}}}}},"responses":{"201":{"description":"Add photos to a project","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhotoList"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{project_id}/photos/delete":{"post":{"operationId":"delete_photos","summary":"Delete photos","description":"Delete photos from a project, together with every edit, staging and video made from them. Only do this when the user explicitly asks to remove those photos; confirm which ones first. All IDs must belong to the project, otherwise nothing is deleted. Returns the deleted IDs; call get_project to see what remains.\n\nRequires a connection with edit access.","tags":["Photos"],"x-required-scope":"write","parameters":[{"in":"path","name":"project_id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The project the photos belong to."},"required":true,"description":"The project the photos belong to."},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"photo_ids":{"description":"Photo IDs to delete (max 100).","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["photo_ids"]}}}},"responses":{"200":{"description":"Delete photos","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhotoDeletion"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/uploads":{"post":{"operationId":"create_upload","summary":"Start a signed upload","description":"Reserve room in a project for up to 25 photos and get one signed URL per file. PUT each file's raw bytes to its upload_url with exactly the returned headers, then call POST /uploads/{id}/complete with the storage_path, filename, size and content_type of every file that uploaded. Files must be JPEG, PNG, WebP, HEIC or HEIF, at most 25 MB each; a project holds at most 100 photos. The reservation expires at expires_at (about 15 minutes); complete before then. Files are stored exactly as sent, except HEIC/HEIF, which is converted to JPEG on completion. Downscale large images yourself (the web app uses a 2048px long edge).\n\nRequires a connection with edit access.","tags":["Uploads"],"x-required-scope":"write","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"project_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The project the photos go into."},"files":{"minItems":1,"maxItems":25,"type":"array","items":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":255},"content_type":{"type":"string","minLength":1,"description":"image/jpeg, image/png, image/webp, image/heic or image/heif."},"size":{"type":"integer","exclusiveMinimum":0,"description":"Exact size in bytes."}},"required":["filename","content_type","size"]}}},"required":["project_id","files"]}}}},"responses":{"201":{"description":"Start a signed upload","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/uploads/{id}/complete":{"post":{"operationId":"complete_upload","summary":"Complete a signed upload","description":"Finish a signed upload: verifies each stored file (size, type and content) and adds it to the project as a photo. List every file that uploaded; files left out are discarded and their reserved room released. HEIC/HEIF files are converted to JPEG. Returns the new photos and a `failed` list with a reason per file.\n\nRequires a connection with edit access.","tags":["Uploads"],"x-required-scope":"write","parameters":[{"in":"path","name":"id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The upload id from POST /uploads."},"required":true,"description":"The upload id from POST /uploads."},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"project_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The same project_id used to create the upload."},"files":{"maxItems":25,"type":"array","items":{"type":"object","properties":{"storage_path":{"type":"string","minLength":1},"filename":{"type":"string","minLength":1,"maxLength":255},"size":{"type":"integer","exclusiveMinimum":0},"content_type":{"type":"string","minLength":1}},"required":["storage_path","filename","size","content_type"]}}},"required":["project_id","files"]}}}},"responses":{"200":{"description":"Complete a signed upload","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadCompletion"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/projects/{project_id}/upload-links":{"post":{"operationId":"create_upload_link","summary":"Create an upload link","description":"Create a private link (with a QR code) the user opens on their phone or computer to add photos to a project, with no login. Use it when the user needs to send photos you can't receive directly, such as photos on their phone. Share the url, or show the QR code, and tell the user the link works for 2 hours. Photos appear in the project as they upload. To follow progress, call get_project and read upload_link.status and upload_link.photos_received until status is done (the user tapped Done), or simply ask the user to tell you when they've finished.\n\nRequires a connection with edit access.","tags":["Uploads"],"x-required-scope":"write","parameters":[{"in":"path","name":"project_id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The project the photos go into."},"required":true,"description":"The project the photos go into."},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"Create an upload link","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadLink"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/edit-options":{"get":{"operationId":"list_edit_options","summary":"List edit options","description":"List every edit PropertyPixel can make, with the exact keys to pass to other tools: enhancement types for enhance_photos (combinable, e.g. blue_skies + improve_lighting), design styles and variation limits for stage_photos, room types, Photo to Video settings for create_video (1–9 photos; one makes a clip, several make a Listing Tour), the Ultra HD add-on, and credit prices. Call this when the user asks what you can do, or before choosing keys you are unsure of.\n\nWorks with view-only access.","tags":["Edit options"],"x-required-scope":"read","responses":{"200":{"description":"List edit options","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditOptions"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/enhancements":{"post":{"operationId":"enhance_photos","summary":"Enhance photos","description":"Apply AI edits (lighting, declutter, blue skies, day to dusk, furniture removal, and more) to listing photos. Costs 100 credits per photo, plus 100 per photo with ultra_hd. All enhancement_types are combined into one result per photo.\n\nSelect photos with photo_ids, or project_id + all_photos: true. Defaults: ultra_hd false; edits start from the original photo unless versions names a prior result.\n\nSpends credits in two steps. Call without quote_id first: you get a quote (cost, balance after, warnings) and nothing is spent. Show the cost to the user and wait for a yes, then call again with the same arguments plus quote_id. The quote lasts 10 minutes and only matches identical arguments.\n\nResults are asynchronous: this returns job IDs right away (status pending). Poll get_job_status with the job IDs, waiting poll_after_ms between calls, until each job is completed or failed. Failed jobs are refunded automatically.\n\nRequires a connection with edit access. Spends credits. Without `quote_id` it returns 409 `quote_required` with a quote and spends nothing. Resend with `quote_id` to run, or send `auto_confirm: true` to skip the quote.","tags":["Editing"],"x-required-scope":"write","x-spends-credits":true,"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"photo_ids":{"description":"The photos to use. Get IDs from get_project. Alternatively pass project_id with all_photos: true.","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"project_id":{"description":"The project the photos belong to. Required with all_photos; with photo_ids it must match their project.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"all_photos":{"description":"Use every photo in project_id instead of listing photo_ids.","type":"boolean"},"enhancement_types":{"minItems":1,"type":"array","items":{"$ref":"#/components/schemas/EnhancementType"},"description":"One or more edits to apply together in a single result, e.g. [\"improve_lighting\", \"blue_skies\"]. See list_edit_options for every type."},"room_type":{"description":"Set the room type on every selected photo first (helps some edits).","$ref":"#/components/schemas/RoomType"},"ultra_hd":{"default":false,"description":"Upscale each result to at least 4K, for 100 extra credits per result. Default false.","type":"boolean"},"versions":{"description":"Edit on top of a previous result instead of the original: map of photo_id → job_id of a completed job on that photo. Photos not listed use the original.","type":"object","propertyNames":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"additionalProperties":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"quote_id":{"description":"The id of a quote the user confirmed. Omit it to get a quote first; nothing is spent without one.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"auto_confirm":{"description":"REST with a personal API key only. Skip the quote step and spend immediately. For trusted scripts; ignored for app (OAuth) connections, which always get a quote.","type":"boolean"}},"required":["enhancement_types"]}}}},"responses":{"201":{"description":"Enhance photos","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobBatch"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientCredits"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/QuoteRequired"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/stagings":{"post":{"operationId":"stage_photos","summary":"Virtually stage photos","description":"Virtually stage rooms: furnish empty rooms or restyle furnished ones in a design_style. Costs 100 credits per variation per photo, plus 100 per variation with ultra_hd.\n\nSelect photos with photo_ids, or project_id + all_photos: true. Defaults: variations 1, ultra_hd false; staging starts from the original photo unless versions names a prior result (e.g. a decluttered one).\n\nSpends credits in two steps. Call without quote_id first: you get a quote (cost, balance after, warnings) and nothing is spent. Show the cost to the user and wait for a yes, then call again with the same arguments plus quote_id. The quote lasts 10 minutes and only matches identical arguments.\n\nResults are asynchronous: this returns job IDs right away (status pending). Poll get_job_status with the job IDs, waiting poll_after_ms between calls, until each job is completed or failed. Failed jobs are refunded automatically.\n\nRequires a connection with edit access. Spends credits. Without `quote_id` it returns 409 `quote_required` with a quote and spends nothing. Resend with `quote_id` to run, or send `auto_confirm: true` to skip the quote.","tags":["Editing"],"x-required-scope":"write","x-spends-credits":true,"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"photo_ids":{"description":"The photos to use. Get IDs from get_project. Alternatively pass project_id with all_photos: true.","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"project_id":{"description":"The project the photos belong to. Required with all_photos; with photo_ids it must match their project.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"all_photos":{"description":"Use every photo in project_id instead of listing photo_ids.","type":"boolean"},"design_style":{"description":"Furniture and decor style, e.g. modern or scandinavian. See list_edit_options.","$ref":"#/components/schemas/DesignStyle"},"variations":{"default":1,"description":"Different stagings to generate per photo (1–4). Default 1. Each one is charged.","type":"integer","minimum":1,"maximum":4},"ultra_hd":{"default":false,"description":"Upscale each result to at least 4K, for 100 extra credits per result. Default false.","type":"boolean"},"versions":{"description":"Edit on top of a previous result instead of the original: map of photo_id → job_id of a completed job on that photo. Photos not listed use the original.","type":"object","propertyNames":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"additionalProperties":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"quote_id":{"description":"The id of a quote the user confirmed. Omit it to get a quote first; nothing is spent without one.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"auto_confirm":{"description":"REST with a personal API key only. Skip the quote step and spend immediately. For trusted scripts; ignored for app (OAuth) connections, which always get a quote.","type":"boolean"}},"required":["design_style"]}}}},"responses":{"201":{"description":"Virtually stage photos","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobBatch"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientCredits"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/QuoteRequired"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/videos":{"post":{"operationId":"create_video","summary":"Create a video","description":"Turn listing photos into a video. One photo makes a Photo to Video clip; 2–9 photos make a Listing Tour, in the order given. Costs 400 credits per photo.\n\nDefaults: clip_seconds 3, aspect_ratio \"auto\"; each photo uses its original unless versions names an enhanced result.\n\nSpends credits in two steps. Call without quote_id first: you get a quote (cost, balance after, warnings) and nothing is spent. Show the cost to the user and wait for a yes, then call again with the same arguments plus quote_id. The quote lasts 10 minutes and only matches identical arguments.\n\nResults are asynchronous: this returns job IDs right away (status pending). Poll get_job_status with the job IDs, waiting poll_after_ms between calls, until each job is completed or failed. Failed jobs are refunded automatically. Videos take a few minutes.\n\nRequires a connection with edit access. Spends credits. Without `quote_id` it returns 409 `quote_required` with a quote and spends nothing. Resend with `quote_id` to run, or send `auto_confirm: true` to skip the quote.","tags":["Video"],"x-required-scope":"write","x-spends-credits":true,"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"project_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The project the photos belong to."},"photo_ids":{"description":"Photos in playback order, 1–9. One photo makes a short clip; several are joined into a Listing Tour with crossfades.","minItems":1,"maxItems":9,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"clip_seconds":{"default":3,"description":"Seconds of motion per photo (2, 3, 4, 5). Default 3.","$ref":"#/components/schemas/VideoClipSeconds"},"aspect_ratio":{"default":"auto","description":"Output shape. Default \"auto\", which follows the first photo.","$ref":"#/components/schemas/VideoAspectRatio"},"versions":{"description":"Edit on top of a previous result instead of the original: map of photo_id → job_id of a completed job on that photo. Photos not listed use the original.","type":"object","propertyNames":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"additionalProperties":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"quote_id":{"description":"The id of a quote the user confirmed. Omit it to get a quote first; nothing is spent without one.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"auto_confirm":{"description":"REST with a personal API key only. Skip the quote step and spend immediately. For trusted scripts; ignored for app (OAuth) connections, which always get a quote.","type":"boolean"}},"required":["project_id","photo_ids"]}}}},"responses":{"201":{"description":"Create a video","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobBatch"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientCredits"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/QuoteRequired"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/recommendations":{"post":{"operationId":"get_recommendations","summary":"Get edit recommendations","description":"Free. Ask PropertyPixel's AI which corrective edits each photo needs (e.g. improve_lighting, clean_and_tidy, straighten_and_reframe). Select photos with photo_ids, or project_id + all_photos: true.\n\nReturns the Recommendations that already exist and starts analysis for photos that have none. Analysis is asynchronous: photos in pending_photo_ids are still being analysed, so call again after poll_after_ms to see them. A daily analysis limit applies; photos over it are listed in skipped_photo_ids.\n\nTo run the suggestions, pass the ready Recommendation IDs to apply_recommendations (paid).\n\nRequires a connection with edit access.","tags":["Recommendations"],"x-required-scope":"write","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"photo_ids":{"description":"The photos to use. Get IDs from get_project. Alternatively pass project_id with all_photos: true.","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"project_id":{"description":"The project the photos belong to. Required with all_photos; with photo_ids it must match their project.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"all_photos":{"description":"Use every photo in project_id instead of listing photo_ids.","type":"boolean"}}}}}},"responses":{"200":{"description":"Get edit recommendations","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationList"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/recommendations/apply":{"post":{"operationId":"apply_recommendations","summary":"Apply recommendations","description":"Run ready Recommendations from get_recommendations as enhancement jobs: one job per photo with all its suggested edits. Costs 100 credits per Recommendation. Only status ready can be applied.\n\nSpends credits in two steps. Call without quote_id first: you get a quote and nothing is spent. Show the cost to the user and wait for a yes, then call again with the same arguments plus quote_id (valid 10 minutes).\n\nResults are asynchronous: poll get_job_status with the returned job IDs, waiting poll_after_ms between calls. Failed jobs are refunded automatically.\n\nRequires a connection with edit access. Spends credits. Without `quote_id` it returns 409 `quote_required` with a quote and spends nothing. Resend with `quote_id` to run, or send `auto_confirm: true` to skip the quote.","tags":["Recommendations"],"x-required-scope":"write","x-spends-credits":true,"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"recommendation_ids":{"description":"IDs of Recommendations with status ready, from get_recommendations.","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"quote_id":{"description":"The id of a quote the user confirmed. Omit it to get a quote first; nothing is spent without one.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"auto_confirm":{"description":"REST with a personal API key only. Skip the quote step and spend immediately. For trusted scripts; ignored for app (OAuth) connections, which always get a quote.","type":"boolean"}},"required":["recommendation_ids"]}}}},"responses":{"201":{"description":"Apply recommendations","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobBatch"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientCredits"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/QuoteRequired"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/jobs":{"get":{"operationId":"get_job_status","summary":"Check job status","description":"Check progress of up to 100 jobs returned by enhance_photos, stage_photos, apply_recommendations or create_video. Returns status (pending, processing, completed, failed, cancelled), progress, result URLs (signed for 1 hour) and a poll_after_ms hint. Photo edits usually finish in under a minute and videos in a few minutes; wait poll_after_ms between checks instead of calling in a tight loop. Failed jobs are refunded automatically.\n\nWorks with view-only access.","tags":["Jobs"],"x-required-scope":"read","parameters":[{"in":"query","name":"ids","schema":{"description":"Job IDs, as an array or comma-separated (max 100).","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":true,"description":"Job IDs, as an array or comma-separated (max 100)."}],"responses":{"200":{"description":"Check job status","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatusList"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/jobs/{id}":{"get":{"operationId":"get_job","summary":"Get a job","description":"Get one job's status, progress and result URL (signed for 1 hour).\n\nWorks with view-only access.","tags":["Jobs"],"x-required-scope":"read","parameters":[{"in":"path","name":"id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Job ID."},"required":true,"description":"Job ID."}],"responses":{"200":{"description":"Get a job","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/jobs/{id}/pick":{"patch":{"operationId":"pick_results","summary":"Pick a result","description":"Mark a finished photo or video version as a pick (picked: true) or remove the mark (picked: false). Picks are the versions the user wants to keep; get_download_link with picks_only downloads them together. Picks are shared by the workspace and never change or delete the versions themselves. Only completed enhancement, staging and video jobs can be picked.\n\nWorks with view-only access.","tags":["Jobs"],"x-required-scope":"read","parameters":[{"in":"path","name":"id","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Job ID of the finished version."},"required":true,"description":"Job ID of the finished version."},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"picked":{"type":"boolean","description":"True to pick, false to unpick."}},"required":["picked"]}}}},"responses":{"200":{"description":"Pick a result","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/downloads":{"post":{"operationId":"get_download_link","summary":"Get a download link","description":"Get download links for finished results. Pass job_ids (1–100 completed versions from one project), or project_id to download that project's picks (picks_only defaults to true; false downloads every finished version, up to 100). One version returns a signed link immediately. Several photos start a zip: status is processing, so call get_download with the returned id after poll_after_ms. If any videos are included you get one signed link per file in `files` instead of a zip. Links last 1 hour; trial accounts get watermarked files.\n\nWorks with view-only access.","tags":["Downloads"],"x-required-scope":"read","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"job_ids":{"description":"Completed job IDs from one project (max 100).","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"project_id":{"description":"Download from this project instead of listing job_ids.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"picks_only":{"default":true,"description":"With project_id: only the picked versions (default true).","type":"boolean"}}}}}},"responses":{"200":{"description":"Get a download link","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Download"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/downloads/{id}":{"get":{"operationId":"get_download","summary":"Check a zip download","description":"Check a zip started by get_download_link. While status is processing, wait poll_after_ms and call again; when ready, url is the zip (valid for 1 hour). If it failed, call get_download_link again.\n\nWorks with view-only access.","tags":["Downloads"],"x-required-scope":"read","parameters":[{"in":"path","name":"id","schema":{"type":"string","pattern":"^run_[A-Za-z0-9]+$","description":"Download ID from get_download_link."},"required":true,"description":"Download ID from get_download_link."}],"responses":{"200":{"description":"Check a zip download","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Download"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/quotes":{"post":{"operationId":"create_quote","summary":"Create a quote","description":"Price a spending request without running it. Pass the returned id as quote_id to the operation within 10 minutes.\n\nRequires a connection with edit access.","tags":["Quotes"],"x-required-scope":"write","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"operation":{"type":"string","enum":["enhance_photos","stage_photos","apply_recommendations","create_video"],"description":"The spending operation to price."},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The exact body you will send to that operation."}},"required":["operation","input"]}}}},"responses":{"201":{"description":"Create a quote","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}}},"components":{"schemas":{"ChatGptFile":{"type":"object","properties":{"download_url":{"description":"Temporary download URL supplied by ChatGPT.","type":"string"},"file_id":{"type":"string","description":"ChatGPT file ID."},"mime_type":{"type":["string","null"]},"file_name":{"type":["string","null"]}},"required":["file_id"]},"EnhancementType":{"type":"string","enum":["improve_lighting","clean_and_tidy","remove_furniture","blue_skies","day_to_dusk","lawn_repair","straighten_and_reframe","upscale","rain_to_shine","natural_twilight","remove_watermark","night_to_day","pool_water"]},"RoomType":{"type":"string","enum":["living_room","dining_room","kitchen","entrance","hallway","master_bedroom","bedroom","kids_bedroom","guest_bedroom","master_bathroom","bathroom","guest_bathroom","powder_room","office","study","laundry_room","storage_room","maid_room","closet","gym","home_theater","pool","balcony","terrace","patio","garden","rooftop","garage","parking","exterior_front","exterior_back","building_exterior","view","basement","other"]},"DesignStyle":{"type":"string","enum":["modern","contemporary","scandinavian","industrial","farmhouse","coastal","mid_century_modern","hamptons","luxury","minimalist","traditional","japandi","glam","bohemian"]},"VideoClipSeconds":{"type":"integer"},"VideoAspectRatio":{"type":"string","enum":["auto","16:9","9:16","1:1"]},"Account":{"type":"object","properties":{"object":{"type":"string","const":"account"},"email":{"type":["string","null"]},"workspace":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"kind":{"type":"string","enum":["personal","team"]},"role":{"type":"string","enum":["owner","editor","reviewer"]}},"required":["id","name","kind","role"],"additionalProperties":false},"scope":{"type":"object","properties":{"effective":{"type":"string","enum":["read","write"],"description":"What this connection can do now: `write` can create, delete and spend credits; `read` can only view, pick and download."},"granted":{"type":"string","enum":["read","write"],"description":"What was granted when connecting. Effective is lower only if the user's workspace role was reduced since."}},"required":["effective","granted"],"additionalProperties":false,"description":"Access level of this connection."},"credits":{"type":"object","properties":{"available":{"type":"integer","description":"Total credits that can be spent now."},"subscription":{"type":"integer"},"topup":{"type":"integer"},"trial":{"type":"integer"}},"required":["available","subscription","topup","trial"],"additionalProperties":false,"description":"100 credits = one standard photo enhancement."},"plan":{"type":"object","properties":{"tier":{"type":"string","description":"Plan name, e.g. starter, professional, studio or trial."},"status":{"type":"string","description":"trial, active, past_due, cancelled or expired."},"is_trial":{"type":"boolean"},"watermarked":{"type":"boolean","description":"True when results carry the PropertyPixel watermark."}},"required":["tier","status","is_trial","watermarked"],"additionalProperties":false},"manage_credits_url":{"description":"Where to add credits or change plan. Null inside ChatGPT.","type":["string","null"]},"studio_url":{"type":"string","format":"uri","description":"The PropertyPixel Studio, to open projects on the web."}},"required":["object","email","workspace","scope","credits","plan","manage_credits_url","studio_url"],"additionalProperties":false},"Problem":{"type":"object","properties":{"type":{"type":"string","format":"uri","description":"Link to the documentation for this error code."},"title":{"type":"string","description":"Short summary of the error code."},"status":{"type":"integer","description":"The HTTP status code."},"code":{"$ref":"#/components/schemas/ErrorCode"},"detail":{"type":"string","description":"What went wrong, in plain language."},"errors":{"description":"Per-field problems, for validation_failed.","type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"additionalProperties":false}},"retry_after":{"description":"Seconds to wait before retrying, for rate_limited.","type":"integer"}},"required":["type","title","status","code","detail"],"additionalProperties":false,"description":"An RFC 9457 problem details object (`application/problem+json`)."},"ErrorCode":{"type":"string","enum":["unauthorized","forbidden_scope","forbidden","not_found","validation_failed","insufficient_credits","quote_required","quote_expired","quote_mismatch","idempotency_conflict","idempotency_in_progress","conflict","rate_limited","upload_rejected","internal"],"description":"Stable machine-readable error code."},"Project":{"type":"object","properties":{"object":{"type":"string","const":"project"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"address":{"type":["string","null"]},"property_type":{"type":["string","null"]},"photo_count":{"type":"integer"},"completed_job_count":{"type":"integer"},"cover":{"anyOf":[{"$ref":"#/components/schemas/MediaUrl"},{"type":"null"}]},"studio_url":{"type":"string","format":"uri","description":"Open this project in the PropertyPixel Studio."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"updated_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]}},"required":["object","id","name","address","property_type","photo_count","completed_job_count","cover","studio_url","created_at","updated_at"],"additionalProperties":false},"MediaUrl":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"Signed URL expiry (about 1 hour). Re-fetch for a fresh URL."}},"required":["url","expires_at"],"additionalProperties":false},"ProjectDetail":{"type":"object","properties":{"object":{"type":"string","const":"project"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"address":{"type":["string","null"]},"property_type":{"type":["string","null"]},"photo_count":{"type":"integer"},"completed_job_count":{"type":"integer"},"cover":{"anyOf":[{"$ref":"#/components/schemas/MediaUrl"},{"type":"null"}]},"studio_url":{"type":"string","format":"uri","description":"Open this project in the PropertyPixel Studio."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"updated_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"photos":{"type":"array","items":{"$ref":"#/components/schemas/Photo"}},"upload_link":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"$ref":"#/components/schemas/UploadLinkStatus"},"photos_received":{"type":"integer"},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["id","status","photos_received","expires_at"],"additionalProperties":false},{"type":"null"}],"description":"The most recent upload link for this project, if any. The URL is only returned when the link is created."}},"required":["object","id","name","address","property_type","photo_count","completed_job_count","cover","studio_url","created_at","updated_at","photos","upload_link"],"additionalProperties":false},"Photo":{"type":"object","properties":{"object":{"type":"string","const":"photo"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"project_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"filename":{"type":["string","null"]},"room_type":{"type":["string","null"]},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"original":{"anyOf":[{"$ref":"#/components/schemas/MediaUrl"},{"type":"null"}]},"thumbnail":{"anyOf":[{"$ref":"#/components/schemas/MediaUrl"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["object","id","project_id","filename","room_type","width","height","original","thumbnail","created_at"],"additionalProperties":false},"UploadLinkStatus":{"type":"string","enum":["waiting","receiving","done","expired"]},"DeletedProject":{"type":"object","properties":{"object":{"type":"string","const":"project"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"deleted":{"type":"boolean","const":true},"photos_deleted":{"type":"integer"}},"required":["object","id","deleted","photos_deleted"],"additionalProperties":false},"Results":{"type":"object","properties":{"object":{"type":"string","const":"results"},"project":{"$ref":"#/components/schemas/Project"},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/Job"},"description":"Jobs still running, the newest finished version of each photo and video, and every pick (newest first)."}},"required":["object","project","jobs"],"additionalProperties":false},"Job":{"type":"object","properties":{"object":{"type":"string","const":"job"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"$ref":"#/components/schemas/JobKind"},"status":{"$ref":"#/components/schemas/JobStatus"},"progress":{"anyOf":[{"type":"number","minimum":0,"maximum":100},{"type":"null"}],"description":"Percent complete while processing."},"stage":{"type":["string","null"]},"project_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"photo_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Source photo (null for multi-photo videos)."},"photo_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"All source photos, in order (videos can have up to 9)."},"source_job_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Prior version this edit was applied on top of."},"enhancement_types":{"type":"array","items":{"type":"string"}},"design_style":{"type":["string","null"]},"ultra_hd":{"type":"boolean"},"credits":{"type":["integer","null"]},"picked":{"type":"boolean"},"watermarked":{"type":"boolean"},"result":{"anyOf":[{"$ref":"#/components/schemas/MediaUrl"},{"type":"null"}],"description":"The finished image or video, when completed."},"thumbnail":{"anyOf":[{"$ref":"#/components/schemas/MediaUrl"},{"type":"null"}]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}],"description":"Why the job failed. Failed jobs are refunded automatically."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"completed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]}},"required":["object","id","kind","status","progress","stage","project_id","photo_id","photo_ids","source_job_id","enhancement_types","design_style","ultra_hd","credits","picked","watermarked","result","thumbnail","error","created_at","completed_at"],"additionalProperties":false},"JobKind":{"type":"string","enum":["enhancement","staging","video"]},"JobStatus":{"type":"string","enum":["pending","processing","completed","failed","cancelled"]},"PhotoList":{"type":"object","properties":{"object":{"type":"string","const":"photo_list"},"photos":{"type":"array","items":{"$ref":"#/components/schemas/Photo"}},"failed":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","description":"The URL or file name that failed."},"error":{"type":"string"}},"required":["source","error"],"additionalProperties":false}},"project_photo_count":{"type":"integer","description":"Photos now in the project (max 100)."}},"required":["object","photos","failed","project_photo_count"],"additionalProperties":false},"PhotoDeletion":{"type":"object","properties":{"object":{"type":"string","const":"deletion"},"deleted_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"project_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["object","deleted_ids","project_id"],"additionalProperties":false},"Upload":{"type":"object","properties":{"object":{"type":"string","const":"upload"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Pass to POST /uploads/{id}/complete."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"files":{"type":"array","items":{"type":"object","properties":{"filename":{"type":"string"},"upload_url":{"type":"string","format":"uri"},"method":{"type":"string","const":"PUT"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"storage_path":{"type":"string"}},"required":["filename","upload_url","method","headers","storage_path"],"additionalProperties":false}},"failed":{"type":"array","items":{"type":"object","properties":{"filename":{"type":"string"},"error":{"type":"string"}},"required":["filename","error"],"additionalProperties":false},"description":"Files rejected before upload (type or size)."}},"required":["object","id","expires_at","files","failed"],"additionalProperties":false},"UploadCompletion":{"type":"object","properties":{"object":{"type":"string","const":"photo_list"},"photos":{"type":"array","items":{"$ref":"#/components/schemas/Photo"}},"failed":{"type":"array","items":{"type":"object","properties":{"filename":{"type":"string"},"error":{"type":"string"}},"required":["filename","error"],"additionalProperties":false}}},"required":["object","photos","failed"],"additionalProperties":false},"UploadLink":{"type":"object","properties":{"object":{"type":"string","const":"upload_link"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"url":{"type":"string","format":"uri","description":"Share this with the user. It opens a page that adds photos to the project, with no login. Treat it like a password."},"qr_svg":{"type":"string","description":"The same URL as a QR code (SVG markup), for scanning with a phone."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"status":{"$ref":"#/components/schemas/UploadLinkStatus"},"photos_received":{"type":"integer"},"max_photos":{"type":"integer","description":"How many photos this link accepts (the project's free space)."},"project_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["object","id","url","qr_svg","expires_at","status","photos_received","max_photos","project_id"],"additionalProperties":false},"EditOptions":{"type":"object","properties":{"object":{"type":"string","const":"edit_options"},"enhancement_types":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"preview_url":{"type":"string","format":"uri"}},"required":["key","label","description","preview_url"],"additionalProperties":false},"description":"Edits for enhance_photos. Combine several in one request; the price is per photo, not per type."},"design_styles":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"preview_url":{"type":"string","format":"uri"}},"required":["key","label","description","preview_url"],"additionalProperties":false},"description":"Furniture styles for stage_photos."},"room_types":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"}},"required":["key","label"],"additionalProperties":false},"description":"Room labels; staging furnishes the room as this type."},"staging":{"type":"object","properties":{"min_variations":{"type":"integer"},"max_variations":{"type":"integer"},"default_variations":{"type":"integer"}},"required":["min_variations","max_variations","default_variations"],"additionalProperties":false},"video":{"type":"object","properties":{"min_photos":{"type":"integer"},"max_photos":{"type":"integer"},"clip_seconds":{"type":"array","items":{"type":"integer"},"description":"Allowed seconds per photo."},"default_clip_seconds":{"type":"integer"},"aspect_ratios":{"type":"array","items":{"type":"string"},"description":"`auto` matches the first photo's orientation."},"default_aspect_ratio":{"type":"string"},"crossfade_seconds":{"type":"number"}},"required":["min_photos","max_photos","clip_seconds","default_clip_seconds","aspect_ratios","default_aspect_ratio","crossfade_seconds"],"additionalProperties":false},"ultra_hd":{"type":"object","properties":{"description":{"type":"string"},"credits_per_photo":{"type":"integer"}},"required":["description","credits_per_photo"],"additionalProperties":false},"credit_costs":{"type":"object","properties":{"enhancement_per_photo":{"type":"integer"},"ultra_hd_per_photo":{"type":"integer"},"staging_per_variation":{"type":"integer"},"video_per_photo":{"type":"integer"},"recommendation_apply_per_photo":{"type":"integer"},"recommendations":{"type":"integer","description":"Getting recommendations is free."}},"required":["enhancement_per_photo","ultra_hd_per_photo","staging_per_variation","video_per_photo","recommendation_apply_per_photo","recommendations"],"additionalProperties":false,"description":"Credits per unit. 100 credits = one standard photo enhancement."}},"required":["object","enhancement_types","design_styles","room_types","staging","video","ultra_hd","credit_costs"],"additionalProperties":false},"JobBatch":{"type":"object","properties":{"object":{"type":"string","const":"job_batch"},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/Job"}},"failed":{"type":"array","items":{"type":"object","properties":{"photo_id":{"type":"string"},"error":{"type":"string"}},"required":["photo_id","error"],"additionalProperties":false}},"credits_spent":{"type":"integer"},"poll_after_ms":{"type":"integer","description":"Suggested wait before calling get_job_status."}},"required":["object","jobs","failed","credits_spent","poll_after_ms"],"additionalProperties":false},"QuoteProblem":{"type":"object","properties":{"type":{"type":"string","format":"uri","description":"Link to the documentation for this error code."},"title":{"type":"string","description":"Short summary of the error code."},"status":{"type":"integer","description":"The HTTP status code."},"code":{"$ref":"#/components/schemas/ErrorCode"},"detail":{"type":"string","description":"What went wrong, in plain language."},"errors":{"description":"Per-field problems, for validation_failed.","type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"additionalProperties":false}},"retry_after":{"description":"Seconds to wait before retrying, for rate_limited.","type":"integer"},"quote":{"description":"Present for quote_required: the price of this exact request.","$ref":"#/components/schemas/Quote"}},"required":["type","title","status","code","detail"],"additionalProperties":false,"description":"A 409 from a spending operation. With code quote_required, `quote` holds the price; resend the same request with its `quote_id` to run it."},"RecommendationList":{"type":"object","properties":{"object":{"type":"string","const":"recommendation_list"},"recommendations":{"type":"array","items":{"$ref":"#/components/schemas/Recommendation"}},"pending_photo_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Photos still being analysed. Call again after poll_after_ms."},"skipped_photo_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Photos with no Recommendation that could not be queued now (daily analysis limit reached, or the photo is not in a project)."},"poll_after_ms":{"type":"integer","description":"Wait this long before calling again; 0 when nothing is pending."}},"required":["object","recommendations","pending_photo_ids","skipped_photo_ids","poll_after_ms"],"additionalProperties":false},"Recommendation":{"type":"object","properties":{"object":{"type":"string","const":"recommendation"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"photo_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"project_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status":{"$ref":"#/components/schemas/RecommendationStatus"},"enhancement_types":{"type":"array","items":{"type":"string"},"description":"The edits that applying this Recommendation runs."},"room_type":{"description":"The photo's room type, if known.","type":["string","null"]},"summary":{"type":"string","description":"One line describing the Recommendation."},"job_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The enhancement job created when it was applied."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["object","id","photo_id","project_id","status","enhancement_types","room_type","summary","job_id","created_at"],"additionalProperties":false},"RecommendationStatus":{"type":"string","enum":["pending","ready","no_changes","applied","dismissed","failed"],"description":"pending: still analysing. ready: can be applied. no_changes: the photo needs no corrective edits. applied: already turned into a job (see job_id). dismissed: the user dismissed it in the Studio. failed: analysis failed."},"JobStatusList":{"type":"object","properties":{"object":{"type":"string","const":"job_status"},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/Job"},"description":"The requested jobs in request order. IDs you can't access are left out."},"all_done":{"type":"boolean","description":"True when every job is completed, failed or cancelled."},"poll_after_ms":{"type":"integer","description":"Wait this long before polling again. 0 means nothing is left to wait for."}},"required":["object","jobs","all_done","poll_after_ms"],"additionalProperties":false},"Download":{"type":"object","properties":{"object":{"type":"string","const":"download"},"id":{"description":"Zip download ID to poll with get_download while status is processing. Null when the links are ready immediately.","type":["string","null"]},"status":{"type":"string","enum":["processing","ready","failed"]},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"The file to download: the single version, or the zip once ready. Null while processing, and when files lists per-file links instead."},"filename":{"type":["string","null"]},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"When url stops working."},"files":{"type":"array","items":{"type":"object","properties":{"job_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string","enum":["photo","video"]},"filename":{"type":"string"},"url":{"type":"string","format":"uri"},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["job_id","kind","filename","url","expires_at"],"additionalProperties":false},"description":"One signed link per file. Used instead of a zip whenever videos are included (videos are too large to zip server-side)."},"file_count":{"type":["integer","null"]},"unavailable_job_ids":{"type":"array","items":{"type":"string"},"description":"Requested versions left out because they were deleted, unfinished or failed to package."},"poll_after_ms":{"type":"integer","description":"0 unless status is processing."}},"required":["object","id","status","url","filename","expires_at","files","file_count","unavailable_job_ids","poll_after_ms"],"additionalProperties":false},"Quote":{"type":"object","properties":{"object":{"type":"string","const":"quote"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"operation":{"type":"string","description":"The operation this quote prices, e.g. enhance_photos."},"credits":{"type":"integer","description":"Total credits the request will spend."},"balance":{"type":"object","properties":{"available":{"type":"integer"},"after":{"type":"integer"}},"required":["available","after"],"additionalProperties":false},"sufficient":{"type":"boolean","description":"False when the balance can't cover the request."},"description":{"type":"string"},"lines":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"quantity":{"type":"integer"},"unit_credits":{"type":"integer"}},"required":["label","quantity","unit_credits"],"additionalProperties":false}},"watermarked":{"type":"boolean","description":"True for trial accounts: results carry a watermark."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"manage_credits_url":{"description":"Where to add credits. Null inside ChatGPT.","type":["string","null"]},"confirm_instructions":{"type":"string"}},"required":["object","id","operation","credits","balance","sufficient","description","lines","watermarked","expires_at","manage_credits_url","confirm_instructions"],"additionalProperties":false}},"headers":{"RateLimitLimit":{"required":true,"description":"Requests allowed per window.","schema":{"type":"integer","description":"Requests allowed per window."}},"RateLimitRemaining":{"required":true,"description":"Requests left in this window.","schema":{"type":"integer","description":"Requests left in this window."}},"RateLimitReset":{"required":true,"description":"Seconds until the window resets.","schema":{"type":"integer","description":"Seconds until the window resets."}},"RetryAfter":{"required":true,"description":"Seconds to wait before retrying.","schema":{"type":"integer","description":"Seconds to wait before retrying."}}},"responses":{"BadRequest":{"description":"The request is invalid. Codes: `validation_failed`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Unauthorized":{"description":"Missing, invalid or revoked credential. Codes: `unauthorized`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Forbidden":{"description":"The credential can't do this. View-only connections get forbidden_scope on writes. Codes: `forbidden_scope`, `forbidden`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"NotFound":{"description":"The resource doesn't exist in this workspace. Codes: `not_found`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"RateLimited":{"description":"Too many requests for this connection. Codes: `rate_limited`.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"InternalError":{"description":"Something failed on our side. Retry later. Codes: `internal`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Conflict":{"description":"The request conflicts with the current state. Codes: `conflict`, `idempotency_in_progress`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Unprocessable":{"description":"An Idempotency-Key was reused with a different body, or an upload was rejected. Codes: `idempotency_conflict`, `upload_rejected`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"InsufficientCredits":{"description":"The workspace does not have enough credits. Codes: `insufficient_credits`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"QuoteRequired":{"description":"This request spends credits and has no valid quote. Codes: `quote_required` (the body's `quote` holds the price), `quote_expired`, `quote_mismatch`, `idempotency_in_progress`, `conflict`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/QuoteProblem"}}}}},"parameters":{"IdempotencyKey":{"in":"header","name":"Idempotency-Key","schema":{"description":"A unique key (for example a UUID) that makes retries safe. A retry with the same key and body returns the stored response; the same key with a different body returns 422. Keys last 24 hours.","type":"string","maxLength":255},"description":"A unique key (for example a UUID) that makes retries safe. A retry with the same key and body returns the stored response; the same key with a different body returns 422. Keys last 24 hours."}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"pp_live_…","description":"An API key from Settings → Developers (`pp_live_…`), or an OAuth access token."},"oauth2":{"type":"oauth2","description":"OAuth 2.1 with PKCE, for apps acting for a user. The user picks a workspace and access level on the consent screen.","flows":{"authorizationCode":{"authorizationUrl":"https://llflgtovnkrsjqydycyu.supabase.co/auth/v1/oauth/authorize","tokenUrl":"https://llflgtovnkrsjqydycyu.supabase.co/auth/v1/oauth/token","scopes":{}}}}}}}