{"openapi":"3.1.0","info":{"title":"Ultiwrite Forensics customer API","version":"1.0.0","description":"One original per analysis: PDF, Office, image, RTF, OLE, or one zip of those. Metadata is always included. Professional API access shares the product's web usage ledger. No main-platform entitlements. Polling, reconciliation and downloads are free. API activation is environment-specific."},"servers":[{"url":"https://ultiwrite.co","description":"Production origin after release; not yet activated"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerKey":[]}],"paths":{"/api/v1/usage":{"get":{"operationId":"getUsage","summary":"Read available/reserved usage and execution eligibility","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/analyses":{"post":{"operationId":"createAnalysis","summary":"Reserve one unit and queue an original-file examination","description":"Use a UUID Idempotency-Key and reuse it with exactly the same original bytes after uncertain responses. A different document with the same key returns 409. Only one multipart field named file is accepted; account, product, capabilities and tier are forbidden. Supported originals are at most 3 MiB: unencrypted PDF (1–40 pages), JPEG/PNG/TIFF/WebP, DOCX/XLSX/PPTX and macro-enabled variants, OLE, RTF, or one zip of those. Three outstanding reserved jobs per account. Submission requires paid Professional eligibility; accepted retries return the same job even at zero available units. Request handlers do not run analysis.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","additionalProperties":false,"required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Exact original bytes, maximum 3 MiB"}}}}}},"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["id","status_url"],"properties":{"id":{"type":"string","format":"uuid"},"status_url":{"type":"string"}}}}},"headers":{"Location":{"schema":{"type":"string"},"description":"Relative status URL on first acceptance"}}},"401":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listAnalyses","summary":"Most recent owned analyses from web and API","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"analyses":{"type":"array","items":{"$ref":"#/components/schemas/AnalysisSummary"}}}}}}},"401":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/analyses/{id}":{"get":{"operationId":"getAnalysis","summary":"Poll durable state; completed results contain the published report snapshot","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Analysis"}}}},"401":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteAnalysis","summary":"Queue cancellation and private artifact deletion","description":"A pending job releases its reservation only after the canonical cancellation/deletion is acknowledged. A completed examination remains settled. Poll until 404. Minimal billing and audit records are retained.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"const":"deleting"}}}}}},"401":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/analyses/{id}/metadata.json":{"get":{"operationId":"downloadMetadata","summary":"Download the published metadata and findings JSON without another charge","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Report"}}}},"401":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/analyses/{id}/report.pdf":{"get":{"operationId":"downloadReport","summary":"Download the private forensic PDF without another charge","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"PDF rendered from the same published findings snapshot","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected; error contains a stable code. No new unit is settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"BearerKey":{"type":"http","scheme":"bearer","description":"Product API key created under /developers. Never an engine machine credential. Store server-side only; expires in 90 days."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","examples":["invalid_api_key","api_plan_required","usage_required","rate_limited","capacity_exceeded","idempotency_conflict","unsupported_document","report_not_ready","service_unavailable"]}}},"Usage":{"type":"object","required":["available","reserved","api_execution","profile","limits"],"properties":{"available":{"type":"integer","minimum":0},"reserved":{"type":"integer","minimum":0},"api_execution":{"type":"boolean"},"profile":{"const":"ultiwrite-forensics@1"},"limits":{"type":"object","properties":{"bytes":{"const":3145728},"pages":{"const":40},"activeAnalyses":{"const":3},"requestsPerMinute":{"const":60}}}}},"AnalysisSummary":{"type":"object","required":["id","name","status","billing","created_at"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["queued","running","completed","failed","cancelled","deleting","deleted"]},"billing":{"type":"string","enum":["reserved","settled","released"]},"created_at":{"type":"string","format":"date-time"}}},"Analysis":{"allOf":[{"$ref":"#/components/schemas/AnalysisSummary"},{"type":"object","required":["report"],"properties":{"report":{"oneOf":[{"$ref":"#/components/schemas/Report"},{"type":"null"}]}}}]},"Report":{"type":"object","required":["document","examinedAt","profile","engineVersion","reportVersion","metadata","findings","coverage","limitations"],"properties":{"document":{"type":"object","required":["name","sha256","pages","bytes"],"properties":{"name":{"type":"string"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"pages":{"type":"integer"},"bytes":{"type":"integer"}}},"examinedAt":{"type":"string","format":"date-time"},"profile":{"const":"ultiwrite-forensics@1"},"engineVersion":{"type":"string"},"reportVersion":{"type":"string"},"metadata":{"type":"object","additionalProperties":true,"description":"Actual source-derived metadata, including quiet results; an edit alone is not proof of manipulation."},"findings":{"type":"array","items":{"type":"object","required":["id","severity","explanation","evidence"],"properties":{"id":{"type":"string"},"severity":{"type":"string"},"explanation":{"type":"string"},"evidence":{"type":"array","items":{"type":"string"}}}}},"coverage":{"type":"array","items":{"type":"object","required":["family","status","reason"],"properties":{"family":{"type":"string"},"status":{"type":"string","description":"Preserves actual completed/quiet, partial, failed and unsupported/unassessed check states from the engine."},"reason":{"type":"string"}}}},"limitations":{"type":"array","items":{"type":"string"}}}}}}}