OSCAR EMR SOAP API Reference¶
Last Updated: 2026-03-09
Complete reference for all SOAP web services exposed by OSCAR EMR via Apache CXF. This is the authoritative API surface used by VitaraVox's OscarSoapAdapter.
VitaraVox Operations Actually Used
Of the 14 SOAP services and 50+ operations, VitaraVox calls only 8 operations across 3 services:
- ScheduleService:
getDayWorkSchedule,getAppointmentsForDateRangeAndProvider2,addAppointment,updateAppointment,getScheduleTemplateCodes - DemographicService:
getDemographic,searchDemographicByName - ProviderService:
getProviders2(true)
When preferRest=true (Kai-hosted OSCAR), all operations route to OAuth 1.0a REST endpoints instead. See Adapter Implementations and OSCAR OAuth Flow.
Overview¶
Three API Surfaces
This page covers Surface 1: SOAP Web Services only. OSCAR also exposes Cookie-Authenticated REST (/ws/rs/*) and OAuth-Protected REST (/ws/services/*). For the full picture — including Cloudflare WAF behavior on Kai-hosted instances — see OSCAR API Protocol Analysis.
OSCAR exposes 14 SOAP web services at the base path /oscar/ws/. Services use document/literal SOAP binding over HTTP with GZIP compression enabled on all endpoints (threshold: 0 bytes).
Cloudflare WAF on Kai-Hosted Instances
Kai-hosted OSCAR instances (e.g., fbh.kai-oscar.com) have a Cloudflare WAF that blocks SOAP requests. The WAF triggers on Content-Type: text/xml combined with a <soapenv:Envelope> body. For Kai-hosted clinics, use the OAuth REST path (preferRest=true) instead. See Protocol Analysis for the 8-test proof matrix.
| # | Service | Endpoint Path | Auth Required |
|---|---|---|---|
| 1 | DemographicService | /oscar/ws/DemographicService |
Yes |
| 2 | ProviderService | /oscar/ws/ProviderService |
Yes |
| 3 | ScheduleService | /oscar/ws/ScheduleService |
Yes |
| 4 | AllergyService | /oscar/ws/AllergyService |
Yes |
| 5 | PrescriptionService | /oscar/ws/PrescriptionService |
Yes |
| 6 | MeasurementService | /oscar/ws/MeasurementService |
Yes |
| 7 | DocumentService | /oscar/ws/DocumentService |
Yes |
| 8 | PreventionService | /oscar/ws/PreventionService |
Yes |
| 9 | BookingService | /oscar/ws/BookingService |
Yes |
| 10 | ProgramService | /oscar/ws/ProgramService |
Yes |
| 11 | FacilityService | /oscar/ws/FacilityService |
Yes |
| 12 | LabUploadService | /oscar/ws/LabUploadService |
Yes |
| 13 | LoginService | /oscar/ws/LoginService |
No |
| 14 | SystemInfoService | /oscar/ws/SystemInfoService |
No |
WSDL Discovery
Append ?wsdl to any endpoint path to retrieve the WSDL definition.
Example: https://your-oscar:8443/oscar/ws/DemographicService?wsdl
Authentication¶
WS-Security (WSS4J) — UsernameToken Profile¶
All endpoints except LoginService and SystemInfoService require WS-Security authentication via the UsernameToken profile.
How It Works¶
- Every SOAP request must include a WS-Security header with a
UsernameTokenelement - OSCAR uses Apache CXF's
WSS4JInInterceptorconfigured forUsernameTokenaction withPasswordTexttype - The
OscarUsernameTokenValidatorvalidates credentials against thesecuritydatabase table - On success, a
LoggedInInfosession is created for the request; on failure, aSoapFaultis thrown
Credential Format¶
| Field | Value | Description |
|---|---|---|
| Username | Security ID (integer) | The security_no from the security table — not the login username |
| Password | Password or Security Token | Either the user's actual password, or a session token from LoginWs.login2() |
| Password Type | PasswordText |
Plaintext password (not digest) |
| Timestamp | Not required | hasTimeStamp: false |
| Nonce | Not required | hasNonce: false |
Username is NOT the login name
The WS-Security Username field expects the numeric Security ID (e.g., "1"), not the text login username (e.g., "admin"). Use the LoginService.login2() method first to exchange a username/password for a Security ID and token.
Two-Step Authentication Flow¶
Step 1: Call LoginService.login2(username, password)
→ Returns: { securityId: 1, securityTokenKey: "8374629103847" }
Step 2: Use securityId as WS-Security Username,
securityTokenKey as WS-Security Password
for all subsequent SOAP calls
Security Token Generation¶
The security token is deterministic per JVM session — it's derived from:
- JVM start time (
ManagementFactory.getRuntimeMXBean().getStartTime()) - Password hash (a numeric mangling of the user's stored password)
This means tokens are invalidated on OSCAR/Tomcat restart.
SOAP Header Example¶
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ws="http://ws.oscarehr.org/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>1</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">8374629103847</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<!-- method call here -->
</soapenv:Body>
</soapenv:Envelope>
Authentication Logging¶
All auth attempts are logged to the oscar_log table:
| Event | Action | Logged Fields |
|---|---|---|
| Success | WS_LOGIN_SUCCESS |
provider_no, IP address |
| Failure | WS_LOGIN_FAILURE |
IP address |
Account Expiry¶
Accounts with date_expiredate in the past are rejected, even with valid credentials.
Common Patterns¶
Date/Time Parameters¶
All date/time parameters use ISO 8601 format: YYYY-MM-DDTHH:MM:SS
VitaraVox Implementation Note
Our OscarSoapAdapter always appends T00:00:00 to date-only strings. OSCAR's JAXB layer rejects bare YYYY-MM-DD format. See Adapter Implementations for details.
Pagination Parameters¶
Many list methods accept pagination:
| Parameter | Type | Description |
|---|---|---|
startIndex |
int |
Starting position (0-based) |
itemsToReturn |
int |
Maximum results to return |
Program/Provider/Demographic Filter¶
A common pattern for filtering clinical data:
| Parameter | Type | Description |
|---|---|---|
programId |
int |
Program ID filter (0 = all programs) |
providerNo |
string |
Provider number filter ("" = all providers) |
demographicId |
int |
Patient ID number |
updatedAfterThisDate |
dateTime |
Only return records modified after this date |
GMT Time Flag¶
Schedule-related methods have v1 (deprecated, local time) and v2 (with useGMTTime boolean) variants. Always prefer the v2 methods.
WSDL Positional Arguments¶
OSCAR SOAP WSDL uses positional args (arg0, arg1, ...) not named parameters. Always check the WSDL complexType definitions for the correct argument order.
Service Details¶
DemographicService¶
Patient demographics management. The most commonly used service for patient lookups, searches, and synchronization.
Java class: org.oscarehr.ws.DemographicWs
WSDL: /oscar/ws/DemographicService?wsdl
No addDemographic
OSCAR's DemographicService has no addDemographic operation. Patient registration must be done through the OSCAR web UI. Our voice agent Registration flow creates a notification for the clinic rather than directly creating patients.
Operations¶
| Operation | Parameters | Returns | Notes |
|---|---|---|---|
getDemographic |
arg0: int (demographicNo) |
demographicTransfer |
Basic patient record |
getDemographic2 |
arg0: int (demographicNo) |
demographicTransfer2 |
Enhanced record with extra fields |
getDemographics |
arg0: int[] (array of IDs) |
demographicTransfer[] |
Batch lookup |
searchDemographicByName |
arg0: string (searchString), arg1: int (startIndex), arg2: int (itemsToReturn) |
demographicTransfer[] |
Name search |
searchDemographicsByAttributes |
arg0: string (hin), arg1: string (firstName), arg2: string (lastName), arg3: string (gender), arg4: dateTime (dob), arg5: string (city), arg6: string (province), arg7: string (phone), arg8: string (email), arg9: string (alias), arg10: int (startIndex), arg11: int (itemsToReturn) |
demographicTransfer[] |
Multi-field search |
getActiveDemographicsAfter |
lastUpdate: dateTime, fields: string |
demographicTransfer[] |
Sync — deprecated |
getActiveDemographicsAfter2 |
lastUpdate: dateTime, fields: string |
demographicTransfer2[] |
Sync — preferred |
getConsentedDemographicIdsAfter |
lastUpdate: dateTime |
int[] |
PHR-consented patients |
getAdmittedDemographicIdsByProgramProvider |
arg0: int (programId), arg1: string (providerNo) |
int[] |
Admitted patient IDs |
getDemographicIdsWithMyOscarAccounts |
arg0: int (startIdExclusive), arg1: int (itemsToReturn) |
int[] |
MyOscar-linked patients |
getDemographicByMyOscarUserName |
arg0: string (myOscarUserName) |
demographicTransfer |
Lookup by MyOscar |
getLatestPhrVerificationByDemographic |
arg0: int (demographicId) |
phrVerificationTransfer |
PHR verification status |
isPhrVerifiedToSendMessages |
arg0: int (demographicId) |
boolean |
PHR messaging check |
isPhrVerifiedToSendMedicalData |
arg0: int (demographicId) |
boolean |
PHR data sharing check |
writePHRId |
arg0: int (demographicNo), arg1: string (phrId) |
string |
Write PHR identifier |
demographicTransfer Fields¶
firstName, lastName, dateOfBirth, email, phone, phone2, cellPhone,
gender, sex, title, address, city, postal, province,
patientStatus, rosterStatus, familyDoctor, activeCount, hsAlertCount,
headRecord, chartNo, hin, dateJoined, lastUpdateDate, patientStatusDate
demographicTransfer2 Additional Fields¶
middleNames, newsletter, consentToUseEmailForCare,
countryOfOrigin, residentialAddress (extended fields)
ProviderService¶
Provider/clinician management.
Java class: org.oscarehr.ws.ProviderWs
WSDL: /oscar/ws/ProviderService?wsdl
No getProvider(id)
There is no single-provider lookup. Use getProviders2(true) and filter client-side. Our OscarSoapAdapter caches the full provider list to avoid repeated calls.
Operations¶
| Operation | Parameters | Returns | Notes |
|---|---|---|---|
getLoggedInProviderTransfer |
(none) | providerTransfer |
Current authenticated provider |
getProviders |
arg0: boolean (active) |
providerTransfer[] |
Deprecated — use getProviders2 |
getProviders2 |
arg0: Boolean (active) |
providerTransfer[] |
List providers by active status |
getProviderProperties |
arg0: string (providerNo), arg1: string (propertyName) |
providerPropertyTransfer[] |
Provider config properties |
providerTransfer Fields¶
firstName, lastName, email, phone, workPhone, address, dob, sex,
specialty, providerType, providerActivity, status, team,
billingNo, ohipNo, practitionerNo, practitionerNoType,
rmaNo, hsoNo, title, comments, signedConfidentiality
ScheduleService¶
Appointments and scheduling. The largest service with 20 operations covering appointment CRUD, schedule templates, and work schedules.
Java class: org.oscarehr.ws.ScheduleWs
WSDL: /oscar/ws/ScheduleService?wsdl
Appointment Retrieval¶
| Operation | Parameters | Returns | Notes |
|---|---|---|---|
getAppointment |
arg0: int (appointmentId) |
appointmentTransfer |
Deprecated — local time |
getAppointment2 |
arg0: int (appointmentId), arg1: boolean (useGMTTime) |
appointmentTransfer |
Preferred |
getAppointmentsForProvider |
arg0: string (providerNo), arg1: dateTime (date) |
appointmentTransfer[] |
Deprecated |
getAppointmentsForProvider2 |
arg0: string, arg1: dateTime, arg2: boolean (useGMTTime) |
appointmentTransfer[] |
Preferred |
getAppointmentsForPatient |
arg0: int (demographicId), arg1: int (startIndex), arg2: int (itemsToReturn) |
appointmentTransfer[] |
Deprecated |
getAppointmentsForPatient2 |
arg0: int, arg1: int, arg2: int, arg3: boolean (useGMTTime) |
appointmentTransfer[] |
Preferred |
getAppointmentsForDateRangeAndProvider |
arg0: dateTime (start), arg1: dateTime (end), arg2: string (providerNo) |
appointmentTransfer[] |
Deprecated |
getAppointmentsForDateRangeAndProvider2 |
arg0: dateTime, arg1: dateTime, arg2: string, arg3: boolean (useGMTTime) |
appointmentTransfer[] |
Preferred — date range query |
getAppointmentsByDemographicIdAfter |
lastUpdate: dateTime, demographicId: int, useGMTTime: boolean |
appointmentTransfer[] |
Patient sync |
getAppointmentsByProgramProviderDemographicDate |
arg0: int (programId), arg1: string (providerNo), arg2: int (demographicId), arg3: dateTime, arg4: int (limit), arg5: boolean (useGMTTime) |
appointmentTransfer[] |
Filtered query |
getAppointmentsUpdatedAfterDate |
arg0: dateTime, arg1: int (limit), arg2: boolean (useGMTTime) |
appointmentTransfer[] |
Global sync |
getAppointmentArchivesUpdatedAfterDate |
arg0: dateTime, arg1: int (limit), arg2: boolean (useGMTTime) |
appointmentArchiveTransfer[] |
Archived appointments |
Appointment Mutation¶
| Operation | Parameters | Returns | Notes |
|---|---|---|---|
addAppointment |
arg0: appointmentTransfer |
int (appointmentId) |
Create new appointment |
updateAppointment |
arg0: appointmentTransfer |
(void) | Update existing appointment |
appointmentTransfer is a wrapped object
Both addAppointment and updateAppointment take arg0: appointmentTransfer as a wrapped object, not flat fields. The WSDL defines this as a complexType. Our adapter wraps all fields inside the appointmentTransfer element.
Schedule Configuration¶
| Operation | Parameters | Returns | Notes |
|---|---|---|---|
getScheduleTemplateCodes |
(none) | scheduleTemplateCodeTransfer[] |
Slot type definitions |
getDayWorkSchedule |
arg0: string (providerNo), arg1: dateTime (date) |
dayWorkScheduleTransfer |
Provider's day schedule |
getAppointmentTypes |
(none) | appointmentTypeTransfer[] |
All appointment types |
getAllDemographicIdByProgramProvider |
arg0: int (programId), arg1: string (providerNo) |
int[] |
Patient IDs for program/provider |
getDayWorkSchedule Returns Schedule Codes, Not Times
getDayWorkSchedule returns {date, scheduleCode} — NOT {startTime, endTime}. The scheduleCode is an integer code point (JAXB Calendar), not a character. Use String.fromCharCode() to decode. See OSCAR Schedule Deep Dive for the full decoding algorithm.
appointmentTransfer Fields¶
id, demographicNo, programId, providerNo,
appointmentStartDateTime, appointmentEndDateTime,
name, type, status, location, reason, remarks, notes,
resources, billing, urgency, style, bookingSource,
createDateTime, creator, updateDateTime, lastUpdateUser
scheduleTemplateCodeTransfer Fields¶
Non-Bookable Schedule Codes¶
The following schedule codes should be filtered when computing available slots:
| Code | Char | Meaning |
|---|---|---|
| 76 | L | Lunch |
| 80 | P | Personal |
| 86 | V | Vacation |
| 65 | A | Administrative |
| 97 | a | Admin (lowercase) |
| 66 | B | Break |
| 72 | H | Holiday |
| 82 | R | Reserved |
| 69 | E | Emergency |
| 71 | G | Government |
| 77 | M | Meeting |
| 109 | m | Meeting (lowercase) |
| 100 | d | Do Not Book |
| 116 | t | Travel |
AllergyService¶
Patient allergy records.
Java class: org.oscarehr.ws.AllergyWs
WSDL: /oscar/ws/AllergyService?wsdl
Operations¶
| Operation | Parameters | Returns |
|---|---|---|
getAllergy |
arg0: int (allergyId) |
allergyTransfer |
getAllergiesByDemographicIdAfter |
lastUpdate: dateTime, demographicId: int |
allergyTransfer[] |
getAllergiesUpdatedAfterDate |
arg0: dateTime, arg1: int (limit) |
allergyTransfer[] |
getAllergiesByProgramProviderDemographicDate |
arg0: int (programId), arg1: string (providerNo), arg2: int (demographicId), arg3: dateTime, arg4: int (limit) |
allergyTransfer[] |
allergyTransfer Fields¶
id, demographicNo, description, reaction, severityOfReaction,
onsetOfReaction, ageOfOnset, startDate, entryDate, lastUpdateDate,
providerNo, typeCode, lifeStage, regionalIdentifier,
agccs, agcsp, hicSeqno, hiclSeqno
PrescriptionService¶
Prescription and drug records.
Java class: org.oscarehr.ws.PrescriptionWs
WSDL: /oscar/ws/PrescriptionService?wsdl
Operations¶
| Operation | Parameters | Returns |
|---|---|---|
getPrescription |
arg0: int (prescriptionId) |
prescriptionTransfer |
getPrescriptionsByDemographicIdAfter |
lastUpdate: dateTime, demographicId: int |
prescriptionTransfer[] |
getPrescriptionUpdatedAfterDate |
arg0: dateTime, arg1: int (limit) |
prescriptionTransfer[] |
getPrescriptionsByProgramProviderDemographicDate |
arg0: int, arg1: string, arg2: int, arg3: dateTime, arg4: int |
prescriptionTransfer[] |
prescriptionTransfer Fields¶
id, demographicId, providerNo, datePrescribed, datePrinted,
datesReprinted, textView, comments, lastUpdateDate,
drugs (array of drugTransfer)
drugTransfer Fields (55 fields)¶
id, gcnSeqNo, archived, archivedDate, archivedReason,
customName, customInstructions, dosage, drugForm, quantity,
unit, method, route, duration, durUnit, frequency,
dispenseInterval, refillQuantity, refillDuration, repeat,
prn, noSubs, startDateUnknown, endDate, rxDate, writtenDate,
pickupDateTime, lastRefillDate, lastUpdateDate, comments,
createDate, rxStatus, scriptNo, special, protocol,
priorRxProtocol, patientCompliance, nonAuthoritative,
outsideProviderName, outsideProviderOhip, longTerm, pastMed,
hideFromDrugProfile, hideFromCpp, takeMin, takeMax, position,
regionalIdentifier, genericName, brandName, atc,
eTreatmentType, customNote, special_instruction
MeasurementService¶
Vital signs and clinical measurements.
Java class: org.oscarehr.ws.MeasurementWs
WSDL: /oscar/ws/MeasurementService?wsdl
Operations¶
| Operation | Parameters | Returns | Notes |
|---|---|---|---|
getMeasurement |
arg0: int (measurementId) |
measurementTransfer |
Single lookup |
getMeasurementsByDemographicIdAfter |
lastUpdate: dateTime, demographicId: int |
measurementTransfer[] |
Patient sync |
getMeasurementsCreatedAfterDate |
arg0: dateTime, arg1: int (limit) |
measurementTransfer[] |
Global sync |
getMeasurementsByProgramProviderDemographicDate |
arg0: int, arg1: string, arg2: int, arg3: dateTime, arg4: int |
measurementTransfer[] |
Filtered query |
getMeasurementMaps |
(none) | measurementMapTransfer[] |
Measurement type definitions |
addMeasurement |
arg0: measurementTransfer |
int (measurementId) |
Create new measurement |
measurementTransfer Fields¶
id, demographicId, providerNo, type, dataField,
dateObserved, createDate, comments, measuringInstruction, appointmentNo
measurementMapTransfer Fields¶
DocumentService¶
Clinical documents and file attachments.
Java class: org.oscarehr.ws.DocumentWs
WSDL: /oscar/ws/DocumentService?wsdl
Operations¶
| Operation | Parameters | Returns |
|---|---|---|
getDocument |
arg0: int (documentNo) |
documentTransfer |
getDocumentsByDemographicIdAfter |
lastUpdate: dateTime, demographicId: int |
documentTransfer[] |
getDocumentsUpdateAfterDate |
arg0: dateTime, arg1: int (limit) |
documentTransfer[] |
getDocumentsByProgramProviderDemographicDate |
arg0: int, arg1: string, arg2: int, arg3: dateTime, arg4: int |
documentTransfer[] |
getProvidersThatHaveAcknowledgedDocument |
arg0: int (documentId) |
providerTransfer[] |
documentTransfer Fields¶
documentNo, doccreator, docdesc, doctype, docClass, docSubClass,
docfilename, contenttype, numberofpages, observationdate,
responsible, reviewer, reviewdatetime, ctlModule, ctlModuleId,
ctlStatus, source, sourceFacility, public1, status,
updatedatetime, programId, appointmentNo, docxml,
fileContents (base64Binary)
PreventionService¶
Preventive care / immunization records.
Java class: org.oscarehr.ws.PreventionWs
WSDL: /oscar/ws/PreventionService?wsdl
Operations¶
| Operation | Parameters | Returns |
|---|---|---|
getPrevention |
arg0: int (preventionId) |
preventionTransfer |
getPreventionsByDemographicIdAfter |
lastUpdate: dateTime, demographicId: int |
preventionTransfer[] |
getPreventionsUpdatedAfterDate |
arg0: dateTime, arg1: int (limit) |
preventionTransfer[] |
getPreventionsByProgramProviderDemographicDate |
arg0: int, arg1: string, arg2: int, arg3: dateTime, arg4: int |
preventionTransfer[] |
preventionTransfer Fields¶
id, demographicId, preventionType, preventionDate, nextDate,
never, refused, deleted, creatorProviderNo, creationDate,
lastUpdateDate, providerNo,
preventionExts (array of preventionExtTransfer: id, key, value, preventionId)
BookingService¶
External / patient-facing appointment booking.
Java class: org.oscarehr.ws.BookingWs
WSDL: /oscar/ws/BookingService?wsdl
VitaraVox uses ScheduleService, not BookingService
Our OscarSoapAdapter uses ScheduleService (addAppointment, updateAppointment, getDayWorkSchedule) for direct appointment manipulation rather than BookingService's encrypted-slot workflow. BookingService is designed for patient-facing web portals with an additional encryption layer.
Operations¶
| Operation | Parameters | Returns | Notes |
|---|---|---|---|
getAppointmentTypesByProvider |
arg0: string (providerNo) |
bookingType[] |
Available booking types for a provider |
getExternalAppointmentTypes |
arg0: int (demographicNo) |
bookingType[] |
Patient-visible booking types |
findAppointment |
arg0: int (demographicNo), arg1: string (appointmentType), arg2: dateTime (startDate) |
appointmentResults |
Search available slots |
bookAppointment |
arg0: string (encryptedTimeSlot), arg1: string (notes) |
appointmentConfirmationTransfer |
Book a slot |
appointmentConfirmationTransfer Fields¶
appointmentTime, appointmentEndTime, appointmentDescription,
location, providerName,
bookingError (code, description)
ProgramService¶
Clinical programs and provider assignments.
Java class: org.oscarehr.ws.ProgramWs
WSDL: /oscar/ws/ProgramService?wsdl
Operations¶
| Operation | Parameters | Returns |
|---|---|---|
getAllPrograms |
(none) | programTransfer[] |
getAllProgramProviders |
(none) | programProviderTransfer[] |
programTransfer Fields¶
id, facilityId, name, type, description, programStatus,
email, phone, fax, address, location, ageMin, ageMax,
mentalHealth, physicalHealth, firstNation, housing, alcohol,
hic, transgender, enableEncounterTime,
enableEncounterTransportationTime, allowBatchAdmission,
allowBatchDischarge, siteSpecificField, userDefined, url, queueSize
programProviderTransfer Fields¶
FacilityService¶
Clinic/facility configuration.
Java class: org.oscarehr.ws.FacilityWs
WSDL: /oscar/ws/FacilityService?wsdl
Operations¶
| Operation | Parameters | Returns | Notes |
|---|---|---|---|
getDefaultFacility |
(none) | facilityTransfer |
Primary facility |
getDefaultFacilities |
(none) | facilityTransfer |
Deprecated (typo in name) |
getAllFacilities |
arg0: Boolean (active) |
facilityTransfer[] |
All facilities |
facilityTransfer Fields¶
id, name, description, contactName, contactPhone, contactEmail,
address, location, disabled, lastUpdated, hic,
allowSims, enableDigitalSignatures, enableHealthNumberRegistry,
enableIntegratedReferrals, enableOcanForms, enableEncounterTime,
enableEncounterTransportationTime, enableGroupNotes, enableAnonymous,
integratorEnabled, integratorUrl, integratorUser, integratorPassword,
sectorId, ocanServiceOrgNumber, orgId, facilityId,
rxInteractionWarningLevel
LabUploadService¶
Laboratory result file uploads. Supports multiple Canadian lab formats.
Java class: org.oscarehr.ws.LabUploadWs
WSDL: /oscar/ws/LabUploadService?wsdl
Text Upload Operations¶
All text-based upload operations share the same signature:
| Operation | Lab System | Format |
|---|---|---|
uploadCML |
CML Labs | HL7 text |
uploadLifelabs |
LifeLabs (MDS) | HL7 text |
uploadExcelleris |
Excelleris (PATHL7) | HL7 text |
uploadIHA |
Interior Health Authority | HL7 text |
uploadGammaDynacare |
Gamma-Dynacare (GDML) | HL7 text |
uploadCDL |
CDL Labs | HL7 text |
uploadCLS |
CLS Labs | HL7 text |
Text upload parameters:
| Parameter | Type | Description |
|---|---|---|
file_name |
string |
Original filename |
contents |
string |
HL7 message content |
oscar_provider_no |
string |
Receiving provider number |
Binary Upload Operations¶
| Operation | Description | Content Type |
|---|---|---|
uploadPDF |
PDF lab report | base64Binary |
uploadDocumentReference |
Generic document | base64Binary |
Returns: string — JSON response with success/failure status.
LoginService¶
Authentication and token exchange. This is the only service (along with SystemInfoService) that does not require WS-Security headers.
Java class: org.oscarehr.ws.LoginWs
WSDL: /oscar/ws/LoginService?wsdl
Operations¶
| Operation | Parameters | Returns | Notes |
|---|---|---|---|
login |
arg0: string (userName), arg1: string (password) |
loginResultTransfer |
Deprecated (2015-01-28) |
login2 |
arg0: string (userName), arg1: string (password) |
loginResultTransfer2 |
Preferred — includes provider info |
Fault: Throws NotAuthorisedException on invalid credentials.
loginResultTransfer Fields¶
loginResultTransfer2 Fields¶
SystemInfoService¶
Health checks and server metadata. Does not require WS-Security authentication.
Java class: org.oscarehr.ws.SystemInfoWs
WSDL: /oscar/ws/SystemInfoService?wsdl
Operations¶
| Operation | Parameters | Returns | Description |
|---|---|---|---|
helloWorld |
(none) | string |
Basic connectivity test |
isAlive |
(none) | string |
Health check |
getServerTime |
(none) | dateTime |
Current server timestamp |
getServerTimeGmtOffset |
(none) | int |
Server timezone offset (hours) |
getMaxListReturnSize |
(none) | int |
Maximum items per list response |
CXF Configuration Reference¶
The SOAP stack is configured in spring_ws.xml:
Endpoint Wiring¶
<!-- No auth required -->
<jaxws:endpoint implementor="#systemInfoWs" address="/SystemInfoService"/>
<jaxws:endpoint implementor="#loginWs" address="/LoginService"/>
<!-- Auth required (WSS4J interceptor) -->
<jaxws:endpoint implementor="#demographicWs" address="/DemographicService">
<jaxws:inInterceptors>
<ref bean="authenticationInWSS4JInterceptor"/>
</jaxws:inInterceptors>
</jaxws:endpoint>
<!-- ... same pattern for all other authenticated endpoints -->
WSS4J Interceptor Configuration¶
// AuthenticationInWSS4JInterceptor.java
properties.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
Global Bus Properties¶
<cxf:bus>
<cxf:properties>
<entry key="ws-security.ut.validator"
value="org.oscarehr.ws.OscarUsernameTokenValidator"/>
</cxf:properties>
</cxf:bus>
REST Bridge SOAP Mapping¶
The OSCAR REST Bridge translates REST/JSON calls into these SOAP operations. It uses the node-soap library with WS-Security.
Bridge Client Configuration¶
// soap-client.js — WS-Security setup
const wsSecurity = new soap.WSSecurity(
config.oscar.username, // OSCAR_WS_USERNAME (Security ID)
config.oscar.password, // OSCAR_WS_PASSWORD (password or token)
{
passwordType: 'PasswordText',
hasTimeStamp: false,
hasNonce: false
}
);
Bridge Environment Variables¶
| Variable | Description |
|---|---|
OSCAR_SOAP_BASE_URL |
Base URL (e.g., http://oscar:8080/oscar/ws) |
OSCAR_WS_USERNAME |
Security ID (numeric) |
OSCAR_WS_PASSWORD |
Password or security token |
REQUEST_TIMEOUT |
SOAP call timeout in ms (default: 30000) |
WSDL_CACHE_TTL |
WSDL cache lifetime in ms (default: 300000 / 5 min) |
Bridge Method to SOAP Mapping¶
| Bridge Method | SOAP Operation | Service |
|---|---|---|
getDemographic(id) |
getDemographic(arg0: id) |
DemographicService |
searchDemographicByName(name) |
searchDemographicByName(arg0, arg1, arg2) |
DemographicService |
getAllDemographics() |
getActiveDemographicsAfter2(lastUpdate: '2000-01-01T00:00:00') |
DemographicService |
getProviders() |
getProviders2() |
ProviderService |
getAppointments(provider, start, end) |
getAppointmentsForDateRangeAndProvider2(...) |
ScheduleService |
addAppointment(data) |
addAppointment(arg0: data) |
ScheduleService |
updateAppointment(data) |
updateAppointment(arg0: data) |
ScheduleService |
cancelAppointment(id) |
updateAppointment(arg0: {id, status:'C'}) |
ScheduleService |
getDayWorkSchedule(provider, date) |
getDayWorkSchedule(arg0, arg1) |
ScheduleService |
getAllergies(demographicId) |
getAllergiesByProgramProviderDemographicDate(...) |
AllergyService |
getPrescriptions(demographicId) |
getPrescriptionsByProgramProviderDemographicDate(...) |
PrescriptionService |
getMeasurements(demographicId) |
getMeasurementsByProgramProviderDemographicDate(...) |
MeasurementService |
addMeasurement(data) |
addMeasurement(arg0: data) |
MeasurementService |
Error Handling¶
Common SOAP Faults¶
| Fault | Cause | Resolution |
|---|---|---|
WSSecurityException: FAILED_AUTHENTICATION |
Invalid Security ID or password/token | Verify credentials via LoginService |
NotAuthorisedException |
Invalid username/password on LoginService | Check credentials |
Method not found in WSDL |
Calling non-existent operation | Verify method name against WSDL |
ECONNREFUSED |
OSCAR Tomcat not running | Check container status |
ETIMEDOUT |
Request exceeded timeout | Increase timeout or reduce query scope |
SecurityError with <wsu:Timestamp> |
WS-Security includes timestamp | Set hasTimeStamp: false — CXF has no Timestamp action configured |
Bridge Retry Logic¶
The REST bridge implements automatic retry with exponential backoff:
- Max retries: 3 attempts
- Backoff: 1s → 2s → 4s
- Reconnect trigger:
ECONNREFUSEDorETIMEDOUTerrors force a fresh SOAP client connection - WSDL cache: 5-minute TTL; stale connections are automatically refreshed
OscarSoapAdapter Circuit Breaker¶
Our production SOAP adapter uses a 4-second circuit breaker timeout (under Vapi's 5-second tool timeout):
- Timeout: 4000ms per SOAP call
- Cold start: First call after PM2 restart fetches WSDL (may be slower)
- Warmup: SOAP clients should be warmed on server startup to avoid cold-start penalties
VitaraVox Services Used¶
Not all 14 OSCAR SOAP services are used by VitaraVox. Here's the subset our OscarSoapAdapter actually calls (verified against source code):
| Service | Operations Called | Purpose |
|---|---|---|
| ScheduleService | getDayWorkSchedule, getAppointmentsForDateRangeAndProvider2, addAppointment, updateAppointment, getScheduleTemplateCodes |
Schedule slots, appointment CRUD, template codes |
| DemographicService | getDemographic, searchDemographicByName |
Patient lookup by ID or name |
| ProviderService | getProviders2 |
Provider roster |
Operations NOT Called
The adapter does not call: searchDemographicsByAttributes, getAppointmentsForProvider2, getAppointmentTypes, LoginService.login2, or SystemInfoService.isAlive.
- Authentication: Uses direct WS-Security credentials via
soap.WSSecurity()-- NOT the two-stepLoginService.login2()flow. The adapter receives the Security ID and password/token at construction time. - Health check: The
healthCheck()method verifies WSDL reachability by creating the SOAP client -- it does NOT callSystemInfoService.isAlive. - Patient search: Only uses
searchDemographicByName(not the multi-attribute variant). Phone search falls back to the REST bridge.
Services not currently used: LoginService, SystemInfoService, AllergyService, PrescriptionService, MeasurementService, DocumentService, PreventionService, BookingService, ProgramService, FacilityService, LabUploadService.
Related Documentation¶
- SOAP Integration Evidence — Proof that SOAP APIs are production-proven
- Adapter Implementations — How OscarSoapAdapter wraps these SOAP calls
- OSCAR Data Architecture — Entity relationships and REST API reference
- OSCAR Schedule Deep Dive — Schedule code decoding algorithm
- EMR Abstraction Layer — IEmrAdapter interface design
- OSCAR REST Bridge — Legacy REST bridge (dev/fallback)