Files
claudetools/.claude/skills/alis/references/api-reference.md
Howard Enos 31f2bdb84f sync: auto-sync from HOWARD-HOME at 2026-06-29 16:55:22
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-06-29 16:55:22
2026-06-29 16:55:55 -07:00

76 lines
4.0 KiB
Markdown

# ALIS API Reference (for the `alis` skill)
Source of truth: the live Swagger specs the ALIS API publishes.
- Swagger UI: https://api.alisonline.com/index.html
- Raw specs: `https://api.alisonline.com/specs/v1/openapi.json` (also `v2`, `v3`)
- Vendor docs (gated, requires support login): https://support.alisonline.com/
ALIS = Medtelligent's assisted-living EHR. The API is a **partner/App-Store integration
API**. A tenant lives at `<tenant>.alisonline.com` (e.g. `cascadestucson.alisonline.com`)
but **all API traffic goes to the shared host `api.alisonline.com`**, scoped by the
logged-in user's company + a `communityId`.
Spec sizes at build (2026-06-29): v1 = 139 paths (main surface), v2 = 14 (newer streaming
exports + incidents), v3 = 5 (streaming exports). Tags: User (auth), Admin, Export:*,
Integration:* (Billing/Care/Communities/Residents/Staff/Prospects/Incidents/Hooks/App
Specific), Pharmacy.
## Authentication
Global security is an OR list: `Bearer | BasicAuth | VendorKey` — any one authorizes.
- **Bearer (what this skill uses):**
- `POST /user/tokens` body `{"username":"<user>@<tenantKey>","password":"..."}`
`{ accessToken (JWT, expiresIn 3600), refreshToken }`
- `POST /user/tokens/refresh` body `{accessToken, refreshToken}` → new pair
- Send `Authorization: Bearer <accessToken>` on every call.
- **The username MUST be tenant-qualified.** `howard.enos` → HTTP 400
(`Username must match ^<username>@<tenantKey>$`); `howard.enos@cascadestucson` → 200.
tenantKey = the tenant subdomain (`cascadestucson`).
- **VendorKey:** `X-Vendor-Key: <key>` header — issued by Medtelligent when an App-Store app
is installed (per-client creds). Not required when a user JWT is used.
- **BasicAuth:** `Authorization: Basic ...` — the existing
`clients/cascades-tucson/alis-api-microsoft-basic` vault entry is this style (used by
Microsoft to call ALIS).
## Staff endpoints — READ ONLY (this is the key constraint)
There is **no** POST/PUT/PATCH/DELETE for staff anywhere in v1/v2/v3. All six are GET:
| Method | Path | Returns |
|---|---|---|
| GET | `/v1/integration/staff?communityId={id}` | roster (communityId REQUIRED — omitting → 403 "Not authorized for facility 0") |
| GET | `/v1/integration/staff/{staffId}` | one staff member |
| GET | `/v1/integration/staff/{staffId}/basicInfo` | address, license, jobRole, **securityRoles** |
| GET | `/v1/integration/staff/{staffId}/photo` | photo |
| GET | `/v1/export/staff` | bulk export |
| GET | `/v1/export/staff/complianceDetails` | training/compliance |
Staff list record fields: `staffId, companyTextKey, communityId, firstName, lastName,
nickName, staffRecordNumber, mobilePhoneNumber, primaryEmail, dateOfBirth, status,
hireDate, dischargeDate, hasPhoto, jobRole, securityRoles[]`.
Optional query params on the list: `status`, `includeAssociatedStaff`.
**To CHANGE staff** → there is no API. Use the ALIS web UI **Staff → Import** with the
13-column .xls (see `import_builder.py` / SKILL.md). That import sets `Login Enabled` and
`Password`, i.e. it is also how staff *logins* are provisioned.
## Other write surfaces (out of scope for this skill, but available on the JWT)
The API *does* allow writes for non-staff objects, e.g.:
- Residents: `POST /v1/integration/residents` (create), `POST .../{residentId}/basicInfo`,
contacts, photo, observations, vitals, room assignments, diagnoses, monitoring flags.
- Prospects (CRM): `POST/PUT /v1/integration/prospects...`
- Billing: incidental charges, payments, statements.
- Webhooks: `/v1/integration/hooks` (subscribe to object create/modify events).
## Scope observed (Cascades, communityId 622, build 2026-06-29)
- 1 community: 622 = "Cascades of Tucson".
- 612 staff total (504 Discharged, 107 Hired, 1 Observer).
- 23 distinct Security Roles in use; 74 distinct Job Role strings (free text — includes
typos/dupes like `caregiver` vs `Certified Caregiver`, and junk like `Test`,
`Dead Weight` — treat Job Role as free text, Security Roles as the controlled list).
- See `role-map.json` for the snapshot + job-role → security-role mapping.