Documentation/api/STANDARD_API.md
Complete guide to OpenEMR's Standard REST API for native OpenEMR resources.
The OpenEMR Standard REST API provides access to OpenEMR's native data structures through RESTful endpoints. This API is designed for:
| Use Standard API When | Use FHIR API When |
|---|---|
| Need OpenEMR-specific data structures | Need healthcare interoperability |
| Integrating with existing OpenEMR workflows | Building standards-compliant apps |
| Require direct table access | Need vendor-neutral data model |
| Administrative/operational tasks | Clinical data exchange |
| Legacy system integration | SMART on FHIR apps required |
Recommendation: For new healthcare applications, use the FHIR API for better interoperability.
Navigate to: Administration → Config → Connectors
Enable: ☑ Enable OpenEMR Standard REST API
Required: All API endpoints require HTTPS/TLS.
Set base URL: Administration → Config → Connectors → Site Address (required for OAuth2 and FHIR)
See Authentication Guide for OAuth2 client registration.
Required scopes: At minimum openid + api:oemr + resource-specific scopes.
Example:
openid api:oemr user/patient.rs user/encounter.rs
See Authorization Guide for complete scope listing.
Standard API endpoints use the following base URL pattern:
https://{your-openemr-host}/apis/{site}/api
https://localhost:9300/apis/default/api
https://localhost:9300/apis/alternate/api
{base}/[resource]
{base}/[resource]/[id]
{base}/[resource]/[id]/[sub-resource]
Examples:
GET https://localhost:9300/apis/default/api/patient
GET https://localhost:9300/apis/default/api/patient/123
GET https://localhost:9300/apis/default/api/patient/123/encounter
All Standard API requests require authentication via Bearer token.
curl -X GET 'https://localhost:9300/apis/default/api/patient' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'Accept: application/json'
See Authentication Guide for OAuth2 flows:
GET /apis/default/api/patient HTTP/1.1
Host: localhost:9300
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
Accept: application/json
| Resource | permissions | Description |
|---|---|---|
| Facility | crus | Manage facility/service location information (facility table). |
| Patient | crus | Manage patient demographics and registration (patient_data table). |
| Encounter | crus | Manage patient encounters and visits. (form_encounter table). |
| Soap Note | crus | Manage Encounter Form SOAP Notes (form_soap table). |
| Vitals | crus | Manage Patient Vitals (form_vitals,form_vital_details table). |
| Practitioner | rus | Manage practitioner information (users table). |
| Medical Problem | cruds | Manage patient medical problems and conditions (lists table). |
| Allergies | cruds | Manage patient allergies (lists table). |
| Medications | cruds | Manage patient medications (lists table). |
| Surgery Issues | cruds | Manage patient surgical issues (lists table). |
| Dental Issues | cruds | Manage patient dental issues (lists table). |
| Appointments | crus | Manage patient appointments (pc_event table). |
| Lists | rs | Read-only access to lists (lists table). |
| Users | rs | Read-only access to users (users table). |
| Insurance Company | crus | Manage insurance companies (insurance_data table). |
| Patient Documents | crs | Manage patient documents (documents table). |
| Patient Employers | rs | Read-only access to patient employers (employers table). |
| Patient Insurance | crus | Manage patient insurance information (patient_insurance table). |
| Patient Messages | cud | Create patient messages (patient_messages table). |
| Patient Referrals (transactions) | cruds | Manage patient referrals (lbt_data table). |
| Patient Immunizations | rs | Read-only access to patient immunizations (immunizations table). |
| Patient Procedures | rs | Read-only access to patient procedures (procedure_order,procedure_report,procedure_result table). |
| Drugs | rs | Read-only access to drugs (drugs table). |
| Prescriptions | rs | Read-only access to prescriptions (prescriptions table). |
| Permissions | Description |
|---|---|
| c | Create resource |
| r | Read resource |
| u | Update resource |
| d | Delete resource |
| s | Search/List resources |
EXPERIMENTAL - Patient-facing API endpoints.
Administration → Config → Connectors
https://localhost:9300/apis/default/portal
| Resource | permissions | Description |
|---|---|---|
| Patient | r | Get logged in patient's demographics and info. |
| Encounter | rs | Get logged in patient's encounters and visits. |
| Appointment | rs | Get logged in patient's appointments. |
| Permissions | Description |
|---|---|
| c | Create resource |
| r | Read resource |
| u | Update resource |
| d | Delete resource |
| s | Search/List resources |
Patients must have API credentials generated by their clinician:
See Authentication Guide for OAuth2 flows:
Patients authenticate using Password Grant with user_role=patient.
⚠️ Portal API is experimental:
patient/* scopes insteadAll Standard API responses use a consistent format:
{
"validationErrors": [],
"internalErrors": [],
"data": <result>
}
Fields:
validationErrors - Array of validation errors (client-side)internalErrors - Array of server errorsdata - Response payload (object for single result, array for multiple)Single Resource:
{
"validationErrors": [],
"internalErrors": [],
"data": {
"id": "1",
"uuid": "90cde167-7b9b-4ed1-bd55-533925cb2605",
"fname": "John",
"lname": "Smith"
}
}
Multiple Resources:
{
"validationErrors": [],
"internalErrors": [],
"data": [
{"id": "1", "fname": "John", "lname": "Smith"},
{"id": "2", "fname": "Jane", "lname": "Doe"}
]
}
Validation Error:
{
"validationErrors": [
"The fname field is required.",
"The DOB field must be a valid date."
],
"internalErrors": [],
"data": []
}
Internal Error:
{
"validationErrors": [],
"internalErrors": [
"Database connection failed"
],
"data": []
}
| Code | Meaning | Common Causes |
|---|---|---|
| 200 | OK | Successful GET/PUT/PATCH request |
| 201 | Created | Successful POST request |
| 400 | Bad Request | Invalid request format |
| 401 | Unauthorized | Missing or invalid token |
| 403 | Forbidden | Insufficient scopes |
| 404 | Not Found | Resource doesn't exist |
| 422 | Unprocessable Entity | Validation error |
| 500 | Internal Server Error | Server error |
401 Unauthorized
{
"error": "invalid_token",
"error_description": "The access token is missing"
}
Solution: Include Authorization: Bearer TOKEN header
403 Forbidden
{
"validationErrors": [],
"internalErrors": ["Insufficient scope for requested resource"],
"data": []
}
Solution: Request appropriate scopes during authorization
404 Not Found
{
"validationErrors": [],
"internalErrors": ["Resource not found"],
"data": []
}
Solution: Verify resource UUID exists
422 Validation Error
{
"validationErrors": [
"The fname field is required.",
"The DOB must be a date in the format Y-m-d."
],
"internalErrors": [],
"data": []
}
Solution: Fix request data validation errors
All UUIDs must be valid UUID v4 format:
90cde167-7b9b-4ed1-bd55-533925cb2605
All dates use ISO 8601 format:
YYYY-MM-DD
Example: 2024-01-15
curl -X POST 'https://localhost:9300/apis/default/api/patient' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1Qi...' \
-H 'Content-Type: application/json' \
--data '{
"title": "Mr",
"fname": "John",
"lname": "Smith",
"DOB": "1980-01-15",
"sex": "Male",
"street": "123 Main St",
"city": "Boston",
"state": "MA",
"postal_code": "12345",
"phone_home": "555-1234",
"email": "[email protected]"
}'
curl -X GET 'https://localhost:9300/apis/default/api/patient?lname=Smith&city=Boston' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1Qi...'
curl -X GET 'https://localhost:9300/apis/default/api/patient/90cde167-7b9b-4ed1-bd55-533925cb2605/encounter' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1Qi...'
curl -X POST 'https://localhost:9300/apis/default/api/appointment' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1Qi...' \
-H 'Content-Type: application/json' \
--data '{
"pc_catid": "5",
"pc_title": "Annual Physical",
"pc_duration": "1800",
"pc_eventDate": "2024-02-15",
"pc_startTime": "09:00:00",
"pc_facility": "1",
"pid": "1"
}'
curl -X POST 'https://localhost:9300/apis/default/api/patient/90cde167-7b9b-4ed1-bd55-533925cb2605/document' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1Qi...' \
-F 'file=@/path/to/lab-results.pdf' \
-F 'path=Lab Reports' \
-F 'date=2024-01-15'
curl -X POST 'https://localhost:9300/apis/default/api/patient/90cde167-7b9b-4ed1-bd55-533925cb2605/allergy' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1Qi...' \
-H 'Content-Type: application/json' \
--data '{
"title": "Penicillin",
"begdate": "2020-01-15",
"diagnosis": "Allergy to penicillin",
"severity_al": "severe",
"reaction": "Hives"
}'
curl -X POST 'https://localhost:9300/apis/default/api/patient/90cde167-7b9b-4ed1-bd55-533925cb2605/vital' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1Qi...' \
-H 'Content-Type: application/json' \
--data '{
"date": "2024-01-15",
"bps": "120",
"bpd": "80",
"weight": "180",
"height": "70",
"temperature": "98.6",
"pulse": "72",
"respiration": "16"
}'
Test Standard API endpoints interactively with Swagger UI:
https://your-openemr-install/swagger/
Navigate to the standard section in Swagger UI.
Test against live demo instances:
Set your client's redirect URI to:
<OpenEMR base URI>/swagger/oauth2-redirect.html
Example:
https://localhost:9300/swagger/oauth2-redirect.html
Next Steps:
Support:
Recommendation: For new integrations, consider using the FHIR API for better interoperability and standards compliance.
This documentation represents the collective knowledge and contributions of the OpenEMR open-source community. The content is based on:
The organization, structure, and presentation of this documentation was enhanced using Claude AI (Anthropic) to:
All technical accuracy is maintained from the original community-authored documentation.
OpenEMR is an open-source project. To contribute to this documentation:
Last Updated: November 2025 License: GPL v3
For complete documentation, see Documentation/api/