{"openapi":"3.1.0","info":{"title":"PT365 HEP Integration API","version":"2026-08-23","description":"White-label, no-PHI exercise catalog and prescription-picker API. Never send patient, encounter, diagnosis, or contact data.","contact":{"name":"PT365 Integration Support","email":"HEP@physicaltherapy365.com"},"license":{"name":"Commercial PT365 HEP license required for production"}},"servers":[{"url":"https://www.physicaltherapy365.com/api/v1","description":"Hosted API"},{"url":"http://localhost:3000/api/v1","description":"Local development"}],"tags":[{"name":"Authentication"},{"name":"Catalog"},{"name":"Picker"},{"name":"Webhooks"},{"name":"Sandbox"}],"paths":{"/oauth/token":{"post":{"tags":["Authentication"],"summary":"Exchange client credentials for an access token","security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["grant_type"],"properties":{"grant_type":{"const":"client_credentials"},"client_id":{"type":"string"},"client_secret":{"type":"string","format":"password"}}}}}},"responses":{"200":{"description":"Access token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/exercises":{"get":{"tags":["Catalog"],"summary":"Search and page through exercises","security":[{"oauth2":["catalog:read"]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Search names, descriptions, targets, tags, and synonyms","schema":{"type":"string"}},{"name":"region","in":"query","required":false,"description":"Body region","schema":{"type":"string"}},{"name":"category","in":"query","required":false,"description":"Exercise category","schema":{"type":"string"}},{"name":"level","in":"query","required":false,"description":"Difficulty level","schema":{"type":"string"}},{"name":"equipment","in":"query","required":false,"description":"Equipment text","schema":{"type":"string"}},{"name":"tags","in":"query","required":false,"description":"Comma-separated tags","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Lifecycle status","schema":{"type":"string"}},{"name":"updated_after","in":"query","required":false,"description":"ISO 8601 date-time","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"Opaque page cursor","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Exercise page","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Exercise"}},"meta":{"$ref":"#/components/schemas/PageMeta"}}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/exercises/{id}":{"get":{"tags":["Catalog"],"summary":"Retrieve a current or historical exercise revision","security":[{"oauth2":["catalog:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"revision","in":"query","required":false,"description":"Immutable content revision","schema":{"type":"string"}}],"responses":{"200":{"description":"Exercise","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Exercise"}}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/taxonomies":{"get":{"tags":["Catalog"],"summary":"List taxonomy values","security":[{"oauth2":["catalog:read"]}],"responses":{"200":{"description":"Taxonomies"},"401":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/catalog/changes":{"get":{"tags":["Catalog"],"summary":"Synchronize catalog lifecycle events","security":[{"oauth2":["catalog:read"]}],"parameters":[{"name":"cursor","in":"query","required":false,"description":"Opaque change cursor","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":250,"default":100}}],"responses":{"200":{"description":"Ordered change page"},"401":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/picker/sessions":{"post":{"tags":["Picker"],"summary":"Create a short-lived origin-bound picker session","security":[{"oauth2":["picker:create"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PickerSessionRequest"}}}},"responses":{"201":{"description":"Picker launch URL"},"400":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhook endpoints","security":[{"oauth2":["webhooks:manage"]}],"responses":{"200":{"description":"Webhook list"},"401":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Webhooks"],"summary":"Create a signed webhook endpoint","security":[{"oauth2":["webhooks:manage"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["url","events"],"properties":{"url":{"type":"string","format":"uri","pattern":"^https://"},"events":{"type":"array","uniqueItems":true,"items":{"enum":["exercise.published","exercise.updated","exercise.deprecated","exercise.withdrawn"]}}}}}}},"responses":{"201":{"description":"Webhook and one-time signing secret"},"400":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}":{"delete":{"tags":["Webhooks"],"summary":"Delete a webhook","security":[{"oauth2":["webhooks:manage"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sandbox/register":{"post":{"tags":["Sandbox"],"summary":"Request work-email sandbox verification","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["company","email","origin"],"properties":{"company":{"type":"string","maxLength":120},"email":{"type":"string","format":"email","maxLength":254},"origin":{"type":"string","format":"uri"},"website":{"type":"string","description":"Leave empty"}}}}}},"responses":{"202":{"description":"Verification sent"},"400":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"oauth2":{"type":"oauth2","flows":{"clientCredentials":{"tokenUrl":"/api/v1/oauth/token","scopes":{"catalog:read":"Read licensed catalog","picker:create":"Create picker sessions","webhooks:manage":"Manage catalog webhooks"}}}}},"schemas":{"Token":{"type":"object","required":["access_token","token_type","expires_in","scope","environment"],"properties":{"access_token":{"type":"string"},"token_type":{"const":"Bearer"},"expires_in":{"type":"integer"},"scope":{"type":"string"},"environment":{"enum":["sandbox","production"]}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}}}}},"PageMeta":{"type":"object","properties":{"environment":{"enum":["sandbox","production"]},"total":{"type":"integer"},"limit":{"type":"integer"},"nextCursor":{"type":["string","null"]},"catalogRevision":{"type":"string"}}},"Prescription":{"type":"object","additionalProperties":false,"required":["exerciseId","revision","side"],"properties":{"exerciseId":{"type":"string"},"revision":{"type":"string"},"side":{"enum":["left","right","bilateral","not_applicable"]},"sets":{"type":"integer","minimum":1},"repetitions":{"type":"integer","minimum":1},"holdSeconds":{"type":"integer","minimum":1},"durationMinutes":{"type":"integer","minimum":1},"frequency":{"type":"object","additionalProperties":false,"required":["times","period"],"properties":{"times":{"type":"integer","minimum":1,"maximum":20},"period":{"enum":["day","week"]}}},"resistance":{"type":"string","maxLength":80},"restSeconds":{"type":"integer","minimum":0},"customDosage":{"type":"string","maxLength":200}}},"PickerSessionRequest":{"type":"object","additionalProperties":false,"required":["origin","clinicianId"],"description":"No patient or encounter fields permitted","properties":{"origin":{"type":"string","format":"uri"},"clinicianId":{"type":"string","pattern":"^[A-Za-z0-9._:-]{8,128}$"},"theme":{"type":"object","additionalProperties":false,"properties":{"brandName":{"type":"string","maxLength":80},"primaryColor":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},"backgroundColor":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"}}},"initialSelection":{"type":"array","maxItems":20,"items":{"$ref":"#/components/schemas/Prescription"}}}},"Media":{"type":"object","required":["role","url","mimeType","width","height","sha256","alt"],"properties":{"role":{"enum":["start","end"]},"url":{"type":"string","format":"uri"},"mimeType":{"const":"image/png"},"width":{"type":"integer"},"height":{"type":"integer"},"sha256":{"type":"string"},"alt":{"type":"string"}}},"Exercise":{"type":"object","required":["id","slug","revision","status","name","description","steps","media"],"properties":{"id":{"type":"string","pattern":"^ex_[0-9a-f]{20}$"},"slug":{"type":"string"},"revision":{"type":"string"},"status":{"enum":["active","deprecated","withdrawn"]},"publishedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"replacementId":{"type":"string"},"changeReason":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"steps":{"type":"array","items":{"type":"string"}},"cue":{"type":"string"},"region":{"enum":["Knee","Shoulder","Low Back","Neck","Hip","Ankle","Elbow / Wrist / Hand"]},"category":{"enum":["Mobility","Strength","Balance","Stretch"]},"level":{"enum":["Early","Foundation","Functional"]},"target":{"type":"string"},"equipment":{"type":"array","items":{"type":"string"}},"tags":{"type":"array","items":{"type":"string"}},"searchSynonyms":{"type":"array","items":{"type":"string"}},"defaultPrescription":{"type":"object"},"media":{"type":"array","minItems":2,"maxItems":2,"items":{"$ref":"#/components/schemas/Media"}}}}}}}