Programmatic access to telehealth licensure rules, compliance alerts, and state comparisons across all 50 US states and DC. All data is editor-reviewed and cited to primary sources.
All requests must include your API key as a Bearer token in the Authorization header.
curl https://api.statelicensure.com/v1/states \
-H "Authorization: Bearer your_api_key_here" 100,000 requests/month on the API plan. Enterprise plans have custom limits. Limits reset on the 1st of each month UTC.
Every response includes rate limit headers:
X-RateLimit-Limit: 100000
X-RateLimit-Remaining: 95779
X-RateLimit-Reset: 2026-06-01
X-RateLimit-Used: 4221
X-RateLimit-Warning: 4% of monthly limit used ← appears at 80%
When you exceed the monthly limit, requests return 429 rate_limit_exceeded.
Need more? Contact us for Enterprise.
All errors return JSON with error and message fields.
{ "error": "rate_limit_exceeded", "message": "Monthly limit reached", "reset_at": "2026-06-01", "upgrade_url": "..." } | Code | Error key | Description |
|---|---|---|
| 401 | unauthorized | Missing, invalid, or revoked API key. |
| 403 | forbidden | API access requires the API or Enterprise plan. |
| 403 | account_suspended | Your account has been suspended. |
| 403 | ip_not_allowed | Request IP is not in the allowlist for this key. |
| 404 | not_found | The requested resource does not exist. |
| 400 | invalid_param | A query parameter has an invalid value. |
| 429 | rate_limit_exceeded | Monthly request limit reached. Includes reset_at and upgrade_url. |
| 500 | server_error | Internal error. Contact hello@statelicensure.com. |
/v1/states Returns all 50 states and DC with their telehealth rule overview.
{
"object": "list",
"count": 51,
"data": [
{
"abbreviation": "CA",
"name": "California",
"compact_available": false,
"commercial_parity_law": true,
"informed_consent_required": true,
"audio_only_allowed": true,
"requires_out_of_state_reg": false,
"medicaid_parity": true,
"source": "Medical Board of California",
"last_verified": "2026-05-01"
},
...
]
} /v1/states/:abbr Returns full telehealth requirements for a single state or DC.
| Name | In | Required | Description |
|---|---|---|---|
| abbr | path | required | 2-letter abbreviation (e.g. CA, NY, TX, DC) |
{
"object": "state",
"abbreviation": "NY",
"name": "New York",
"licensure": {
"requires_state_license": true,
"compact_available": false,
"compact": null,
"requires_out_of_state_reg": false
},
"consent": { "informed_consent_required": true },
"modalities": { "live_video": true, "audio_only": true },
"prescribing": {
"telehealth_prescribing_allowed": true,
"prior_in_person_visit_required": false,
"ryan_haight_applies": true,
"ryan_haight_exceptions": "COVID-era DEA telehealth prescribing extension in effect; permanent rule pending",
"dea_special_registration_required": false,
"controlled_substances": {
"schedule_ii_allowed": true,
"schedule_iii_allowed": true,
"schedule_iv_allowed": true,
"schedule_v_allowed": true,
"buprenorphine_allowed": true,
"stimulants_allowed": true,
"benzodiazepines_allowed": true
},
"requires_dea": true,
"requires_cures_pmp": true,
"pmp": {
"name": "I-STOP",
"registration_url": "https://commerce.health.state.ny.us/nyspmp/",
"required_schedules": "II–IV",
"notes": "Must query I-STOP before prescribing Schedule II–IV. Mandatory for all controlled substance prescriptions."
},
"notes": "Full telehealth prescribing. ISTOP (NY PMP) registration required for Schedule II–IV.",
"source_url": "https://www.op.nysed.gov/",
"last_verified": "2026-05-01"
},
"reimbursement": {
"commercial_parity_law": true,
"medicaid_parity": true
},
"fees": {
"renewal_fee_usd": null,
"renewal_cycle_months": 24,
"cme_required_hours": 50
},
"source": "New York State Education Department",
"last_verified": "2026-05-01"
} /v1/states/:abbr/compare Returns side-by-side telehealth rules for any two states or DC.
| Name | In | Required | Description |
|---|---|---|---|
| abbr | path | required | First state abbreviation |
| with | query | required | Second state abbreviation (e.g. ?with=FL) |
{
"object": "comparison",
"state_a": { "abbreviation": "NY", "compact_available": false, ... },
"state_b": { "abbreviation": "FL", "compact_available": true, ... }
} /v1/states/bulk Fetch full requirements for multiple states in a single request (all 50 states + DC supported). Useful for loading a provider roster.
| Name | In | Required | Description |
|---|---|---|---|
| states | body | required | Array of state abbreviations including DC. Max 51. |
{
"object": "bulk",
"count": 3,
"not_found": [],
"data": {
"CA": { "object": "state", "abbreviation": "CA", "name": "California", ... },
"NY": { "object": "state", "abbreviation": "NY", "name": "New York", ... },
"FL": { "object": "state", "abbreviation": "FL", "name": "Florida", ... }
}
} /v1/states/:abbr/history Returns a log of requirement changes for a state — when compact eligibility changed, fees updated, registration requirements were added, etc.
| Name | In | Required | Description |
|---|---|---|---|
| abbr | path | required | 2-letter state abbreviation or DC |
| limit | query | optional | Results per page. 1–100, default 20. |
| page | query | optional | Page number, default 1. |
{
"object": "list",
"state": { "abbreviation": "CO", "name": "Colorado" },
"data": [
{
"id": "uuid",
"changed_at": "2026-05-29T12:00:00Z",
"changed_fields": {
"requires_out_of_state_reg": { "from": false, "to": true },
"out_of_state_reg_deadline": { "from": null, "to": "2026-01-01" }
},
"snapshot": { "compact_available": true, "commercial_parity_law": true, ... },
"source_note": null
}
],
"count": 1,
"total": 1,
"page": 1,
"total_pages": 1,
"has_more": false
} /v1/alerts Returns published compliance alerts, newest first.
| Name | In | Required | Description |
|---|---|---|---|
| state | query | optional | Filter by state abbreviation (e.g. CA, DC). Omit for all states including federal. |
| severity | query | optional | practice_changing | new_rule | informational |
| since | query | optional | ISO date — return alerts published after this date (e.g. 2026-05-01) |
| limit | query | optional | Results per page. 1–100, default 20. |
| page | query | optional | Page number, default 1. |
{
"object": "list",
"data": [
{
"id": "uuid",
"object": "alert",
"title": "Florida out-of-state telehealth registration required",
"summary": "HB 1035 requires out-of-state physicians to register...",
"severity": "practice_changing",
"alert_type": "new_rule",
"state": { "abbreviation": "FL", "name": "Florida" },
"federal": false,
"action_required": true,
"action_notes": "Register with FL Board of Medicine before Jul 1, 2026",
"source_url": "https://flhealthsource.gov/telehealth/",
"published_at": "2026-05-18T00:00:00Z"
}
],
"count": 1,
"total": 22,
"page": 1,
"total_pages": 2,
"has_more": true
} /v1/alerts/:id Returns a single alert by ID.
| Name | In | Required | Description |
|---|---|---|---|
| id | path | required | Alert UUID |
{
"id": "uuid",
"object": "alert",
"title": "...",
...
} /v1/usage Returns your API usage for the current and past months.
{
"object": "usage",
"current_period": {
"requests_used": 4221,
"monthly_limit": 100000,
"remaining": 95779,
"percent_used": 4,
"reset_at": "2026-06-01",
"warning": null
},
"history": [
{ "month": "2026-05-01", "request_count": 4221 },
{ "month": "2026-04-01", "request_count": 12883 }
]
} Instead of polling the API, register an HTTPS endpoint and we'll send you a POST request the moment a telehealth rule change alert is published.
| Event | Description |
|---|---|
| alert.published | Fires when a telehealth rule change alert is approved and published. Includes full alert payload. |
| requirement.changed | Fires when a state telehealth requirement field changes (compact eligibility, parity law, prescribing rules, fees, etc). Includes a diff of changed fields and full snapshot. |
{
"event": "alert.published",
"id": "uuid",
"title": "Florida: Out-of-state telehealth providers must register by July 1, 2026",
"summary": "HB 1035 requires out-of-state physicians...",
"severity": "practice_changing",
"alert_type": "new_rule",
"state": { "abbreviation": "FL", "name": "Florida" },
"federal": false,
"action_required": true,
"action_notes": "Register with the Florida Board of Medicine before July 1, 2026",
"source_url": "https://flboardofmedicine.gov/",
"published_at": "2026-05-28T01:00:00Z"
} {
"event": "requirement.changed",
"state": { "abbreviation": "CO", "name": "Colorado" },
"changed_fields": {
"requires_out_of_state_reg": { "from": false, "to": true },
"out_of_state_reg_deadline": { "from": null, "to": "2026-01-01" }
},
"snapshot": {
"compact_available": true,
"commercial_parity_law": true,
"informed_consent_required": false,
"audio_only_allowed": true,
"requires_out_of_state_reg": true,
"out_of_state_reg_deadline": "2026-01-01",
"prescribing_allowed": true,
"controlled_substance_allowed": true,
"renewal_fee_usd": 62500,
"source_name": "Colorado Medical Board",
"source_url": "https://dpo.colorado.gov/MedicalBoard",
"last_verified_at": "2026-05-29"
},
"changed_at": "2026-05-29T12:00:00Z"
} Every webhook request includes a signature header. Verify it to ensure the request came from StateLicensure.
X-StateLicensure-Signature: t=1748390400,v1=abc123... Verify in Node.js:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const [tPart, vPart] = signature.split(',');
const timestamp = tPart.replace('t=', '');
const expected = vPart.replace('v1=', '');
const hmac = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${payload}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(hmac),
Buffer.from(expected)
);
} Manage webhook endpoints at app.statelicensure.com/api-keys → Webhooks tab. Up to 10 endpoints per organization. Delivery is attempted up to 3 times — retries run on the next delivery cycle (every 5 minutes).
Create, view, and revoke API keys from the StateLicensure app at https://app.statelicensure.com/api-keys.