{"openapi":"3.1.0","info":{"title":"HumanPen API","version":"0.1.0","description":"Create asynchronous document-processing jobs, monitor progress, and download the editable results."},"servers":[{"url":"https://api.humanpen.net/v1"}],"security":[{"bearerAuth":[]}],"paths":{"/health":{"get":{"operationId":"getHealth","summary":"Get API liveness details","security":[],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/Health"}}}}}}}}},"/ready":{"get":{"operationId":"getReadiness","summary":"Get dependency readiness details","security":[],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/Readiness"}}}}}},"503":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/Readiness"}}}}}}}}},"/credits/balance":{"get":{"operationId":"getCreditBalance","summary":"Check the credit balance","description":"Credits available to spend, and how many are reserved by jobs still running.","responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/CreditBalance"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/credits/rates":{"get":{"operationId":"getCreditRates","summary":"Read the per-operation credit rates","description":"What each operation costs, so a caller can estimate a job before submitting it.","responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/CreditRates"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/detect-reports/parse":{"post":{"operationId":"parseDetectionReport","summary":"Parse an AI-detection report","description":"Reads a Turnitin or iThenticate AI Writing report: returns the overall AI percentage and the flagged passages, without retaining the uploaded PDF. Pass the segment text as selected_texts when creating a job to rewrite only those passages.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"The AI Writing report PDF to parse. The uploaded bytes are not retained."},"type":{"type":"string","enum":["turnitin","ithenticate"],"description":"Which product exported the report. Optional - omit it and the report is identified from its own contents."}}}}}},"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/DetectionReportParseResult"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"415":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/auth/me":{"get":{"operationId":"getCurrentUser","summary":"Get the authenticated principal and synchronized business-side user state","responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/CurrentUser"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/auth/session/sync":{"post":{"operationId":"syncCurrentUserSession","summary":"Create or update the business-side user mirror for an interactive session","responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/CurrentUser"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/auth/me/locale":{"patch":{"operationId":"updateCurrentUserLocale","summary":"Update the current user preferred locale","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLocaleRequest"}}}},"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/CurrentUserLocale"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/auth/me/usage":{"get":{"operationId":"getCurrentUserUsage","summary":"Get current-user document usage and configured quotas","description":"Returns cumulative usage, polish-job status totals, and the active limits applied to this API principal.","responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/UserUsageSummary"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/files":{"post":{"operationId":"createSourceFile","summary":"Upload a source document and extract document metadata","description":"Interactive web sessions only. Creates a staged source file for settings confirmation. API keys receive API_KEY_STANDALONE_UPLOAD_FORBIDDEN and must post the document directly to a create-job endpoint instead.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"DOCX file to store as the source document."}}}}}},"responses":{"201":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/SourceFileUpload"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"415":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"operationId":"listFiles","summary":"List current user files","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/FileList"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/files/{file_id}/preview":{"get":{"operationId":"getFilePreview","summary":"Get stored file preview text","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/FilePreview"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/files/{file_id}/selected-texts/validate":{"post":{"operationId":"validateSelectedTexts","summary":"Validate selected passages against a staged document","description":"Runs the same deterministic matcher the workers use, and returns the full paragraph each passage resolves to. No model is called and no job is created.","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateSelectedTextsRequest"}}}},"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/SelectedTextValidationResult"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/files/{file_id}/download-url":{"get":{"operationId":"createFileDownloadUrl","summary":"Create a short-lived download link (returns JSON, not the file)","description":"Returns a time-limited URL for a file this account owns. The URL downloads with a plain GET and carries no credentials of yours, so treat it as a secret while it lives.","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"expires_seconds","in":"query","required":false,"schema":{"type":"integer","minimum":60,"maximum":3600,"default":300},"description":"How long the link stays valid, in seconds. Defaults to 300 (5 minutes)."}],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/FileDownload"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/files/{file_id}/content":{"get":{"operationId":"downloadFileContent","summary":"Download the file bytes through the API","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Stored DOCX file bytes","headers":{"Content-Disposition":{"schema":{"type":"string"}},"Content-Length":{"schema":{"type":"integer"}}},"content":{"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/files/{file_id}":{"delete":{"operationId":"deleteFile","summary":"Delete a stored file and revoke future access","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/FileAssetSummary"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/jobs/humanize":{"post":{"operationId":"createHumanizeJob","summary":"Upload a DOCX and create a humanization job","description":"API-key callers must send multipart form data containing the DOCX and options; JSON returns API_KEY_MULTIPART_REQUIRED. turnitin_file is optional. If selected_texts is omitted, detected report passages become the polishing scope. If selected_texts is supplied, that explicit list is final and the private report is retained only as a job attachment. Interactive web sessions may use a staged source_file_id.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateHumanizeJobMultipartRequest"},"encoding":{"selected_texts":{"style":"form","explode":true}}},"application/json":{"schema":{"$ref":"#/components/schemas/CreateHumanizeJobFromFileRequest"}}}},"responses":{"201":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/JobReceipt"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"415":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/jobs/citation-format-correction":{"post":{"operationId":"createCitationFormatCorrectionJob","summary":"Create a citation-format correction job","description":"API-key callers send multipart form data with the document in `file` plus the options; JSON returns API_KEY_MULTIPART_REQUIRED. Interactive sessions may instead stage the document with POST /files and pass the returned source_file_id as JSON. Rewrites in-text citations and the reference list into the target style; the body text is left unchanged.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateCitationFormatCorrectionJobMultipartRequest"}},"application/json":{"schema":{"$ref":"#/components/schemas/CreateCitationFormatCorrectionJobFromFileRequest"}}}},"responses":{"201":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/JobReceipt"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/jobs/condense":{"post":{"operationId":"createCondenseJob","summary":"Create a condense job","description":"API-key callers send multipart form data with the document in `file` plus the options; JSON returns API_KEY_MULTIPART_REQUIRED. Interactive sessions may instead stage the document with POST /files and pass the returned source_file_id as JSON. Shortens the whole document to max_words, or shortens only the passages given in segments, each to its own budget. A passage is resolved to the paragraph containing it.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateCondenseJobMultipartRequest"}},"application/json":{"schema":{"$ref":"#/components/schemas/CreateCondenseJobFromFileRequest"}}}},"responses":{"201":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/JobReceipt"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/jobs/translate":{"post":{"operationId":"createTranslateJob","summary":"Create a document translation job","description":"API-key callers send multipart form data with the document in `file` plus the options; JSON returns API_KEY_MULTIPART_REQUIRED. Interactive sessions may instead stage the document with POST /files and pass the returned source_file_id as JSON. Translates the document into target_lang, keeping the source formatting and returning the same file format.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateTranslateJobMultipartRequest"}},"application/json":{"schema":{"$ref":"#/components/schemas/CreateTranslateJobFromFileRequest"}}}},"responses":{"201":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/JobReceipt"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/jobs":{"get":{"operationId":"listJobs","summary":"List current user jobs","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}},{"name":"type","in":"query","required":false,"description":"Filter by job type.","schema":{"type":"string","enum":["humanize","citation_format_correction","condense","translate"]}}],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/JobList"}}}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/jobs/{job_id}":{"get":{"operationId":"getJob","summary":"Get one job and temporary download URLs","description":"Only job_id is required. Poll every 5 seconds or so, backing off toward 30 seconds - jobs typically take minutes - and stop when finished is true. Once the result is available its download_url works with a plain GET, no Authorization header; it expires quickly, so fetch the job again if it lapsed.","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/Job"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/jobs/{job_id}/cancel":{"post":{"operationId":"cancelJob","summary":"Cancel a queued or running job","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/Job"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/jobs/{job_id}/retry":{"post":{"operationId":"retryJob","summary":"Retry a failed or cancelled job","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/Job"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api-keys":{"get":{"operationId":"listApiKeys","summary":"List API keys for the current interactive user","responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/ApiKeyList"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"post":{"operationId":"createApiKey","summary":"Create an API key for server-to-server use","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}}},"responses":{"201":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/ApiKeyCreated"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api-keys/{api_key_id}":{"delete":{"operationId":"revokeApiKey","summary":"Revoke one API key","parameters":[{"name":"api_key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Standard JSON envelope","content":{"application/json":{"schema":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string","example":"OK"},"message":{"type":"string","example":"ok"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"$ref":"#/components/schemas/ApiKey"}}}}}},"401":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Use a Logto access token or an API key secret prefixed with hp_."}},"schemas":{"ErrorEnvelope":{"type":"object","required":["code","message","data"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string","description":"Request correlation id also returned as X-Request-ID."},"data":{"type":"null"}}},"Health":{"type":"object","additionalProperties":true},"Readiness":{"type":"object","additionalProperties":true},"SourceFileUpload":{"type":"object","required":["file_id","filename","mime_type","size_bytes","sha256","n_chars","n_words","n_tokens","paragraph_count","table_count","detected_language","preview_text"],"properties":{"file_id":{"type":"string","format":"uuid","description":"Stable source file id used by the interactive staged-file flow."},"filename":{"type":"string","description":"Original client filename.","example":"paper.docx"},"mime_type":{"type":"string","description":"Detected document MIME type.","example":"application/vnd.openxmlformats-officedocument.wordprocessingml.document"},"size_bytes":{"type":"integer","description":"Uploaded file size in bytes."},"sha256":{"type":"string","description":"Hex-encoded SHA-256 digest of the uploaded bytes."},"n_chars":{"type":"integer","description":"Extracted document character count."},"n_words":{"type":"integer","description":"Extracted document word count."},"n_tokens":{"type":"integer","description":"Estimated model token count using the configured tokenizer."},"paragraph_count":{"type":"integer","description":"Number of DOCX paragraphs inspected."},"table_count":{"type":"integer","description":"Number of DOCX tables inspected."},"detected_language":{"type":"string","description":"Best-effort BCP 47-style language code."},"preview_text":{"type":"string","description":"Plain-text preview extracted from the source document."}}},"CurrentUser":{"type":"object","required":["subject","scopes","role","is_admin"],"properties":{"subject":{"type":"string","description":"Stable identity subject from the identity provider."},"email":{"type":["string","null"],"format":"email","description":"Account email, when the identity provider supplies one."},"name":{"type":["string","null"],"description":"Display name, when set."},"scopes":{"type":"array","items":{"type":"string"},"description":"Scopes this credential carries."},"role":{"type":"string","enum":["user","admin"],"description":"Business role of the account."},"is_admin":{"type":"boolean","description":"Whether the account may reach the admin console."},"locale":{"anyOf":[{"type":"string","enum":["en","zh-CN"]},{"type":"null"}],"description":"Preferred interface language."}}},"UpdateLocaleRequest":{"type":"object","required":["locale"],"properties":{"locale":{"type":"string","enum":["en","zh-CN"],"description":"Interface language to store for this account."}}},"CurrentUserLocale":{"type":"object","required":["subject","locale"],"properties":{"subject":{"type":"string","description":"Identity subject the preference belongs to."},"locale":{"type":"string","enum":["en","zh-CN"],"description":"Stored interface language."}}},"FileList":{"type":"object","required":["items","total","limit","offset","has_more"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/FileAssetSummary"},"description":"Files owned by the caller, newest first."},"total":{"type":"integer","minimum":0,"description":"Total files matching the query."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Page size used for this response."},"offset":{"type":"integer","minimum":0,"description":"Number of items skipped before this page."},"has_more":{"type":"boolean","description":"Whether further pages exist."}}},"DocumentInfoSummary":{"type":"object","required":["n_chars","n_words","n_tokens","detected_language","paragraph_count","table_count","preview_text"],"properties":{"n_chars":{"type":"integer","description":"Character count extracted from the document."},"n_words":{"type":"integer","description":"Word count in the billing ruler."},"n_tokens":{"type":"integer","description":"Estimated token count; an internal size hint, not a billing figure."},"detected_language":{"type":"string","description":"Language detected in the document text."},"paragraph_count":{"type":["integer","null"],"description":"Number of paragraphs found."},"table_count":{"type":["integer","null"],"description":"Number of tables found."},"preview_text":{"type":"string","description":"Leading text of the document, for confirming the right file was uploaded."}}},"FileAssetSummary":{"type":"object","required":["file_id","kind","filename","mime_type","ext","size_bytes","sha256","deleted_at","deleted_reason","created_at","document_info"],"properties":{"file_id":{"type":"string","format":"uuid","description":"Stored file identifier."},"kind":{"type":"string","description":"File role, such as source or polished."},"filename":{"type":"string","description":"Original filename as uploaded."},"mime_type":{"type":"string","description":"MIME type recorded at upload."},"ext":{"type":"string","description":"File extension, including the dot."},"size_bytes":{"type":"integer","description":"Stored size in bytes."},"sha256":{"type":"string","description":"SHA-256 of the file contents, for de-duplication and integrity checks."},"deleted_at":{"type":["string","null"],"format":"date-time","description":"When the file stopped being downloadable; null while it is live."},"deleted_reason":{"type":["string","null"],"description":"Why the file went away, e.g. retention_expired."},"created_at":{"type":["string","null"],"format":"date-time","description":"When the file stopped being downloadable; null while it is live."},"document_info":{"anyOf":[{"$ref":"#/components/schemas/DocumentInfoSummary"},{"type":"null"}],"description":"Extracted document metadata, when the file was inspected."}}},"FilePreview":{"type":"object","required":["file_id","filename","kind","preview_text","n_chars","n_words","n_tokens","detected_language"],"properties":{"file_id":{"type":"string","format":"uuid","description":"Stored file identifier."},"filename":{"type":"string","description":"Original filename."},"kind":{"type":"string","description":"Which role this file plays: source, result, or detection report."},"preview_text":{"type":"string","description":"Extracted preview text."},"n_chars":{"type":"integer","description":"Character count of the document."},"n_words":{"type":"integer","description":"Word count in the billing ruler."},"n_tokens":{"type":"integer","description":"Estimated token count."},"detected_language":{"type":"string","description":"Language detected in the text."}}},"ValidateSelectedTextsRequest":{"additionalProperties":false,"description":"Passages to match against one staged source DOCX.","properties":{"selected_texts":{"description":"Source passages to locate in the staged DOCX.","items":{"maxLength":20000,"minLength":1,"type":"string"},"maxItems":500,"minItems":1,"title":"Selected Texts","type":"array"}},"required":["selected_texts"],"title":"ValidateSelectedTextsRequest","type":"object"},"SelectedTextValidationItem":{"type":"object","required":["index","status","match_mode","match_count"],"properties":{"index":{"type":"integer","minimum":0,"description":"Zero-based index in the submitted selected_texts array."},"status":{"type":"string","enum":["matched","ambiguous","not_found","invalid_query"],"description":"Deterministic matcher outcome. matched and ambiguous are accepted for job creation."},"match_mode":{"type":["string","null"],"enum":["normalized_exact","alnum_only",null],"description":"Normalization mode that produced the match, or null when no match was found."},"match_count":{"type":"integer","minimum":0,"description":"Number of source locations matched by this passage."}}},"SelectedTextValidationSummary":{"type":"object","required":["total","matched","unmatched"],"properties":{"total":{"type":"integer","minimum":1,"description":"Number of submitted passages."},"matched":{"type":"integer","minimum":0,"description":"Number of accepted matches."},"unmatched":{"type":"integer","minimum":0,"description":"Number of passages that must be corrected."}}},"SelectedTextValidationResult":{"type":"object","required":["file_id","valid","items","summary"],"properties":{"file_id":{"type":"string","format":"uuid","description":"Validated staged source DOCX identifier."},"valid":{"type":"boolean","description":"Whether every submitted passage can enter a job."},"items":{"type":"array","description":"Per-passage results in request order.","items":{"$ref":"#/components/schemas/SelectedTextValidationItem"}},"summary":{"$ref":"#/components/schemas/SelectedTextValidationSummary"}}},"FileDownload":{"type":"object","required":["file_id","filename","url","expires_seconds"],"properties":{"file_id":{"type":"string","format":"uuid","description":"Requested stored file identifier."},"filename":{"type":"string","description":"Suggested download filename."},"url":{"type":"string","format":"uri","description":"Short-lived signed or proxied download URL."},"expires_seconds":{"type":"integer","description":"Number of seconds before the URL expires."}}},"DetectionProblemSegment":{"type":"object","required":["text","page_number","problem_types"],"properties":{"text":{"type":"string","description":"The flagged passage, exactly as it appears in the document."},"page_number":{"type":"integer","minimum":1,"description":"1-based page of the report the passage was found on."},"problem_types":{"type":"array","items":{"type":"string","enum":["ai_written","ai_paraphrased"]},"description":"What the detector flagged this passage as."}}},"CreditBalance":{"type":"object","required":["balance","frozen_balance","available_balance","next_expiry","credits_enabled"],"properties":{"balance":{"type":"integer","description":"Credits owned: what is spendable plus what jobs have reserved."},"frozen_balance":{"type":"integer","description":"Credits reserved by jobs that have not finished."},"available_balance":{"type":"integer","description":"Credits that can be spent right now."},"next_expiry":{"type":["string","null"],"format":"date-time","description":"When the file stopped being downloadable; null while it is live."},"credits_enabled":{"type":"boolean","description":"Whether this deployment charges credits at all."}}},"CreditRate":{"type":"object","required":["operation","credits_per_unit"],"properties":{"operation":{"type":"string","enum":["humanize","citation_format_correction","condense","translate"],"description":"The operation this rate applies to."},"credits_per_unit":{"type":"integer","description":"Credits charged per words_per_unit words processed."}}},"CreditRates":{"type":"object","required":["items","words_per_unit","min_credits_per_job"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CreditRate"},"description":"One rate per operation."},"words_per_unit":{"type":"integer","description":"The block of words a rate is quoted against - 1000."},"min_credits_per_job":{"type":"integer","description":"The least any single job is charged, however short the document."}}},"DetectionReportParseResult":{"type":"object","required":["report_type","ai_percent","filename","size_bytes","page_count","skipped_page_count","segment_count","problem_type_counts","segments"],"properties":{"report_type":{"type":["string","null"],"enum":["turnitin","ithenticate",null],"description":"Which vendor produced the report: turnitin or ithenticate. Null when neither could be determined."},"ai_percent":{"type":["number","null"],"minimum":0,"maximum":100,"description":"The headline \"detected as AI\" percentage. Null when the report shows \"*\" (too little text to assess) or states no figure - null never means zero."},"filename":{"type":"string","description":"Uploaded report filename."},"size_bytes":{"type":"integer","description":"Uploaded report size in bytes."},"page_count":{"type":"integer","maximum":500,"description":"Pages in the report PDF."},"skipped_page_count":{"type":"integer","description":"Leading cover pages skipped before extraction."},"segment_count":{"type":"integer","maximum":500,"description":"How many flagged passages were extracted."},"problem_type_counts":{"type":"object","additionalProperties":{"type":"integer"},"description":"Count of flagged passages per problem type."},"segments":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/DetectionProblemSegment"},"description":"The flagged passages, ready to pass as selected_texts when creating a job."}}},"CreateHumanizeJobFromFileRequest":{"additionalProperties":false,"description":"Interactive-session request that creates a job from a staged file.","properties":{"strategy":{"default":"conservative","description":"Polishing intensity. Aggressive rewrites most extensively.","enum":["conservative","balanced","aggressive","balanced_v2","aggressive_v2"],"title":"Strategy","type":"string"},"selected_texts":{"anyOf":[{"items":{"maxLength":20000,"minLength":1,"type":"string"},"maxItems":500,"minItems":1,"type":"array"},{"type":"null"}],"default":null,"description":"Final source passages to polish. Omit or use null for the full document, or to use all detected Turnitin passages when turnitin_file is supplied.","title":"Selected Texts"},"additional_instructions":{"anyOf":[{"maxLength":2000,"type":"string"},{"type":"null"}],"default":null,"description":"Additional style or quality instructions for this job.","examples":["Keep the AI rate low while using advanced grammar, sentence structures, and vocabulary."],"title":"Additional Instructions"},"source_file_id":{"description":"Source file ID returned by POST /files in an interactive session.","format":"uuid","title":"Source File Id","type":"string"}},"required":["source_file_id"],"title":"CreateHumanizeJobFromFileRequest","type":"object"},"CreateHumanizeJobMultipartRequest":{"additionalProperties":false,"description":"One-request server-to-server humanization job creation with an optional Turnitin report.","properties":{"file":{"type":"string","format":"binary","contentMediaType":"application/vnd.openxmlformats-officedocument.wordprocessingml.document","description":"Source DOCX file. Send the raw file bytes as the file part of multipart/form-data; do not send a path or Base64 string."},"turnitin_file":{"type":"string","format":"binary","contentMediaType":"application/pdf","description":"Optional Turnitin PDF report. The report is retained with the job. Its detected passages are used only when selected_texts is omitted."},"strategy":{"default":"conservative","description":"Polishing intensity. Aggressive rewrites most extensively.","enum":["conservative","balanced","aggressive","balanced_v2","aggressive_v2"],"title":"Strategy","type":"string"},"selected_texts":{"anyOf":[{"items":{"maxLength":20000,"minLength":1,"type":"string"},"maxItems":500,"minItems":1,"type":"array"},{"type":"null"}],"default":null,"description":"Final source passages to polish. Omit or use null for the full document, or to use all detected Turnitin passages when turnitin_file is supplied.","title":"Selected Texts"},"additional_instructions":{"anyOf":[{"maxLength":2000,"type":"string"},{"type":"null"}],"default":null,"description":"Additional style or quality instructions for this job.","examples":["Keep the AI rate low while using advanced grammar, sentence structures, and vocabulary."],"title":"Additional Instructions"}},"title":"CreateHumanizeJobMultipartRequest","type":"object","required":["file"]},"CreateCitationFormatCorrectionJobFromFileRequest":{"additionalProperties":false,"description":"Interactive-session citation-format-correction job from a staged file.","properties":{"citation_style":{"description":"Target citation style (e.g. apa7, mla9, harvard, ieee, gbt7714).","examples":["apa7"],"title":"Citation Style","type":"string"},"additional_instructions":{"anyOf":[{"maxLength":2000,"type":"string"},{"type":"null"}],"default":null,"description":"Additional instructions for this job.","title":"Additional Instructions"},"source_file_id":{"description":"Source file ID returned by POST /files in an interactive session.","format":"uuid","title":"Source File Id","type":"string"}},"required":["citation_style","source_file_id"],"title":"CreateCitationFormatCorrectionJobFromFileRequest","type":"object"},"CreateCondenseJobFromFileRequest":{"additionalProperties":false,"description":"Interactive-session condense job from a staged file.","properties":{"max_words":{"anyOf":[{"maximum":1000000,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Whole-document target word count. Mutually exclusive with segments.","title":"Max Words"},"segments":{"anyOf":[{"items":{"$ref":"#/components/schemas/CondenseSegment"},"maxItems":500,"minItems":1,"type":"array"},{"type":"null"}],"default":null,"description":"Passages to condense, each with its own word budget. Mutually exclusive with max_words.","title":"Segments"},"additional_instructions":{"anyOf":[{"maxLength":2000,"type":"string"},{"type":"null"}],"default":null,"description":"Additional instructions for this job.","title":"Additional Instructions"},"source_file_id":{"description":"Source file ID returned by POST /files in an interactive session.","format":"uuid","title":"Source File Id","type":"string"}},"required":["source_file_id"],"title":"CreateCondenseJobFromFileRequest","type":"object"},"CreateTranslateJobFromFileRequest":{"additionalProperties":false,"description":"Interactive-session translation job from a staged file.","properties":{"source_lang":{"default":"auto","description":"Source language, or \"auto\" to detect.","title":"Source Lang","type":"string"},"target_lang":{"description":"Target language.","title":"Target Lang","type":"string"},"source_file_id":{"description":"Source file ID returned by POST /files in an interactive session.","format":"uuid","title":"Source File Id","type":"string"}},"required":["target_lang","source_file_id"],"title":"CreateTranslateJobFromFileRequest","type":"object"},"CreateCitationFormatCorrectionJobMultipartRequest":{"additionalProperties":false,"description":"Server-to-server options accompanying an uploaded document.","properties":{"file":{"type":"string","format":"binary","description":"Source document. Send the raw file bytes as the file part of multipart/form-data; do not send a path or Base64 string."},"citation_style":{"description":"Target citation style (e.g. apa7, mla9, harvard, ieee, gbt7714).","examples":["apa7"],"title":"Citation Style","type":"string"},"additional_instructions":{"anyOf":[{"maxLength":2000,"type":"string"},{"type":"null"}],"default":null,"description":"Additional instructions for this job.","title":"Additional Instructions"}},"required":["file","citation_style"],"title":"CreateCitationFormatCorrectionJobMultipartRequest","type":"object"},"CreateCondenseJobMultipartRequest":{"additionalProperties":false,"description":"Server-to-server options accompanying an uploaded document.","properties":{"file":{"type":"string","format":"binary","description":"Source document. Send the raw file bytes as the file part of multipart/form-data; do not send a path or Base64 string."},"max_words":{"anyOf":[{"maximum":1000000,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Whole-document target word count. Mutually exclusive with segments.","title":"Max Words"},"segments":{"anyOf":[{"items":{"$ref":"#/components/schemas/CondenseSegment"},"maxItems":500,"minItems":1,"type":"array"},{"type":"null"}],"default":null,"description":"Passages to condense, each with its own word budget. Mutually exclusive with max_words.","title":"Segments"},"additional_instructions":{"anyOf":[{"maxLength":2000,"type":"string"},{"type":"null"}],"default":null,"description":"Additional instructions for this job.","title":"Additional Instructions"}},"title":"CreateCondenseJobMultipartRequest","type":"object","required":["file"]},"CreateTranslateJobMultipartRequest":{"additionalProperties":false,"description":"Server-to-server options accompanying an uploaded document.","properties":{"file":{"type":"string","format":"binary","description":"Source document. Send the raw file bytes as the file part of multipart/form-data; do not send a path or Base64 string."},"source_lang":{"default":"auto","description":"Source language, or \"auto\" to detect.","title":"Source Lang","type":"string"},"target_lang":{"description":"Target language.","title":"Target Lang","type":"string"}},"required":["file","target_lang"],"title":"CreateTranslateJobMultipartRequest","type":"object"},"JobStatus":{"type":"string","description":"Current public job state. WAITING includes accepted jobs not yet dispatched. DONE, ERROR, and CANCELLED are terminal states.","enum":["WAITING","RUNNING","DONE","ERROR","CANCELLED"]},"JobStatusCounts":{"type":"object","description":"Number of owned polish jobs in each state.","required":["WAITING","RUNNING","DONE","ERROR","CANCELLED"],"properties":{"WAITING":{"type":"integer","description":"Accepted jobs waiting for dispatch or a worker."},"RUNNING":{"type":"integer","description":"Jobs currently being processed."},"DONE":{"type":"integer","description":"Successfully completed jobs."},"ERROR":{"type":"integer","description":"Jobs that ended with an error."},"CANCELLED":{"type":"integer","description":"Jobs cancelled by a user or administrator."}}},"JobFile":{"type":"object","description":"One stored file: identity, billable size, and whether a download works.","required":["file_id","filename","words","available","retained_until"],"properties":{"file_id":{"type":"string","format":"uuid","description":"Stored file identifier."},"filename":{"type":["string","null"],"description":"Original filename; results keep the source name."},"words":{"type":["integer","null"],"description":"Word count in the billing ruler, so this number ties directly to credits."},"available":{"type":"boolean","description":"Whether this file can currently be downloaded. False once it is deleted or retention removed it."},"retained_until":{"type":["string","null"],"format":"date-time","description":"UTC time when retention removes this file. Null when files are kept indefinitely."},"download_url":{"type":"string","format":"uri","description":"Temporary presigned download URL, served only by the job-detail endpoint for an available result. Works with a plain GET - no Authorization header. Expires quickly; fetch the job again for a fresh one."},"download_url_expires_at":{"type":["string","null"],"format":"date-time","description":"UTC expiry of download_url. Present only alongside download_url."}}},"JobCredits":{"type":"object","description":"What this job costs, in credits.","required":["frozen","charged"],"properties":{"frozen":{"type":"integer","minimum":0,"description":"Credits reserved while the job can still consume them. 0 once it is finished."},"charged":{"type":["integer","null"],"description":"Credits actually charged. Null while the job runs; the settled amount on DONE; always 0 on ERROR and CANCELLED - a job that did not complete is not charged."}}},"JobError":{"type":"object","description":"Why a job failed. Only present on a failed job.","required":["code","message"],"properties":{"code":{"type":["string","null"],"description":"Stable machine-readable failure code."},"message":{"type":["string","null"],"description":"Human-readable failure context."}}},"Job":{"type":"object","description":"One asynchronous document job.","required":["job_id","operation","status","finished","progress_percent","source","result","credits","error","created_at","started_at","finished_at"],"properties":{"job_id":{"type":"string","format":"uuid","description":"Stable identifier for polling and lifecycle operations."},"operation":{"type":"string","enum":["humanize","citation_format_correction","condense","translate"],"description":"Which operation produced this job."},"status":{"$ref":"#/components/schemas/JobStatus"},"finished":{"type":"boolean","description":"Whether the job reached a terminal state. Poll this boolean, not the status enum: new status values may appear, finished keeps its meaning."},"progress_percent":{"type":"integer","minimum":0,"maximum":100,"description":"Best-effort completion percentage for the current attempt."},"source":{"allOf":[{"$ref":"#/components/schemas/JobFile"}],"description":"The uploaded document."},"result":{"anyOf":[{"$ref":"#/components/schemas/JobFile"},{"type":"null"}],"description":"The produced document. Null until the job succeeds."},"credits":{"$ref":"#/components/schemas/JobCredits"},"error":{"anyOf":[{"$ref":"#/components/schemas/JobError"},{"type":"null"}],"description":"Failure details, or null."},"created_at":{"type":["string","null"],"format":"date-time","description":"UTC job creation time."},"started_at":{"type":["string","null"],"format":"date-time","description":"UTC time when a worker started the current attempt."},"finished_at":{"type":["string","null"],"format":"date-time","description":"UTC time when the job reached a terminal state."}}},"JobReceipt":{"type":"object","description":"The create response: a receipt, not the resource. It answers what was submitted, what it will cost, and which id to poll; everything else is one GET away.","required":["job_id","operation","status","credits_frozen","created_at"],"properties":{"job_id":{"type":"string","format":"uuid","description":"Identifier to poll: GET /jobs/{job_id}."},"operation":{"type":"string","enum":["humanize","citation_format_correction","condense","translate"],"description":"Which operation this job will perform."},"status":{"$ref":"#/components/schemas/JobStatus"},"credits_frozen":{"type":"integer","minimum":0,"description":"Credits reserved for this job at creation. The final charge is at most this; the job resource reports the settled amount in credits.charged."},"created_at":{"type":["string","null"],"format":"date-time","description":"UTC job creation time."}}},"JobList":{"type":"object","required":["items","total","limit","offset","has_more"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Job"},"description":"Jobs owned by the caller, newest first."},"total":{"type":"integer","minimum":0,"description":"Total jobs matching the query."},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Page size used for this response."},"offset":{"type":"integer","minimum":0,"description":"Number of items skipped before this page."},"has_more":{"type":"boolean","description":"Whether further pages exist."}}},"UserUsageTotals":{"type":"object","description":"Cumulative storage and document-processing usage for the current user.","required":["files","storage_bytes","jobs","active_jobs","source_tokens","target_tokens","source_chars","target_chars","active_api_keys","success_rate"],"properties":{"files":{"type":"integer","description":"Stored files that have not been deleted."},"storage_bytes":{"type":"integer","description":"Total retained file bytes."},"jobs":{"type":"integer","description":"Total polish jobs created."},"active_jobs":{"type":"integer","description":"Jobs in WAITING or RUNNING."},"source_tokens":{"type":"integer","description":"Estimated tokens across source documents."},"target_tokens":{"type":"integer","description":"Estimated tokens across polished documents."},"source_chars":{"type":"integer","description":"Characters across source documents."},"target_chars":{"type":"integer","description":"Characters across polished documents."},"active_api_keys":{"type":"integer","description":"API keys that have not been revoked."},"success_rate":{"type":["number","null"],"minimum":0,"maximum":1,"description":"DONE jobs divided by terminal jobs, or null when no terminal job exists."}}},"UserUsageQuotas":{"type":"object","description":"Current hard limits enforced before uploads and job creation.","required":["max_active_jobs","max_files","max_storage_bytes","max_document_tokens"],"properties":{"max_active_jobs":{"type":"integer","description":"0 means unlimited."},"max_files":{"type":"integer","description":"0 means unlimited."},"max_storage_bytes":{"type":"integer","description":"0 means unlimited."},"max_document_tokens":{"type":"integer","description":"0 means unlimited."}}},"UserUsageSummary":{"type":"object","required":["totals","status_counts","quotas"],"properties":{"totals":{"$ref":"#/components/schemas/UserUsageTotals"},"status_counts":{"$ref":"#/components/schemas/JobStatusCounts"},"quotas":{"$ref":"#/components/schemas/UserUsageQuotas"}}},"CreateApiKeyRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"description":"Label shown in the key list, for telling keys apart."},"scopes":{"type":"array","items":{"type":"string","enum":["documents:read","documents:write"]},"default":["documents:write","documents:read"],"description":"Scopes to grant. Defaults to read and write on documents."}}},"ApiKey":{"type":"object","required":["api_key_id","name","key_prefix","scopes"],"properties":{"api_key_id":{"type":"string","format":"uuid","description":"Stored file identifier."},"name":{"type":"string","description":"Label given at creation."},"key_prefix":{"type":"string","description":"Leading characters of the key, shown so keys can be told apart."},"secret":{"type":["string","null"],"description":"The full key. Null for keys created before keys became re-copyable."},"scopes":{"type":"array","items":{"type":"string"},"description":"Scopes this key carries."},"last_used_at":{"type":["string","null"],"format":"date-time","description":"When the file stopped being downloadable; null while it is live."},"revoked_at":{"type":["string","null"],"format":"date-time","description":"When the file stopped being downloadable; null while it is live."},"created_at":{"type":["string","null"],"format":"date-time","description":"When the file stopped being downloadable; null while it is live."}}},"ApiKeyCreated":{"allOf":[{"$ref":"#/components/schemas/ApiKey"},{"type":"object","required":["secret"],"properties":{"secret":{"type":"string"}}}]},"ApiKeyList":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"},"description":"Keys owned by the caller, newest first."}}},"CondenseSegment":{"additionalProperties":false,"description":"One passage to condense to its own word budget.","properties":{"text":{"description":"The passage to shorten, copied from the document.","maxLength":20000,"minLength":1,"title":"Text","type":"string"},"max_words":{"description":"Target word budget for this passage.","maximum":1000000,"minimum":1,"title":"Max Words","type":"integer"}},"required":["text","max_words"],"title":"CondenseSegment","type":"object"}}}}