{"openapi":"3.1.0","info":{"title":"Densem Platform API","version":"1.0.0","description":"Business conversion API. Authenticate with an organization API key (`Authorization: Bearer mdn_...`). The catalog is sourced from CONVERSIONS."},"servers":[{"url":"https://densem.com/api/v1"}],"tags":[{"name":"Conversions"},{"name":"Jobs"},{"name":"Files"},{"name":"Uploads"},{"name":"Webhooks"},{"name":"Connections"},{"name":"Billing"}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"mdn","description":"Organization API key created in Settings → Developers."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"Conversion":{"type":"object","required":["id","label","family","input","output","operation"],"properties":{"id":{"type":"string","example":"ost-pst"},"label":{"type":"string"},"family":{"type":"string","enum":["mailbox","media","office","archive","vm","regulatory"]},"input":{"type":"string"},"output":{"type":"string"},"operation":{"type":"string"},"keywords":{"type":"array","items":{"type":"string"}}}},"Job":{"type":"object","required":["id","status","outputFormat","progress"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["draft","queued","processing","completed","partial","failed","needs_attention"]},"inputFormat":{"type":"string","nullable":true},"outputFormat":{"type":"string"},"intent":{"type":"string"},"fileCount":{"type":"integer"},"totalSize":{"type":"integer"},"completedCount":{"type":"integer"},"processingCount":{"type":"integer"},"failedCount":{"type":"integer"},"needsAttentionCount":{"type":"integer"},"progress":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"File":{"type":"object","required":["id","jobId","status"],"properties":{"id":{"type":"string","format":"uuid"},"jobId":{"type":"string","format":"uuid"},"name":{"type":"string"},"size":{"type":"integer"},"inputFormat":{"type":"string","nullable":true},"outputFormat":{"type":"string","nullable":true},"status":{"type":"string"},"progress":{"type":"integer"},"error":{"type":"object","nullable":true,"properties":{"code":{"type":"string"},"message":{"type":"string"},"suggestion":{"type":"string","nullable":true}}},"output":{"type":"object","nullable":true},"downloadUrl":{"type":"string","format":"uri","nullable":true},"downloadExpiresAt":{"type":"integer","nullable":true}}},"Upload":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"jobId":{"type":"string","format":"uuid"},"fileName":{"type":"string"},"fileSize":{"type":"integer"},"offset":{"type":"integer"},"complete":{"type":"boolean"}}},"SourceRef":{"type":"object","required":["connectionId"],"properties":{"connectionId":{"type":"string","format":"uuid"},"id":{"type":"string"},"path":{"type":"string"}}},"DestinationRef":{"type":"object","required":["connectionId"],"properties":{"connectionId":{"type":"string","format":"uuid"},"folderId":{"type":"string"},"path":{"type":"string"}}}}},"security":[{"apiKey":[]}],"paths":{"/conversions":{"get":{"tags":["Conversions"],"summary":"List supported conversions","security":[{"apiKey":[]}],"parameters":[{"name":"family","in":"query","schema":{"type":"string","enum":["mailbox","media","office","archive","vm","regulatory"]}},{"name":"q","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Catalog sourced from CONVERSIONS.","content":{"application/json":{"schema":{"type":"object","properties":{"conversions":{"type":"array","items":{"$ref":"#/components/schemas/Conversion"}}}}}}}}}},"/jobs":{"post":{"tags":["Jobs"],"summary":"Create an asynchronous conversion job","description":"Accepts conversionId or outputFormat, plus multipart files, a sourceUrl, or a cloud sourceRef. Optional destination uploads results back to Drive, Dropbox, OneDrive or S3.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Replay-safe key. The same key and request return the original response; a different body returns 409."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"conversionId":{"type":"string","example":"ost-pst"},"outputFormat":{"type":"string","example":"PST"},"name":{"type":"string"},"sourceUrl":{"type":"string","format":"uri"},"fileName":{"type":"string"},"sourceRef":{"$ref":"#/components/schemas/SourceRef"},"destination":{"$ref":"#/components/schemas/DestinationRef"},"start":{"type":"boolean","default":true},"quote_id":{"type":"string","format":"uuid"},"max_price":{"type":"number","description":"Refuse before reserve if the quote exceeds this euro amount."},"max_price_minor":{"type":"integer","description":"Same cap in integer euro cents."}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"conversionId":{"type":"string"},"outputFormat":{"type":"string"},"name":{"type":"string"},"sourceUrl":{"type":"string"},"files":{"type":"array","items":{"type":"string","format":"binary"}},"start":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Draft job created without files."},"202":{"description":"Job accepted and started."},"402":{"description":"Insufficient prepaid balance ({ error: insufficient_balance, available, required, missing }), quote above max_price, spending limit, or card authentication required."}}}},"/jobs/{id}":{"get":{"tags":["Jobs"],"summary":"Get job status, progress, and per-file errors","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Job and files."},"404":{"description":"Unknown job."}}}},"/jobs/{id}/files":{"post":{"tags":["Jobs"],"summary":"Add files, a source URL, or start a resumable upload","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"sourceUrl":{"type":"string","format":"uri"},"fileName":{"type":"string"},"fileSize":{"type":"integer","description":"When set without sourceUrl, starts a resumable upload."},"mimeType":{"type":"string"},"start":{"type":"boolean","default":true}}}},"multipart/form-data":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"type":"string","format":"binary"}},"start":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Files added or upload session created."},"202":{"description":"Files added and job started."}}}},"/uploads/{id}":{"get":{"tags":["Uploads"],"summary":"Read resumable upload offset","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Upload session."}}},"put":{"tags":["Uploads"],"summary":"Append a resumable upload chunk","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Content-Range","in":"header","required":true,"schema":{"type":"string","example":"bytes 0-1048575/123456789"}}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Chunk accepted."},"202":{"description":"Upload completed and job started."}}}},"/files/{id}":{"get":{"tags":["Files"],"summary":"Get file status and a signed download URL","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File metadata."}}}},"/files/{id}/download":{"get":{"tags":["Files"],"summary":"Download a completed file","description":"Accepts the organization API key or a time-limited HMAC signature (`exp` + `sig`).","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"exp","in":"query","schema":{"type":"integer"}},{"name":"sig","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Binary result.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}}}}},"/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhook endpoints","responses":{"200":{"description":"Organization webhook endpoints."}}},"post":{"tags":["Webhooks"],"summary":"Create a signed webhook endpoint","description":"The signing secret is returned once. Deliveries use Densem-Signature (t,v1 HMAC-SHA256).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["job.completed","file.ready","file.failed"]}}}}}}},"responses":{"201":{"description":"Endpoint created; secret shown once."}}}},"/webhooks/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook endpoint."}}},"delete":{"tags":["Webhooks"],"summary":"Revoke a webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook disabled."}}}},"/connections":{"get":{"tags":["Connections"],"summary":"List cloud connections","responses":{"200":{"description":"Drive, Dropbox, OneDrive and S3 connections."}}},"post":{"tags":["Connections"],"summary":"Create an S3 connection","description":"OAuth providers are connected in Settings → Developers. S3 uses access keys.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["provider","accessKeyId","secretAccessKey","bucket"],"properties":{"provider":{"type":"string","enum":["s3"]},"accessKeyId":{"type":"string"},"secretAccessKey":{"type":"string"},"region":{"type":"string","default":"us-east-1"},"bucket":{"type":"string"},"prefix":{"type":"string"},"endpoint":{"type":"string","format":"uri"},"label":{"type":"string"}}}}}},"responses":{"201":{"description":"S3 connection created."}}}},"/connections/{id}":{"get":{"tags":["Connections"],"summary":"Get a cloud connection","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cloud connection."}}},"delete":{"tags":["Connections"],"summary":"Disconnect a cloud connection","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Connection revoked."}}}},"/connections/{id}/items":{"get":{"tags":["Connections"],"summary":"List files and folders for Dropbox, OneDrive, or S3","description":"Google Drive is not listable: pick files, Docs, Sheets, Slides, or a folder in the dashboard Google Picker, then pass sourceRef.id. Native Google files are exported to Office or PDF.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"parent","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Folder items."},"400":{"description":"Google Drive connections must use Picker."}}}},"/quotes":{"post":{"tags":["Billing"],"summary":"Create an immutable pay-per-use quote","description":"Amount is computed server-side from verified bytes, formats and file count (job_id or persisted input). Client amounts are ignored. Pricing rule microdeon-payg 3.0.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"job_id":{"type":"string"},"operation":{"type":"string"},"input_bytes":{"type":"integer"},"input_format":{"type":"string"},"output_format":{"type":"string"},"file_count":{"type":"integer"},"entity_count":{"type":"integer"},"virtual_size_bytes":{"type":"integer","description":"VM qemu-img virtual-size in bytes. Used as max(input, output, virtual_size) for disk conversions."},"max_price":{"type":"number"},"max_price_minor":{"type":"integer"}}}}}},"responses":{"201":{"description":"Quote created."},"402":{"description":"Spending limit, max_price exceeded, or enterprise_quote_required for jobs over 5 TB."}}},"get":{"tags":["Billing"],"summary":"Load a quote by id","parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Quote."},"404":{"description":"Unknown quote."}}}},"/balance":{"get":{"tags":["Billing"],"summary":"Read prepaid wallet balance","responses":{"200":{"description":"Balance, reserved and available amounts in integer cents."}}}},"/balance/topups":{"post":{"tags":["Billing"],"summary":"Open Stripe Checkout to add prepaid balance","description":"Creates a Stripe Checkout Session in payment mode. The wallet is credited only after payment_intent.succeeded. Never credit on the browser redirect.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount_minor","consent_accepted"],"properties":{"amount_minor":{"type":"integer","minimum":1000},"exact_shortfall":{"type":"boolean"},"consent_accepted":{"type":"boolean"},"sensitive_confirmed":{"type":"boolean","description":"Required for console top-ups of 500 € or more."},"success_url":{"type":"string"},"cancel_url":{"type":"string"}}}}}},"responses":{"201":{"description":"Checkout session created; follow url."},"400":{"description":"Invalid amount or missing consent."}}}},"/balance/transactions":{"get":{"tags":["Billing"],"summary":"List wallet ledger entries","responses":{"200":{"description":"Append-only wallet transactions."}}}}},"x-densem":{"scopes":["conversions:create","jobs:read","files:read","webhooks:manage","connections:manage"],"defaultScopes":["conversions:create","jobs:read","files:read"]}}