One of OSCAR EMR’s biggest practical advantages is that it does not have to stand alone. Clinics can connect OSCAR to other tools — online booking, automated reminders, payments, virtual visits — so the EMR becomes the centre of a connected clinic rather than an island. This guide explains, in plain terms, how OSCAR EMR integration works, what the OSCAR API enables, and what to look for when connecting third-party tools.
It is written for clinic owners, managers, and decision-makers — not developers. You do not need to be technical to make a good integration decision.
Why Integration Matters for a Clinic
An EMR on its own is a clinical record. But a modern clinic also needs patients to book online, receive reminders, complete intake forms before they arrive, attend virtual visits, and pay invoices. If those tools cannot talk to the EMR, your staff become the integration — manually copying appointments, re-keying patient data, and reconciling systems by hand.
Integration removes that manual middle layer. When a booking tool is integrated with OSCAR, an online booking becomes an OSCAR appointment automatically. When an intake tool is integrated, the patient’s answers land in their OSCAR chart. The payoff is fewer errors, less double entry, and staff time given back. If you are weighing systems generally, our guide on top EMR software integration tips is a useful companion.
What the OSCAR API Enables
An API (application programming interface) is the defined way one software system lets another system read or write its data — securely and in a structured format. The OSCAR codebase includes a REST/web-services layer (served under a /ws/ path) covering most of the clinical record — scheduling, demographics, billing, prescriptions, documents, ticklers, labs, eForms and more. Once an external application is registered and authorized on a clinic’s OSCAR instance, it can do things like read schedules and appointment availability, create or update appointments, read or write patient demographic information, and push documents into a chart — programmatically, without a human re-typing anything.
Access is not open by default. In OSCAR’s open-source code, an administrator registers each API client inside OSCAR itself — issuing it a client key, a secret, and a token lifetime — and the API uses OAuth authorization, so a client only gets the access a clinic has explicitly granted. The exact API surface, the authorization steps, and whether a clinic can self-enable it all depend on your OSCAR variant, version, and service provider — on a hosted variant, enabling API access is typically something your provider does, not something you switch on yourself.
The section below walks through a concrete example so you can see what your IT contact or integration vendor will actually be doing — and so you know what to confirm with your provider first.
Two things make OSCAR relatively integration-friendly:
- It is open-source. Because the OSCAR codebase is open, the integration surface is more transparent than a fully closed, proprietary EMR. New to that idea? See what OSCAR EMR is.
- There is an established integration ecosystem. OSCAR has been integrated with third-party tools for years, so the patterns are well understood.
That said, “OSCAR” is several variants — OscarPro, Juno, Avaros, OpenOSP — and the exact API access, terms, and process differ between them. Practically, the variant and service provider your clinic uses determines what integration is available and how you enable it.
A Worked Example: The Typical OSCAR API Flow
To make the above concrete, here is the end-to-end flow an integration follows on the OSCAR core — register a client, complete the authorization handshake, then read and write a patient record. The details below are grounded in the open-source OSCAR codebase (the OpenOSP / Open-O distribution). They illustrate the shape of the work; treat them as a reference to hand to your IT contact, not as a guarantee — see the variant caveat at the end.
This is technical by necessity. If you are a non-technical reader, the takeaway is simply that this is a well-defined, three-stage process — connect, read, write — and the rest of this section is for whoever does your integration.
Step 1 — Connect: register an API client and get a token
API access starts inside OSCAR’s own admin area, on the Manage REST Clients (OAuth) screen (under Administration, in the API section). An administrator clicks Add New and fills in three fields:
- Name — a label for the integration.
- URI — the client’s address (used as the OAuth callback / redirect target).
- Token Lifetime (seconds) — how long an issued access token stays valid.
Saving the client produces a Client Key and Client Secret — the credentials the external application uses to identify itself.
OSCAR uses 3-legged OAuth 1.0a. With the key and secret in hand, the application completes a three-call handshake against the web-services layer (the same screen displays these three URLs):
- Request a temporary token —
POST /ws/oauth/initiate, signed with the client key and secret. - Send the clinic user to authorize — the user opens
GET /ws/oauth/authorize?oauth_token=...in a browser, sees a consent screen, and approves the access. OSCAR then issues a verifier. - Exchange for an access token —
POST /ws/oauth/token, presenting the temporary token and verifier, returns the long-lived access token (valid for the token lifetime set when the client was registered).
From here on, every API request is signed with the client credentials plus this access token. The token represents access a specific clinic user has explicitly granted — not blanket access.
Step 2 — Read: load a demographic
In OSCAR, a patient record is a demographic. The web-services layer exposes it under a REST path; in the open-source code the demographic service lives at /ws/services/demographics.
To load one patient, the application makes an authenticated GET request to that path with the patient’s demographic number:
GET /ws/services/demographics/{demographicNo}
Authorization: OAuth oauth_consumer_key="...", oauth_token="...", oauth_signature="..."
Accept: application/json
The response is a JSON demographic record. Its fields include demographicNo, firstName, lastName, dateOfBirth (with separate dobYear / dobMonth / dobDay values), sex, hin (the health-insurance number), phone, email, an address block (address, city, province, postal), providerNo (the patient’s assigned provider), and patientStatus. The same service also offers a lighter /ws/services/demographics/{demographicNo}/basic variant and a /ws/services/demographics/quickSearch?query=... lookup for finding a patient before you have their number.
Step 3 — Write: create or update a demographic
Writing back uses the same path with a different HTTP method and a JSON body:
- Create a new patient —
POST /ws/services/demographicswith a JSON demographic in the request body. OSCAR returns the saved record, now carrying its newdemographicNo. - Update an existing patient —
PUT /ws/services/demographicswith a JSON demographic whosedemographicNoidentifies the record to change.
POST /ws/services/demographics
Authorization: OAuth oauth_consumer_key="...", oauth_token="...", oauth_signature="..."
Content-Type: application/json
{
"firstName": "Jordan",
"lastName": "Lee",
"dobYear": "1985", "dobMonth": "04", "dobDay": "12",
"sex": "M",
"hin": "...",
"phone": "...",
"email": "[email protected]",
"address": { "address": "...", "city": "...", "province": "ON", "postal": "..." },
"providerNo": "..."
}
That is the whole loop: an integration connects once (Steps 1), then reads and writes patient data (Steps 2–3) as the clinic works. The exact set of fields a record requires, and which are validated, vary by OSCAR version — your integrator confirms the required schema against the specific instance.
The same pattern across the rest of the API
The demographic example generalises. The web-services layer is a family of REST services that all follow the same shape — an authenticated request to a path under /ws/services/, returning or accepting JSON. Alongside demographics, the open-source code includes services for scheduling and appointments (/ws/services/schedule), prescriptions (/ws/services/rx), documents (/ws/services/document), lab results (/ws/services/labs), ticklers/reminders (/ws/services/tickler), eForms (/ws/services/forms), consultations, providers, and more. Once your integrator has the OAuth handshake working and the credentials in place, moving from reading a patient to reading a schedule or pushing a document is the same request pattern against a different path.
A necessary caveat on all of the above: these paths, methods, and field names come from one open-source distribution of OSCAR. The exact API surface, the endpoint paths, which services are enabled, and the authorization steps vary by OSCAR variant, version, and service provider. Before scoping any integration, confirm the actual API details — and whether API access is enabled at all — with whoever hosts and supports your OSCAR.
A Worked Example: The OSCAR SOAP API
Alongside the REST/JSON layer above, the same OSCAR core also exposes a long-standing SOAP API. It predates the REST surface, still ships in the open-source code, and is the only way to reach a handful of operations (notably the lab-upload service). If you are an integrator, knowing both is useful: REST is the path of least resistance for most clinical reads/writes, and SOAP is what you fall back to when a feature only lives there or when the receiving system is itself SOAP-native.
The details below are again grounded in the OpenOSP / Open-O distribution. The variant caveat from the previous section applies in full — which SOAP services are mounted, whether they are enabled at all, and what authentication is accepted will differ across OSCAR variants and hosting providers.
Where the SOAP API lives
OSCAR mounts SOAP via Apache CXF. In the web application’s web.xml, the CXF servlet is bound to /ws/* (and /ops/*):
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
The Spring/CXF config (spring_ws.xml) then registers each SOAP service under a stable address. So every SOAP endpoint follows the same pattern:
https://{your-oscar-host}/{context}/ws/{ServiceName}
For example, the demographic SOAP endpoint is …/ws/DemographicService, and its WSDL is at …/ws/DemographicService?wsdl — the standard CXF convention. All services share the namespace http://ws.oscarehr.org/.
A second filter, WebServiceSessionInvalidatingFilter, is mapped to /ws/*. Practically, this means each SOAP call is treated as a stateless API call and the HTTP session is not held open — every request must carry its own credentials.
Step 1 — Connect: authenticate with a WS-Security UsernameToken
OSCAR’s SOAP services do not use OAuth. They use WS-Security UsernameToken authentication, configured in spring_ws.xml via a CXF AuthenticationInWSS4JInterceptor attached to each protected endpoint. The interceptor runs WSS4J in UsernameToken mode with PasswordText (plaintext password inside the SOAP header — so the transport must be HTTPS).
Two endpoints are deliberately unauthenticated: SystemInfoService (health check / server time) and LoginService (used to obtain credentials). Everything else — DemographicService, ScheduleService, DocumentService, LabUploadService, and the rest — requires the WSS header.
There is one OSCAR-specific quirk in the validator (OscarUsernameTokenValidator): the WS-Security Username field is not the textual login name, it is the numeric security_no from OSCAR’s security table. The password is either the user’s password or a short-lived security token issued by LoginService. To convert a human username into a security_no (and optionally a token), call LoginService.login2 first:
POST /ws/LoginService
Content-Type: text/xml; charset=UTF-8
SOAPAction: ""
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ws="http://ws.oscarehr.org/">
<soapenv:Body>
<ws:login2>
<userName>integration_user</userName>
<password>...</password>
</ws:login2>
</soapenv:Body>
</soapenv:Envelope>
The response carries a securityId (the numeric ID you will use as the WSS Username) and a securityTokenKey (a token you may use in place of the password on subsequent calls).
Every subsequent SOAP call to a protected service then includes a WS-Security header of this shape:
<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>1234</wsse:Username> <!-- security_no -->
<wsse:Password Type="...#PasswordText">SECRET_OR_TOKEN</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
Successful authentication is recorded in OSCAR’s audit log as WS_LOGIN_SUCCESS; failures are logged as WS_LOGIN_FAILURE with the caller’s IP.
Step 2 — Read: load a demographic over SOAP
DemographicService is the SOAP counterpart to the REST demographic resource. Its operations live in DemographicWs.java (ca.openosp.openo.webserv). To fetch one patient by ID, call getDemographic (or the newer getDemographic2, which uses the DemographicTransfer2 shape):
POST /ws/DemographicService
Content-Type: text/xml; charset=UTF-8
SOAPAction: ""
<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>1234</wsse:Username>
<wsse:Password Type="...#PasswordText">SECRET_OR_TOKEN</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ws:getDemographic>
<arg0>10001</arg0> <!-- demographicId -->
</ws:getDemographic>
</soapenv:Body>
</soapenv:Envelope>
The response body wraps a DemographicTransfer — the same conceptual record as the REST demographic resource (first/last name, date of birth, sex, HIN, phone, email, address block, assigned provider, patient status), just rendered as XML instead of JSON. Other useful read operations on the same service include:
searchDemographicByName(searchString, startIndex, itemsToReturn)— name-prefix lookup with paging.searchDemographicsByAttributes(hin, firstName, lastName, gender, dateOfBirth, …)— broader patient search.getActiveDemographicsAfter(lastUpdate, fields)andgetActiveDemographicsAfter2(...)— delta sync of recently updated records, with optional field filtering.getDemographics(demographicIds)— bulk fetch by ID list.getConsentedDemographicIdsAfter(lastUpdate)— IDs whose patient-consent record changed after a timestamp (useful for syncing only patients who have granted consent).
The pattern stays the same across services: same endpoint shape, same WSS header, different operation name and arguments. Any modern SOAP/WSDL client (Java CXF, .NET WCF, Python zeep, soapUI) can generate the bindings from the live ?wsdl.
Other SOAP services worth knowing
The open-source SOAP surface is broader than the demographic example. From spring_ws.xml and the *Ws.java classes in ca.openosp.openo.webserv, the services mounted under /ws/ are:
SystemInfoService(no auth) —helloWorld,isAlive,getServerTime,getServerTimeGmtOffset,getMaxListReturnSize. Useful as a connectivity / version probe.LoginService(no auth) —login,login2. Exchanges a textual username + password for asecurityIdand security token (see Step 1).ScheduleService—getAppointment2,getAppointmentsForProvider2,getAppointmentsForPatient2,getAppointmentsForDateRangeAndProvider2,getDayWorkSchedule,getAppointmentTypes,addAppointment,updateAppointment,getAppointmentsUpdatedAfterDate,getAppointmentArchivesUpdatedAfterDate,getAppointmentsByDemographicIdAfter. The*2operations take an explicituseGMTTimeflag — prefer them; the originals are marked@Deprecated.BookingService—getAppointmentTypesByProvider,getExternalAppointmentTypes,findAppointment(returns offered slots for a patient + appointment type),bookAppointment(books an offered slot using an encrypted slot reference). This is the service designed for external booking widgets.ProviderService—getLoggedInProviderTransfer,getProviders(active),getProviders2(Boolean active),getProviderProperties(providerNo, propertyName).FacilityService—getDefaultFacility,getDefaultFacilities,getAllFacilities(active).ProgramService—getAllPrograms,getAllProgramProviders(community/program-level lookups used by the program module).AllergyService—getAllergy,getAllergiesUpdatedAfterDate,getAllergiesByDemographicIdAfter,getAllergiesByProgramProviderDemographicDate.PreventionService— same four-shape pattern as Allergy, for prevention records (immunizations, screening events).MeasurementService—getMeasurement,addMeasurement,getMeasurementsCreatedAfterDate,getMeasurementsByDemographicIdAfter,getMeasurementMaps.PrescriptionService—getPrescription,getPrescriptionUpdatedAfterDate,getPrescriptionsByDemographicIdAfter,getPrescriptionsByProgramProviderDemographicDate.DocumentService—getDocument,getDocumentsUpdateAfterDate,getDocumentsByDemographicIdAfter,getDocumentsByProgramProviderDemographicDate. Patient-attached document metadata; the document binary is fetched separately.LabUploadService— lab-result ingestion:uploadCLS,uploadCML,uploadLifelabs,uploadExcelleris,uploadIHA,uploadGammaDynacare,uploadCDL,uploadPDF,uploadDocumentReference. The CXF endpoint for this service is given a five-minute receive timeout because batch uploads of multiple lab results in a single call can be slow.
Many services follow the getXByDemographicIdAfter(lastUpdate, demographicId) pattern — pull what changed for this patient since this timestamp. That is the intended shape for keeping a downstream system in sync without polling everything.
REST vs SOAP — when to use which
Both layers are mounted by the same CXF bus in spring_ws.xml: REST under /ws/rs/... and SOAP under /ws/{ServiceName}. They share the underlying OSCAR data model and managers — DemographicManager, ScheduleManager, DocumentManager, and so on — so for the operations that exist on both sides, the records you read or write are the same records.
From the source, three practical differences shape the choice:
- Authentication model. REST uses 3-legged OAuth 1.0a (per-clinic-user consent) plus a cookie-auth path for in-app calls. SOAP uses WS-Security UsernameToken — simpler to wire up, but tied to a specific OSCAR user account (the
security_no) rather than an explicitly delegated grant. - Coverage. The REST surface is broader for newer features — billing, messaging, ticklers, eForms, consultations, reporting, pharmacy lookups, and several UX-specific services only exist as REST resources. SOAP is broader for some older clinical entities (allergies, preventions, measurements have a clean SOAP delta-sync shape) and is the only path for
LabUploadService— the lab-ingestion entry points are SOAP-only. - Tooling. SOAP comes with a published WSDL contract — generate a strongly-typed client from
…/ws/{ServiceName}?wsdland you get the operation list and types for free. REST is JSON-over-HTTP without a formal schema in the open-source code, so clients tend to be hand-written.
A pragmatic default for a new integration: use REST for anything that exists on both sides (demographics, scheduling, documents, prescriptions), and use SOAP where the source dictates — lab uploads, the booking flow when you are matching the external-booking design, or when you are integrating from a SOAP-native system and a generated client is genuinely faster.
The same variant caveat applies: the services, operations, and auth model described above come from one open-source OSCAR distribution (OpenOSP / Open-O). Other variants — OscarPro, Juno, Avaros, hosted forks — may enable a different subset, change the authentication, or disable the SOAP layer entirely. Confirm with whoever supports your OSCAR before designing against any specific endpoint.
Common OSCAR EMR Integration Patterns
Integrations with OSCAR generally fall into a few recognizable patterns. Knowing them helps you ask vendors the right questions.
- API-based integration. The external tool connects to an OSCAR API to read and write data in real time — the cleanest, most modern pattern. Best for live two-way sync, like online booking that writes straight into the OSCAR scheduler.
- HL7 / health-data-standard messaging. Healthcare has long-standing data-exchange standards used to move things like lab results and clinical messages between systems. OSCAR uses HL7 v2 messaging for these clinical data flows — importing lab results and moving documents and messages between systems. The newer FHIR standard also appears in the OSCAR codebase, but mostly for specific purposes such as provincial public-health and immunization reporting rather than as a general-purpose patient-data API; how much FHIR a clinic can actually use depends on the variant and version.
- Plug-in / browser-extension integration. Some tools integrate at the point of use — a plug-in or browser extension that adds functionality directly on top of the OSCAR screen the user already has open. This is a fast way to extend OSCAR without deep back-end work.
- File-based or batch exchange. Older or simpler integrations may exchange data as scheduled files rather than live API calls. It works, but it is not real-time.
For most patient-facing needs — booking, reminders, intake — real-time, two-way integration is what you want, so a missed appointment or a new booking is reflected everywhere instantly.
Common Third-Party Integrations Clinics Add
In practice, the integrations Canadian OSCAR clinics most often add are:
- Online booking — patients self-schedule into real OSCAR appointment slots.
- Automated appointment reminders — SMS and email reminders triggered from the OSCAR schedule, reducing no-shows.
- Digital patient intake forms — patients complete intake before the visit; answers flow into the chart.
- Telehealth / virtual visits — video appointments linked to the OSCAR workflow.
- Payments — collecting fees and reconciling them against the schedule.
- EMR task automation — automating repetitive chart, inbox, and data-entry work.
Each of these only delivers its full value when it is genuinely integrated with OSCAR — not running as a disconnected parallel system your staff have to reconcile.
What to Ask Before You Integrate
Before committing to any tool that claims to integrate with OSCAR, get clear answers to:
- Which OSCAR variants does it support? Make sure it works with your variant (OscarPro, Juno, Avaros, OpenOSP, or self-hosted) and version.
- Is the sync one-way or two-way? Two-way (read and write) is what most clinic workflows need.
- Is it real-time? A booking that takes hours to appear in OSCAR is a source of double-bookings.
- How is patient data protected? Integration moves health information between systems. Confirm each vendor’s security practices and compliance with Canadian privacy law (such as PIPEDA and your province’s health-information legislation) — and ask for it in writing.
- Who supports the integration? When something breaks, is it the EMR provider, the third-party vendor, or both? Get this in writing.
- What does enabling it involve? Some integrations need cooperation or sign-off from your OSCAR service provider — ask about the process and any cost.
How Cortico Integrates with OSCAR EMR
Cortico is built to be exactly this kind of integration layer for OSCAR clinics. Rather than asking clinics to wrangle APIs themselves, Cortico provides a ready, supported, two-way integration with OSCAR EMR — the patient-engagement platform sits on top of the EMR clinics already use.
In practice that means:
- Online booking for OSCAR — patient self-bookings flow directly into the OSCAR scheduler.
- Telehealth for OSCAR — virtual visits connected to the OSCAR workflow.
- The Oscar Software System integration — the broader connected platform of Cortico capabilities working with OSCAR.
- EMR task automation — automating the repetitive chart and inbox work that integration makes possible.
- A free Cortico EMR plug-in — a no-cost way for OSCAR clinics to start.
The point of integration is to make OSCAR the hub of a connected clinic without your staff doing the connecting by hand. A supported integration partner removes the technical burden — your team gets the result, not the project.
Cortico through the same six questions
The six-question gauntlet above is the right way to vet any OSCAR integration. It would be unfair not to run Cortico through it:
- Which OSCAR variants does it support? OSCAR Pro, Juno, Avaros, OpenOSP, and self-hosted OSCAR — the same OSCAR REST/web-services layer underneath, so the integration shape is the same; what differs is the enablement path with each service provider. The current variant-by-variant compatibility detail lives in the Cortico EMR compatibility guide.
- Is the sync one-way or two-way? Two-way. Bookings, demographics, intake responses, and documents read from and write to OSCAR through the same
/ws/services/REST surface described earlier in this article, plus the SOAP services where they are the only path (notably lab and document uploads). - Is it real-time? Yes — appointments self-booked by patients land on the OSCAR scheduler within seconds, not in a nightly batch. The same applies to intake responses writing back to the chart.
- How is patient data protected? Cortico is SOC 2 Type II and ISO 27001 certified, and meets HIPAA, PIPEDA, and PHIPA. The detail and current attestations are in the Cortico security brief, available in writing on request.
- Who supports the integration? Cortico supports its side; your OSCAR service provider supports the OSCAR side; we coordinate directly with them when an issue spans both. There is a single Cortico support contact for the clinic so staff do not have to triage where a problem lives.
- What does enabling it involve? On hosted variants, your OSCAR service provider has to issue API credentials and turn on the relevant endpoints. For a clinic doing this for the first time, that step typically takes one to two weeks, depending on the provider’s queue, and is usually the gating item on the timeline.
The honest trade-off: adopting Cortico is an additional vendor relationship to manage on top of the EMR, and the first-time enablement depends on your OSCAR provider’s responsiveness. For most clinics that is materially smaller than changing EMRs — but it is worth naming upfront rather than discovering at go-live.
The Bottom Line
OSCAR EMR’s open-source foundation and established integration ecosystem make it one of the more connectable EMRs in Canadian primary care. Its REST/web-services layer covers most of the clinical record and uses OAuth-based authorization, so a clinic can grant scoped access to a trusted partner; the practical integration patterns are well understood; and the integrations clinics most want — booking, reminders, intake, telehealth, payments, automation — are all achievable. The key is choosing integrations that are genuinely two-way, real-time, secure, and supported on your specific OSCAR variant — and confirming with your service provider what API access they will enable.
Book a personalized demo to see how Cortico integrates with your OSCAR EMR.

