{"openapi":"3.1.0","info":{"title":"hello.new links","version":"1.0.0","description":"Temporary uploads, shares, webhooks and websites for agents. One call, no account: the response carries the link's key, its only credential. With an account key (hk_…) as a Bearer token, links live at hello.new/@username/name and keep until deleted; an account holds at most 1000 live links and 1 GB of stored bytes, or 100,000 and 100 GB on Pro (403 and 413 past that). Account keys and sessions only ever go in the Authorization header, never in a URL. Bodies are JSON whatever the Content-Type. Errors are {\"error\": \"<sentence>\"}."},"servers":[{"url":"https://api.hello.new"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An account key (hk_…) or a signed-in session."}},"responses":{"Error":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"Ok":{"type":"object","properties":{"ok":{"const":true}}},"UploadBody":{"type":"object","properties":{"expires_in":{"type":["integer","null"],"minimum":60,"description":"Seconds. Anonymous: at most 86400, default 86400. On an account: default never."},"name":{"type":["string","null"],"description":"Account links only: hello.new/@you/{name}."},"note":{"type":["string","null"],"maxLength":280,"description":"Shown to the human on the upload page."},"max_files":{"type":"integer","minimum":1,"maximum":100,"description":"Default and most: 10, or 100 on a Pro account."}}},"ShareBody":{"type":"object","required":["text"],"properties":{"expires_in":{"type":["integer","null"],"minimum":60,"description":"Seconds. Anonymous: at most 86400, default 86400. On an account: default never."},"name":{"type":["string","null"],"description":"Account links only: hello.new/@you/{name}."},"text":{"type":"string","description":"At most 256 KB of UTF-8, or 5 MB on a Pro account."},"title":{"type":["string","null"],"maxLength":120},"content_type":{"enum":["text/markdown","text/plain"],"default":"text/markdown"}}},"WebhookBody":{"type":"object","properties":{"expires_in":{"type":["integer","null"],"minimum":60,"description":"Seconds. Anonymous: at most 86400, default 86400. On an account: default never."},"name":{"type":["string","null"],"description":"Account links only: hello.new/@you/{name}."},"note":{"type":["string","null"],"maxLength":280}}},"SiteBody":{"type":"object","required":["files"],"properties":{"expires_in":{"type":["integer","null"],"minimum":60,"description":"Seconds. Anonymous: at most 86400, default 86400. On an account: default never."},"name":{"type":["string","null"],"description":"Account links only: hello.new/@you/{name}."},"files":{"type":"object","description":"Path to contents: text as a string, anything binary as {\"base64\": \"…\"}. index.html is the home page; paths are case-sensitive. At most 10 MB and 100 files, or 100 MB and 1,000 on a Pro account; 25 MB a file.","additionalProperties":{"oneOf":[{"type":"string"},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string"}}}]}},"title":{"type":["string","null"],"maxLength":120},"password":{"type":["string","null"],"minLength":4,"maxLength":128,"description":"Account sites only, and only in a JSON body, never the URL. Visitors get hello.new's own password page instead of the site, and none of its files, until they enter it; then their browser stays in for 24 hours, or until the site expires if that is sooner. Spaces at either end are dropped. On PUT, leave it out to keep the password, send a new one to replace it (everyone who got in with the old one has to enter the new one), or null to remove it."}}},"ClaimBody":{"type":"object","required":["id","key"],"properties":{"id":{"type":"string"},"key":{"type":"string"},"name":{"type":["string","null"]}}},"Claimed":{"type":"object","properties":{"kind":{"enum":["upload","share","webhook","site"]},"id":{"type":"string"},"url":{"type":"string","format":"uri"},"name":{"type":["string","null"]},"expires_at":{"type":"null"}}},"Upload":{"type":"object","properties":{"kind":{"const":"upload"},"id":{"type":"string"},"url":{"type":"string","format":"uri"},"key":{"type":"string","description":"Shown once. Only its hash is kept."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"claim_url":{"type":"string","format":"uri","description":"Anonymous links: where a signed-in human keeps this link."},"analytics_url":{"type":"string","format":"uri","description":"GET /analytics/{id} with this link's key: who opened it, from where, on what."},"stats_url":{"type":"string","format":"uri","description":"The same analytics as a page for a person; the key rides in the URL fragment."},"owner":{"type":"string","description":"Account links: @username."},"name":{"type":["string","null"]},"files_url":{"type":"string","format":"uri"},"note":{"type":["string","null"]},"max_files":{"type":"integer"},"max_bytes":{"type":"integer"}}},"Share":{"type":"object","properties":{"kind":{"const":"share"},"id":{"type":"string"},"url":{"type":"string","format":"uri"},"key":{"type":"string","description":"Shown once. Only its hash is kept."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"claim_url":{"type":"string","format":"uri","description":"Anonymous links: where a signed-in human keeps this link."},"analytics_url":{"type":"string","format":"uri","description":"GET /analytics/{id} with this link's key: who opened it, from where, on what."},"stats_url":{"type":"string","format":"uri","description":"The same analytics as a page for a person; the key rides in the URL fragment."},"owner":{"type":"string","description":"Account links: @username."},"name":{"type":["string","null"]},"raw_url":{"type":"string","format":"uri"},"title":{"type":["string","null"]},"content_type":{"type":"string"}}},"Webhook":{"type":"object","properties":{"kind":{"const":"webhook"},"id":{"type":"string"},"url":{"type":"string","format":"uri"},"key":{"type":"string","description":"Shown once. Only its hash is kept."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"claim_url":{"type":"string","format":"uri","description":"Anonymous links: where a signed-in human keeps this link."},"analytics_url":{"type":"string","format":"uri","description":"GET /analytics/{id} with this link's key: who opened it, from where, on what."},"stats_url":{"type":"string","format":"uri","description":"The same analytics as a page for a person; the key rides in the URL fragment."},"owner":{"type":"string","description":"Account links: @username."},"name":{"type":["string","null"]},"inbox_url":{"type":"string","format":"uri"},"note":{"type":["string","null"]},"max_requests":{"type":"integer"},"max_bytes":{"type":"integer"}}},"Site":{"type":"object","properties":{"kind":{"const":"site"},"id":{"type":"string"},"url":{"type":"string","format":"uri"},"key":{"type":"string","description":"Shown once. Only its hash is kept."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"claim_url":{"type":"string","format":"uri","description":"Anonymous links: where a signed-in human keeps this link."},"analytics_url":{"type":"string","format":"uri","description":"GET /analytics/{id} with this link's key: who opened it, from where, on what."},"stats_url":{"type":"string","format":"uri","description":"The same analytics as a page for a person; the key rides in the URL fragment."},"owner":{"type":"string","description":"Account links: @username."},"name":{"type":["string","null"]},"named_url":{"type":"string","format":"uri","description":"Named account sites: hello.new/@you/{name}, which sends visitors on to url."},"title":{"type":["string","null"]},"files":{"type":"integer"},"bytes":{"type":"integer"},"protected":{"type":"boolean","description":"Visitors need the password before anything of the site is served."}}},"File":{"type":"object","properties":{"seq":{"type":"integer"},"name":{"type":"string"},"size":{"type":"integer"},"content_type":{"type":"string"},"received_at":{"type":"string","format":"date-time"},"url":{"type":"string","format":"uri","description":"Carries ?key= when you listed with the link's key. Listed with an account key or session, it carries no key: fetch it with your Authorization header."}}},"Breakdown":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"hits":{"type":"integer"},"visitors":{"type":"integer"}}}},"Analytics":{"type":"object","properties":{"id":{"type":"string"},"kind":{"enum":["upload","share","webhook","site"]},"url":{"type":"string","format":"uri"},"title":{"type":["string","null"]},"note":{"type":["string","null"]},"owner":{"type":["string","null"],"description":"@username for account links."},"name":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"full":{"type":"boolean","description":"false for an anonymous link: totals, timeseries and countries only."},"interval":{"enum":["24h","7d","30d","90d","all"]},"unit":{"enum":["hour","day","week"]},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"totals":{"type":"object","properties":{"views":{"type":"integer"},"visitors":{"type":"integer"},"reads":{"type":"integer"},"uploads":{"type":"integer"},"downloads":{"type":"integer"},"requests":{"type":"integer"},"refused":{"type":"integer"},"bots":{"type":"integer"},"countries":{"type":"integer"},"bytes":{"type":"integer"}}},"timeseries":{"type":"array","items":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"views":{"type":"integer"},"visitors":{"type":"integer"},"reads":{"type":"integer"},"uploads":{"type":"integer"},"downloads":{"type":"integer"},"requests":{"type":"integer"}}}},"countries":{"$ref":"#/components/schemas/Breakdown"},"locked":{"type":"array","items":{"type":"string"},"description":"Anonymous links: the breakdowns claiming unlocks."},"claim_url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"object"},"description":"Full only: the latest 100 requests, newest first, without IP addresses or headers."}},"additionalProperties":{"$ref":"#/components/schemas/Breakdown"}},"Limits":{"type":"object","description":"The plan's limits. Per account: links (live), bytes (stored). Per link: file_bytes, files_per_upload, requests_per_webhook, share_bytes, site_bytes, files_per_site.","properties":{"links":{"type":"integer"},"bytes":{"type":"integer"},"file_bytes":{"type":"integer"},"files_per_upload":{"type":"integer"},"requests_per_webhook":{"type":"integer"},"share_bytes":{"type":"integer"},"site_bytes":{"type":"integer"},"files_per_site":{"type":"integer"}}},"Me":{"type":"object","properties":{"user_id":{"type":"string"},"username":{"type":["string","null"]},"display_name":{"type":["string","null"]},"plan":{"enum":["free","pro"]},"billing":{"type":["object","null"],"description":"The Stripe subscription, once there has been one. Pro while status is active, trialing or past_due.","properties":{"status":{"type":"string"},"period_end":{"type":"integer","description":"Unix seconds."},"cancel_at_period_end":{"type":"boolean"},"interval":{"enum":["month","year"]}}},"usage":{"type":"object","properties":{"links":{"type":"integer"},"bytes":{"type":"integer"}}},"limits":{"$ref":"#/components/schemas/Limits"}}},"Url":{"type":"object","properties":{"url":{"type":"string","format":"uri"}}},"Request":{"type":"object","properties":{"seq":{"type":"integer"},"received_at":{"type":"string","format":"date-time"},"method":{"type":"string"},"path":{"type":"string"},"query":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Lower-cased. Hop-by-hop, forwarding and Cookie headers are not kept; Authorization is."},"content_type":{"type":["string","null"]},"body":{"type":["string","null"],"description":"The body as text, or null when it is not UTF-8."},"body_base64":{"type":"string","description":"Present only when body is null."}}}}},"paths":{"/upload":{"post":{"summary":"Make an upload link a human opens to send you files","parameters":[{"name":"client","in":"query","required":false,"schema":{"type":"string"},"description":"A label for the calling tool (the X-Hello-Client header wins)."}],"security":[{},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadBody"}}}},"responses":{"201":{"description":"The link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/u/{id}":{"get":{"summary":"What the upload page shows (no key needed)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."}],"responses":{"200":{"description":"The page","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"404":{"$ref":"#/components/responses/Error"}}},"delete":{"summary":"Delete the link and its files","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"The link's key, and only that: an account key (hk_…) or session token here is refused with 401. `Authorization: Bearer <key>` works too, and on an account link so does the owning account's key or session, in the Authorization header only."}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/u/{id}/files/{name}":{"put":{"summary":"Upload one file (the raw body, at most 50 MB, or 100 MB on a Pro account's link); no key needed","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"responses":{"201":{"description":"Stored","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":true},"seq":{"type":"integer"},"name":{"type":"string"},"size":{"type":"integer"}}}}}},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/u/{id}/files":{"get":{"summary":"List the files received","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"The link's key, and only that: an account key (hk_…) or session token here is refused with 401. `Authorization: Bearer <key>` works too, and on an account link so does the owning account's key or session, in the Authorization header only."}],"responses":{"200":{"description":"The files","content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"$ref":"#/components/schemas/File"}}}}}}},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/u/{id}/files/{seq}":{"servers":[{"url":"https://hellouploads.com"}],"get":{"summary":"Download one file","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"seq","in":"path","required":true,"schema":{"type":"integer"}},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"The link's key, and only that: an account key (hk_…) or session token here is refused with 401. `Authorization: Bearer <key>` works too, and on an account link so does the owning account's key or session, in the Authorization header only."}],"responses":{"200":{"description":"The bytes, with their content type"},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/share":{"post":{"summary":"Publish text or markdown at a URL","parameters":[{"name":"client","in":"query","required":false,"schema":{"type":"string"},"description":"A label for the calling tool (the X-Hello-Client header wins)."}],"security":[{},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareBody"}}}},"responses":{"201":{"description":"The link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Share"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/s/{id}":{"get":{"summary":"The share, as JSON","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."}],"responses":{"200":{"description":"The share","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"404":{"$ref":"#/components/responses/Error"}}},"delete":{"summary":"Delete the share","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"The link's key, and only that: an account key (hk_…) or session token here is refused with 401. `Authorization: Bearer <key>` works too, and on an account link so does the owning account's key or session, in the Authorization header only."}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/s/{id}/raw":{"servers":[{"url":"https://hellouploads.com"}],"get":{"summary":"The share text itself","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."}],"responses":{"200":{"description":"The text"},"404":{"$ref":"#/components/responses/Error"}}}},"/webhook":{"post":{"summary":"Make a URL that records the HTTP requests sent to it","parameters":[{"name":"client","in":"query","required":false,"schema":{"type":"string"},"description":"A label for the calling tool (the X-Hello-Client header wins)."}],"security":[{},{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookBody"}}}},"responses":{"201":{"description":"The link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/w/{id}":{"description":"Any method, and any path below it (/w/{id}/anything), is recorded. At most 256 KB per request, or 1 MB on a Pro account's webhook.","post":{"summary":"Send the webhook a request","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."}],"responses":{"200":{"description":"Recorded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":true},"seq":{"type":"integer"}}}}}},"404":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/webhook/{id}":{"get":{"summary":"Read the requests received, optionally waiting for the next one","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"The link's key, and only that: an account key (hk_…) or session token here is refused with 401. `Authorization: Bearer <key>` works too, and on an account link so does the owning account's key or session, in the Authorization header only."},{"name":"since","in":"query","schema":{"type":"integer","default":0},"description":"Only requests with a higher seq."},{"name":"wait","in":"query","schema":{"type":"number","minimum":0,"maximum":25,"default":0},"description":"Seconds to hold the call open until a request arrives."}],"responses":{"200":{"description":"The inbox","content":{"application/json":{"schema":{"type":"object","properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/Request"}}}}}}},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}},"delete":{"summary":"Delete the webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"The link's key, and only that: an account key (hk_…) or session token here is refused with 401. `Authorization: Bearer <key>` works too, and on an account link so does the owning account's key or session, in the Authorization header only."}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/site":{"post":{"summary":"Publish a static website at an address of its own","description":"Send JSON ({\"files\": {…}}), or the folder as a .tar or .tar.gz archive (tar -cz -C dist . | curl --data-binary @- …) with title, expires_in and name in the query string. The site is served at https://{id}.hellonew.app: /about finds about.html or about/index.html, and a path with no file gets 404.html, or index.html when there is none, so single-page apps route. Everything in a site is public, unless a site on an account has a password: then visitors see nothing of it until they enter the password on hello.new's own page (10 tries per visitor per 15 minutes). Anonymous sites carry a small Report badge, are not indexed by search engines, and may not contain a password field.","parameters":[{"name":"client","in":"query","required":false,"schema":{"type":"string"},"description":"A label for the calling tool (the X-Hello-Client header wins)."},{"name":"title","in":"query","required":false,"schema":{"type":"string"},"description":"Archive uploads only, as in the JSON body."},{"name":"expires_in","in":"query","required":false,"schema":{"type":"integer"},"description":"Archive uploads only, as in the JSON body."},{"name":"name","in":"query","required":false,"schema":{"type":"string"},"description":"Archive uploads only, as in the JSON body."}],"security":[{},{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteBody"}},"application/gzip":{"schema":{"type":"string","format":"binary"}},"application/x-tar":{"schema":{"type":"string","format":"binary"}}}},"responses":{"201":{"description":"The site","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/site/{id}":{"get":{"summary":"The site: its address, title, file count, size and whether it has a password (no key needed)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."}],"responses":{"200":{"description":"The site","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"404":{"$ref":"#/components/responses/Error"}}},"put":{"summary":"Publish again at the same address: the files sent replace every old one","description":"The password stays as it is unless the JSON body has `password`: a new one replaces it, null removes it.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"The link's key, and only that: an account key (hk_…) or session token here is refused with 401. `Authorization: Bearer <key>` works too, and on an account link so does the owning account's key or session, in the Authorization header only."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteBody"}},"application/gzip":{"schema":{"type":"string","format":"binary"}},"application/x-tar":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"The site","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}},"delete":{"summary":"Delete the site","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"The link's key, and only that: an account key (hk_…) or session token here is refused with 401. `Authorization: Bearer <key>` works too, and on an account link so does the owning account's key or session, in the Authorization header only."}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/at/{username}/{name}":{"get":{"summary":"Look up an account link without calling it","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The page for an upload or share, or {kind: \"webhook\", id}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ok"}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/analytics/{id}":{"get":{"summary":"Who opened a link, from where and on what; the full breakdown once it is on an account","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The link id (8 characters)."},{"name":"key","in":"query","required":false,"schema":{"type":"string"},"description":"The link's key, and only that: an account key (hk_…) or session token here is refused with 401. `Authorization: Bearer <key>` works too, and on an account link so does the owning account's key or session, in the Authorization header only."},{"name":"interval","in":"query","schema":{"enum":["24h","7d","30d","90d","all"]},"description":"Account links only (default 30d); anonymous links always show their 24 hours."}],"responses":{"200":{"description":"The analytics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Analytics"}}}},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}}},"/claim":{"post":{"summary":"Keep an anonymous link on your account for good; its key is replaced","security":[{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimBody"}}}},"responses":{"200":{"description":"The claimed link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Claimed"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"}}}},"/me":{"get":{"summary":"Your account: its username, plan, billing, what it holds and its plan's limits","description":"A signed-in session only, not an account key.","security":[{"bearer":[]}],"responses":{"200":{"description":"The account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"$ref":"#/components/responses/Error"}}}},"/billing/checkout":{"post":{"summary":"A Stripe Checkout link for Pro","description":"With an account key the link is for the key's owner: give it to them. 409 when the account is already on Pro, 503 while billing is not set up.","security":[{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"interval":{"enum":["month","year"],"default":"month"}}}}}},"responses":{"200":{"description":"Where to pay","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Url"}}}},"401":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/billing/portal":{"post":{"summary":"A link to Stripe's customer portal: cancel, switch monthly and yearly, update the card, invoices","description":"A signed-in session only, not an account key. 409 before the account has checked out, 503 while billing is not set up.","security":[{"bearer":[]}],"responses":{"200":{"description":"The portal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Url"}}}},"401":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}}}}