Provider Services API
Mappings
Provider Services Mappings
SBC and DCR use separate mapping paths because data moves in opposite directions. SBC maps OneKey data into Salesforce, while DCR maps Salesforce changes into OneKey.
Data Change Request (DCR)
DCR pushes changes out to OneKey, so the Salesforce field is the source and the OneKey field is the target. This direction is the reverse of Provider Bulk Sync.
Everything below is the out-of-the-box mapping that ships with the connector. The mapping is metadata-driven and also includes explicit DataWeave logic for entity selection and field transformations: the field list lives in mapping.json, the in-scope entities live in objects.json, the mandatory-field rules live in schema.json, and the transformation logic lives in mapper.dwl, all under onekey-sys-impl/src/main/resources/mappingTemplates/validation/. To change what is mapped, add code-value translations, or apply per-country rules, see the Extend Connector guide; make those changes in the OneKey System API mapping layer, not in the application flows.
How the Mapping Works
A DCR is submitted as a request that carries an operation (create or update), an entityType (activity or workplace), and an entityData object holding the changed Salesforce entities. The System API resolves the mapping in three stages:
- Physical entity allow-list (
objects.json). Six physical Salesforce entities are accepted out of the box. A request that includes any other entity is rejected with"Your request includes unsupported entities: {0}...".
| Entity Key | Salesforce Entity |
|---|---|
ACCOUNT | Account |
HCP | HealthcareProvider |
HCP_SPECIALTY | HealthcareProviderSpecialty |
CARE_SPECIALTY | CareSpecialty |
ADDRESS | ContactPointAddress |
AFFILIATION | ProviderAffiliation |
Field mapping (
mapping.jsonviamapper.dwl). Each Salesforce field is matched (case-insensitively) to its OneKey target field and internal mapping field.Accountfields resolve to either Individual (HCP) or Workplace (HCO) targets depending on whether the record has aLastName(Individual) or only aName(Workplace).mapper.dwlthen applies field-specific transformations (code-value translations, birth-date splitting, date reformatting) and appendsOPERATIONandENTITY_TYPE.Schema validation (
schema.json). Before the request is sent to OneKey, the mapped payload is validated against a JSON Schema (draft-07). Missing mandatory fields fail with"Missing required fields: {0}...". The mandatory set depends on the operation, the entity type, and the country (see Mandatory Fields).
DCR Entity Type Resolution
A DCR request must carry one of two entity types. The value controls the mapping branch and mandatory-field rules:
activity: required for every HCP-related DCR. The Provider Services API sets this value when the Account is a person account (IsPersonType).workplace: required for every HCO-related DCR.
These are the only values allowed by the DCR schema.json. Use workplace, not workspace; workspace fails schema validation.
Affiliation eligibility is a separate check. An affiliation is submitted only when its AffiliationType is Hard (dcr.activityAffiliationType). DCRs for non-activity (non-Hard) affiliations are not supported by the MDM system; the connector fails them locally with "DCRs for non-activity type affiliations are not supported by the MDM system" without calling OneKey.
In the mapping tables that follow, the Mandatory column shows whether a field is required for an HCP (
activity), an HCO (workplace), or both, and for which operation.
Null and Empty Value Handling
The DCR mapping pipeline uses the DataWeave output directive skipNullOn = "everywhere" (sometimes described as skipNull = "everywhere"). By default, null values are omitted from objects and arrays instead of being serialized into the OneKey request. Selected empty values are also omitted when mapper logic uses isEmpty or converts an unresolved value to null.
Examples:
- If
ContactPointAddress.Streetresolves to null, the request omitsADD_STREET; it doesn't send"ADD_STREET": null. - If
ProfessionalTitlehas no matching code translation,mapper.dwlconverts the unresolved result to null, soIND_HCP_TITLEis omitted. - If a DCR comment is empty after trimming,
setVrSubmitRequestPayload.dwldoesn't addvalidation.requestComment.
skipNullOn doesn't remove every empty string by itself. Empty values are omitted only when the surrounding mapper explicitly tests isEmpty or normalizes the value to null.
If a OneKey contract requires an explicit null or empty value, update the mapping pipeline in this order:
- Confirm that the target OneKey field accepts the explicit value. Sending null where the contract doesn't allow it causes downstream validation failures.
- Update the
outputdirective or field-specific condition inprovider-services-impl/src/main/resources/dwl/dcr/submitSAPIRequest.dwlso the Process API preserves the value sent to the System API. - Update
onekey-sys-impl/src/main/resources/mappingTemplates/validation/mapper.dwlso the field mapping doesn't normalize or drop the value. - Update
onekey-sys-impl/src/main/resources/dwl/vr/setVrSubmitRequestPayload.dwlso the final OneKey payload includes the field. - Test the Process-to-System request and the final System-to-OneKey payload for the affected country, operation, and entity type.
This behavior isn't controlled by a runtime property; changing it requires mapper-script changes at every stage that currently omits the value.
Account Mapping
Account fields map to OneKey Workplace (HCO) or Individual (HCP) targets. The SourceSystemIdentifier is the OneKey entity ID and is mandatory only on update (on create, OneKey generates it).
| Salesforce Field | OneKey Target Field | Mapping Field | Transformation | Mandatory | Transformation with Example |
|---|---|---|---|---|---|
| SourceSystemIdentifier | workplace.workplaceEid | WKP_ONEKEY_ID | Direct | ✅ HCO update | "WFR123" → "WFR123" |
| SourceSystemIdentifier | individual.individualEid | IND_ONEKEY_ID | Direct | ✅ HCP update | "IFR123" → "IFR123" |
| Name | workplace.usualName | WKP_USUAL_NAME | Direct | ✅ HCO always; HCP non-US | "City Hospital" → "City Hospital" |
| FirstName | individual.firstName | IND_FIRST_NAME | Direct | ✅ HCP | "John" → "John" |
| LastName | individual.lastName | IND_LAST_NAME | Direct | ✅ HCP | "Doe" → "Doe" |
| Phone | workplace.telephone | WKP_PHONE_NUMBER | Direct | ❌ | "5551234" → "5551234" |
| Fax | workplace.fax | WKP_TELEPHONE_FAX | Direct | ❌ | "5555678" → "5555678" |
| PersonBirthdate | individual.birthYear | IND_BIRTH_DATE_YEAR | Year extracted from the date | ❌ | "1980-05-01" → "1980" |
| PersonBirthdate | individual.birthDay | IND_BIRTH_DATE_DAY | Month-day extracted (--MM-dd) | ❌ | "1980-05-01" → "--05-01" |
| PersonGender | individual.genderCode | IND_GENDER | Salesforce value → OneKey code, Code "GEN" | ❌ | "Male" → "M", "Female" → "F" |
| PersonMobilePhone | individual.mobilePhone | IND_TELEPHONE_MOBILE | Direct | ❌ | "5559999" → "5559999" |
A dedicated branch in
mapper.dwlsplits onePersonBirthdatevalue into two OneKey fields:IND_BIRTH_DATE_YEARandIND_BIRTH_DATE_DAY.
HealthcareProvider Mapping
HealthcareProvider fields describe the provider's type, class, status, title, and bed count. Several are code-value translated per country.
| Salesforce Field | OneKey Target Field | Mapping Field | Transformation | Mandatory | Transformation with Example |
|---|---|---|---|---|---|
| Status | workplace.statusCode | WKP_STATUS_CODE | Salesforce value → OneKey code, Code "STA"; result cast to Number | ❌ | "Active" → 3 |
| Status | individual.statusCode | IND_HCP_STATUS_CODE | Salesforce value → OneKey code, Code "STA"; result cast to Number | ❌ | "Inactive" → 9 |
| ProviderType | workplace.typeCode | WKP_HCP_TYPE_CODE | Salesforce value → OneKey code, Code "TET" | ❌ | "Private Hospital" → "HPR" |
| ProviderType | individual.typeCode | IND_HCP_TYPE_CODE | Salesforce value → OneKey code, Code "TYP" | ✅ HCP | "Physician" → "M", "Dentist" → "D" |
| ProviderClass | workplace.activityLocationCode | WKP_HCP_LOCATION_CODE | Salesforce value → OneKey code, Code "LEX" | ✅ HCO | "Hospital" → "H", "Laboratory" → "L" |
| ProfessionalTitle | individual.titleCode | IND_HCP_TITLE | Salesforce value → OneKey code, Code "TIT" via referCodesMapping (codeValues file) | ❌ | "Psychologist" → "PS" |
| TotalLicensedBeds | workplace.numberOfBeds | WKP_CU_UNIT_BED_NUMBER | Direct | ❌ | 120 → 120 |
CareSpecialty Mapping
CareSpecialty carries the specialty code, sent as IND_SP_CODE (HCP) or WKP_SP_CODE (HCO). For an HCP create, IND_SP_CODE is mandatory. A configurable per-request specialty limit exists (dataChange.submit.specialty.limit, default 3).
| Salesforce Field | OneKey Target Field | Mapping Field | Transformation | Mandatory | Transformation with Example |
|---|---|---|---|---|---|
| SpecialtyCode | workplace.speciality | WKP_SP_CODE | Direct | ❌ | "UR" → "UR" |
| SpecialtyCode | individual.speciality | IND_SP_CODE | Direct | ✅ HCP create | "VI" → "VI" |
Specialty data for DCR is carried by
CareSpecialty.SpecialtyCode.HealthcareProviderSpecialtyhas no mapped fields. It exists inobjects.jsonso the entity allow-list check passes because the connector reaches CareSpecialty through it.
ContactPointAddress Mapping
Address fields locate the provider. City and CountryCode are always mandatory, because OneKey uses the country to select the region and validate the request.
| Salesforce Field | OneKey Target Field | Mapping Field | Transformation | Mandatory | Transformation with Example |
|---|---|---|---|---|---|
| CountryCode | address.country | ADD_COUNTRY | Direct | ✅ always | "US" → "US" |
| City | address.city | ADD_CITY | Direct | ✅ always | "GREENVILLE" → "GREENVILLE" |
| Street | address.longLabel | ADD_STREET | Direct | ❌ | "Po Box 20128" → "Po Box 20128" |
| PostalCode | address.longPostalCode | ADD_POSTALCODE | Direct | ❌ | "27858 0128" → "27858 0128" |
ProviderAffiliation Mapping
ProviderAffiliation maps to the OneKey activity (the HCP-to-HCO link). No affiliation field is individually mandatory, but only Hard affiliations are eligible for DCR (see DCR Entity Type Resolution).
| Salesforce Field | OneKey Target Field | Mapping Field | Transformation | Mandatory | Transformation with Example |
|---|---|---|---|---|---|
| SourceSystemIdentifier | activity.activityEid | ACT_AFFILIATION_ID | Direct | ❌ | "ACT123" → "ACT123" |
| EffectiveStartDate | activity.startDate | ACT_START_DATE | Reformatted to yyyy-MM-dd'T'00:00:00Z | ❌ | "2026-01-15" → "2026-01-15T00:00:00Z" |
| EffectiveEndDate | activity.endDate | ACT_END_DATE | Reformatted to yyyy-MM-dd'T'00:00:00Z | ❌ | "2026-12-31" → "2026-12-31T00:00:00Z" |
| Role | activity.role | ACT_ROLE | Salesforce value → OneKey code, Code "TIH" via referCodesMapping (codeValues file) | ❌ | "Doctor" → "GMD" |
Request Envelope Fields
Beyond the entity fields, the System API adds the request envelope from setVrSubmitRequestPayload.dwl:
| Request Field | Source | Notes |
|---|---|---|
isoCod2 | request countryCode | Two-character ISO country code. |
entityType | request entityType | activity (HCP) or workplace (HCO). |
validation.clientRequestId | request requestId | The Salesforce DCR record ID. |
validation.requestDate | current time | yyyy-MM-dd'T'HH:mm:ss'Z'. |
validation.requestProcess | request operation | create → "I", update → "U". |
validation.process | config dataChange.submit.process | Defaults to "Q". |
validation.requestComment | request comment | Only set when a comment is present. |
validation.user | request user | Only set when a user value is present on the request. The Provider Services app does not send user for DCR out of the box, so this field is absent by default. |
Mandatory Fields
The System API validates mandatory fields against schema.json before calling OneKey. ADD_CITY and ADD_COUNTRY are always required. The rest depend on operation × entity type × country (US vs. non-US):
| Operation | Entity Type | Country | Additional Mandatory Fields |
|---|---|---|---|
| create | activity | US | IND_FIRST_NAME, IND_LAST_NAME, IND_HCP_TYPE_CODE, IND_SP_CODE |
| create | activity | non-US | above + WKP_USUAL_NAME |
| update | activity | US | IND_FIRST_NAME, IND_LAST_NAME, IND_ONEKEY_ID, IND_HCP_TYPE_CODE |
| update | activity | non-US | above + WKP_USUAL_NAME |
| create | workplace | any | WKP_USUAL_NAME, WKP_HCP_LOCATION_CODE |
| update | workplace | any | WKP_USUAL_NAME, WKP_ONEKEY_ID, WKP_HCP_LOCATION_CODE |
Expressed in Salesforce terms:
| Entity | Mandatory Fields |
|---|---|
| Account | FirstName, LastName (HCP); Name (HCO, and HCP non-US); SourceSystemIdentifier (on update) |
| HealthcareProvider | ProviderType (HCP); ProviderClass (HCO) |
| CareSpecialty | SpecialtyCode (HCP create only) |
| ContactPointAddress | City, CountryCode (always) |
| ProviderAffiliation | nothing mandatory |
Managed Fields
For External DCR to fire correctly, these Salesforce fields must be configured as External Managed Fields in alignment with OneKey. A DCR is only generated when a managed field changes.
| Entity | Fields |
|---|---|
| Account | Fax, Name, PersonBirthdate, PersonGender, PersonMobilePhone, Phone |
| ContactPointAddress | Address, Name |
| HealthcareProvider | Name, ProfessionalTitle, ProviderClass, ProviderType, Status, TotalLicensedBeds |
| HealthcareProviderSpecialty | Name, SpecialtyId |
| ProviderAffiliation | EffectiveEndDate, EffectiveStartDate, Role |
Picklist Values for Testing
To exercise the shipped mapping end-to-end, use Salesforce source values that appear in the base mapping.json and codeValues.json files. Confirm that each value is valid for the customer's country and OneKey contract before testing against OneKey.
| Entity | Field | Salesforce Value | OneKey Value |
|---|---|---|---|
| Account | PersonGender | Male | M |
| Account | PersonGender | Female | F |
| HealthcareProvider (Individual) | ProviderType | Physician | M |
| HealthcareProvider (Individual) | ProviderType | Administrators | A |
| HealthcareProvider (Individual) | ProviderType | Dentist | D |
| HealthcareProvider (Individual) | ProfessionalTitle | Psychologist | PS |
| HealthcareProvider (Individual) | ProfessionalTitle | Veterinarian | VD |
| HealthcareProvider (Individual) | ProfessionalTitle | Pharmacist | RP |
| HealthcareProvider (Workplace) | ProviderType | Private Hospital | HPR |
| HealthcareProvider (Workplace) | ProviderType | Functional Reeducation Center | CRF |
| HealthcareProvider (Workplace) | ProviderType | Prosthesis Laboratory | LPR |
| HealthcareProvider (Workplace) | ProviderClass | Hospital | H |
| HealthcareProvider (Workplace) | ProviderClass | Clinics and Health Care Center | K |
| HealthcareProvider (Workplace) | ProviderClass | Laboratory | L |
| ProviderAffiliation | Role | Doctor | GMD |
| ProviderAffiliation | Role | Pharmacist | PHC |
| ProviderAffiliation | Role | Administrator | ADR |
CareSpecialty.SpecialtyCode is passed through directly rather than translated by the shipped mapping. Use a specialty code supported by the customer's OneKey contract.
Search Before Create (SBC)
SBC maps in the opposite direction: OneKey Individual, Workplace, and Activity data into the Life Sciences Cloud data model. It reuses the transformation approach used by Provider Bulk Sync.
For SBC request and response schemas, examples, errors, and field constraints, see the Provider Services API specification. For mapping changes, see Extend Connector.
To locate and extend the SBC mappings:
- Use
mappingTemplates/searchin the OneKey System API for fields returned by provider search. This controls the synchronous search result shape. - Use
mappingTemplates/downloadfor the selected provider and related records written to Salesforce. This controls the data imported after selection. - Keep SBC changes separate from
mappingTemplates/validation, which is used only by DCR. This prevents an inbound mapping change from affecting outbound validation requests. - Review the full OneKey-to-Salesforce field tables before changing either mapping path.
For the full OneKey → Salesforce field tables (Individual, Workplace, and Activity, including transformations, filters, and code-value translations), see the Data Mappings page in the OneKey System API documentation. The Provider Bulk Sync connector shares the same download mapping layer.