{"openapi":"3.1.0","info":{"title":"WarpTunnel","version":"1.0.0","description":"Personal HTML publishing. Maximum HTML size 2097152 bytes; default expiration 30 days. Public links require no authentication. See /llms.txt."},"servers":[{"url":"https://warptunnel.com"}],"paths":{"/api/v1/pages":{"post":{"operationId":"publish","summary":"Publish HTML; expires in 30 days unless keep is true.","security":[{"bearerAuth":[]}],"parameters":[{"name":"title","in":"query","description":"Title for raw text/html uploads.","schema":{"type":"string","maxLength":200}},{"name":"keep","in":"query","description":"Retention setting for raw text/html uploads.","schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"additionalProperties":false,"properties":{"file":{"type":"string","format":"binary"},"title":{"type":"string","maxLength":200},"keep":{"type":"boolean"}}}},"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"keep":{"type":"boolean"},"html":{"type":"string","minLength":1}},"required":["html"],"additionalProperties":false}},"text/html":{"schema":{"type":"string","minLength":1}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"},"title":{"type":"string","minLength":1,"maxLength":200},"url":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"keep":{"type":"boolean"},"bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"version":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id","title","url","createdAt","updatedAt","expiresAt","keep","bytes","version"],"additionalProperties":false}}}},"default":{"description":"Actionable error. Typical statuses: 400, 401, 404, 409, 413, 415, 500, 503.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"docs":{"type":"string","format":"uri"},"details":{}},"required":["code","message","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}},"get":{"operationId":"list","summary":"List active pages with pagination.","security":[{"bearerAuth":[]}],"parameters":[{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"pages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"},"title":{"type":"string","minLength":1,"maxLength":200},"url":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"keep":{"type":"boolean"},"bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"version":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id","title","url","createdAt","updatedAt","expiresAt","keep","bytes","version"],"additionalProperties":false}},"cursor":{"type":["string","null"]}},"required":["pages","cursor"],"additionalProperties":false}}}},"default":{"description":"Actionable error. Typical statuses: 400, 401, 404, 409, 413, 415, 500, 503.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"docs":{"type":"string","format":"uri"},"details":{}},"required":["code","message","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/api/v1/pages/{id}":{"get":{"operationId":"info","summary":"Read page metadata.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"},"title":{"type":"string","minLength":1,"maxLength":200},"url":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"keep":{"type":"boolean"},"bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"version":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id","title","url","createdAt","updatedAt","expiresAt","keep","bytes","version"],"additionalProperties":false}}}},"default":{"description":"Actionable error. Typical statuses: 400, 401, 404, 409, 413, 415, 500, 503.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"docs":{"type":"string","format":"uri"},"details":{}},"required":["code","message","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}},"put":{"operationId":"update","summary":"Replace HTML, preserving the URL and keep setting unless supplied. Restarts temporary expiration.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"}},{"name":"If-Match","in":"header","description":"Optional quoted page version from metadata. A stale version returns 409.","schema":{"type":"string"}},{"name":"title","in":"query","description":"Title for raw text/html uploads.","schema":{"type":"string","maxLength":200}},{"name":"keep","in":"query","description":"Retention setting for raw text/html uploads.","schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"additionalProperties":false,"properties":{"file":{"type":"string","format":"binary"},"title":{"type":"string","maxLength":200},"keep":{"type":"boolean"}}}},"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"keep":{"type":"boolean"},"html":{"type":"string","minLength":1}},"required":["html"],"additionalProperties":false}},"text/html":{"schema":{"type":"string","minLength":1}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"},"title":{"type":"string","minLength":1,"maxLength":200},"url":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"keep":{"type":"boolean"},"bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"version":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id","title","url","createdAt","updatedAt","expiresAt","keep","bytes","version"],"additionalProperties":false}}}},"default":{"description":"Actionable error. Typical statuses: 400, 401, 404, 409, 413, 415, 500, 503.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"docs":{"type":"string","format":"uri"},"details":{}},"required":["code","message","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}},"delete":{"operationId":"delete","summary":"Delete a page. Repeating deletion is safe.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"}},{"name":"If-Match","in":"header","description":"Optional quoted page version from metadata. A stale version returns 409.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"},"deleted":{"type":"boolean","const":true}},"required":["id","deleted"],"additionalProperties":false}}}},"default":{"description":"Actionable error. Typical statuses: 400, 401, 404, 409, 413, 415, 500, 503.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"docs":{"type":"string","format":"uri"},"details":{}},"required":["code","message","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/api/v1/pages/{id}/content":{"get":{"operationId":"content","summary":"Download the original HTML.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"}}],"responses":{"200":{"description":"Success","content":{"text/html":{"schema":{"type":"string"}}}},"default":{"description":"Actionable error. Typical statuses: 400, 401, 404, 409, 413, 415, 500, 503.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"docs":{"type":"string","format":"uri"},"details":{}},"required":["code","message","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/api/v1/pages/{id}/retention":{"patch":{"operationId":"retention","summary":"Keep indefinitely or expire in 1–30 days from now.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"}},{"name":"If-Match","in":"header","description":"Optional quoted page version from metadata. A stale version returns 409.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"keep":{"type":"boolean","const":true}},"required":["keep"],"additionalProperties":false},{"type":"object","properties":{"keep":{"type":"boolean","const":false},"days":{"default":30,"type":"integer","minimum":1,"maximum":30}},"required":["keep","days"],"additionalProperties":false}]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z]{3,8}-[a-z]{3,8}-[2-9a-km-np-z]{4}$"},"title":{"type":"string","minLength":1,"maxLength":200},"url":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"keep":{"type":"boolean"},"bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"version":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id","title","url","createdAt","updatedAt","expiresAt","keep","bytes","version"],"additionalProperties":false}}}},"default":{"description":"Actionable error. Typical statuses: 400, 401, 404, 409, 413, 415, 500, 503.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"docs":{"type":"string","format":"uri"},"details":{}},"required":["code","message","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}}}}