{"openapi":"3.1.0","info":{"title":"Microsite Public API","version":"1.0.0","description":"Programmatic access to your Microsite account: create, list, and manage share links, plus analytics and leads. Authenticate with an API key as a bearer token.","contact":{"name":"Microsite","url":"https://microsite.com.au"}},"servers":[{"url":"https://microsite.com.au/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"msk_live_*","description":"Send your API key as `Authorization: Bearer msk_live_…`. Keys are created via POST /account/api-keys while signed in."}},"schemas":{"Link":{"type":"object","properties":{"shareId":{"type":"string","description":"12-char hex link id."},"mode":{"type":"string","enum":["video","file","collection","site"]},"type":{"type":"string","description":"Human label for the mode."},"label":{"type":"string"},"displayTitle":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string","format":"uri","description":"Public share URL."},"showOnProfile":{"type":"boolean"},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"retentionRule":{"type":"string"},"expired":{"type":"boolean"},"fileCount":{"type":"integer"},"sizeBytes":{"type":"integer"},"durationSeconds":{"type":"integer","description":"Video only."},"streamStatus":{"type":"string","description":"Video only."},"thumbnailUrl":{"type":"string","format":"uri"},"deletedAt":{"type":"string","description":"Set when the link is in trash."}}},"Error":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}},"paths":{"/me":{"get":{"summary":"Get the authenticated account, plan, and usage.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Account summary."},"401":{"description":"Unauthenticated."}}}},"/links":{"get":{"summary":"List share links on the account.","security":[{"bearerAuth":[]}],"parameters":[{"name":"mode","in":"query","schema":{"type":"string","enum":["video","file","collection","site"]}},{"name":"tag","in":"query","schema":{"type":"string"}},{"name":"includeTrashed","in":"query","schema":{"type":"string","enum":["0","1"]}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Paginated link list."}}},"post":{"summary":"Create a hosted (non-video) share link. Requires write scope.","description":"Upload file(s) as multipart/form-data, or send JSON with a fetchable `sourceUrl`. One file → a `file` link; multiple files (or a single `.zip`) → a `collection`; `shareMode=site` with a `.zip` containing an index.html → a hosted `site`. Enforces the same plan size/type limits and expiry rules as the browser upload. Hosted uploads are capped at 100 MB — use POST /links/video for large media. Video is rejected with code use_video_endpoint.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"A single file to host (alias of `files`)."},"files":{"type":"array","items":{"type":"string","format":"binary"},"description":"One or more files. 2+ → collection."},"shareMode":{"type":"string","enum":["file","site"],"description":"`site` hosts a static site from a single .zip (default `file`)."},"linkExpiry":{"type":"string","enum":["1h","24h","7d","never"],"description":"Defaults to 7d. `never` requires Pro."},"linkPassword":{"type":"string","description":"Optional password gate."},"linkSlug":{"type":"string","description":"Custom slug (Pro)."},"linkPathName":{"type":"string","description":"Custom slug namespace (Pro)."},"label":{"type":"string"},"leadCapture":{"type":"string","enum":["0","1"],"description":"Enable lead capture (Pro)."},"leadHeadline":{"type":"string"},"showOnProfile":{"type":"string","enum":["0","1"]}}}},"application/json":{"schema":{"type":"object","properties":{"sourceUrl":{"type":"string","format":"uri","description":"A publicly fetchable http(s) URL. The server downloads it into R2. A `.zip` expands into a collection (or a site with shareMode=site)."},"fileName":{"type":"string","description":"Overrides the filename inferred from the URL."},"shareMode":{"type":"string","enum":["file","site"]},"linkExpiry":{"type":"string","enum":["1h","24h","7d","never"]},"linkPassword":{"type":"string"},"linkSlug":{"type":"string"},"linkPathName":{"type":"string"},"label":{"type":"string"},"leadCapture":{"type":"boolean"},"leadHeadline":{"type":"string"},"showOnProfile":{"type":"boolean"}},"required":["sourceUrl"]}}}},"responses":{"201":{"description":"Created link (same shape as the Link schema); `mode` is file, collection, or site."},"400":{"description":"No file / unsupported type / use_video_endpoint / site_requires_zip / too_many_files."},"403":{"description":"Insufficient scope / invalid expiry / requires Pro."},"413":{"description":"File exceeds the API upload ceiling."}}}},"/links/video":{"post":{"summary":"Start a Cloudflare Stream direct upload for a video link. Requires write scope.","description":"Returns a one-time Stream upload URL and a shareId. Upload the bytes directly to `upload.url` (they never pass through this API), then call POST /links/video/complete to finalize.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"fileName":{"type":"string","description":"Video filename (must be a supported video extension)."},"fileSize":{"type":"integer","description":"Byte length of the video (used for plan limits + upload method)."},"linkExpiry":{"type":"string","enum":["1h","24h","7d","never"]},"linkPassword":{"type":"string"},"linkSlug":{"type":"string"},"linkPathName":{"type":"string"}},"required":["fileName","fileSize"]}}}},"responses":{"201":{"description":"{ shareId, upload: { url, method, streamUid }, slug, expiresAt, complete }."},"403":{"description":"Insufficient scope / invalid expiry."},"503":{"description":"Video hosting not configured."}}}},"/links/video/complete":{"post":{"summary":"Finalize a Stream upload after the bytes are uploaded. Requires write scope.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"shareId":{"type":"string","description":"From POST /links/video."},"streamUid":{"type":"string","description":"From POST /links/video (upload.streamUid)."}},"required":["shareId","streamUid"]}}}},"responses":{"200":{"description":"{ shareId, url, slug, streamStatus, processing }."},"404":{"description":"Upload session not found or not owned by this account."}}}},"/links/{id}":{"get":{"summary":"Get a single link.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Link."},"404":{"description":"Not found."}}},"patch":{"summary":"Update a link (label, tags, profile visibility). Requires write scope.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"showOnProfile":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated link."},"403":{"description":"Insufficient scope."}}},"delete":{"summary":"Move a link to trash (recoverable). Requires write scope.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Trashed."},"403":{"description":"Insufficient scope."}}}},"/links/{id}/analytics":{"get":{"summary":"Engagement analytics for a link (Pro / analytics feature).","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"range","in":"query","schema":{"type":"string","description":"e.g. 7d, 30d, 90d"}}],"responses":{"200":{"description":"Analytics dashboard payload."},"403":{"description":"Requires Pro."}}}},"/leads":{"get":{"summary":"List captured leads (Pro / analytics feature).","security":[{"bearerAuth":[]}],"parameters":[{"name":"shareId","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":100,"maximum":200}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Paginated lead list ({ leads, pagination })."},"403":{"description":"Requires Pro."}}}}}}