Integration
Canonical API integration using Ellucian Ethos as the standard data layer to feed normalized student and academic data into Salesforce Education Data Architecture.
This integration uses Ellucian Ethos as the canonical API layer between one or more underlying student information systems and Salesforce Education Data Architecture (EDA). Rather than building point-to-point connections from each SIS directly to Salesforce, Ethos normalizes student, program, and enrollment data into its open Ed-Fi Compatible Data Model, then publishes change events via its REST API which are mapped and pushed into EDA's Account, Contact, Affiliation, and Program Plan objects.
The complexity lies in reconciling Ethos's generalized data entities (e.g., persons, enrollments) to EDA's highly structured object model with its specific affiliation rules, academic account types, and system-to-system ID linking. Additionally, deduplicating person records, mapping multiple SIS source identifiers to a single EDA contact, and handling partial or late-arriving enrollment data require careful mapping logic and error-handling choreography.
A working piece from this integration — no sign-up. The full build handles the edge cases, safeguards, and cutover.
Canonical field mapping from Ellucian Ethos persons endpoint to Salesforce EDA Contact + Affiliation records:
| Ethos Field (GET /persons/{id}) | EDA Target Object | EDA Target Field | Notes |
|---|---|---|---|
personGuid | Contact | Ethos_GUID__c | External ID key |
names[0].firstName | Contact | FirstName | |
names[0].lastName | Contact | LastName | |
emails[0].emailAddress | Contact | Email | Primary email only |
demographics.birthDate | Contact | Birthdate | |
student.admissions[0].programMemberships[0].accountGuid | Affiliation | Account__c | Look up by Ethos_GUID__c |
student.admissions[0].applicationStatus | Affiliation | Status__c | Map coded values to EDA picklist |
// Ellucian Ethos GET /persons/{guid} // Response → Transform → Salesforce EDA upsert const ethosPerson = { personGuid: "8f1a7c3e-9b2d-4f6a-8e1c-2b4d5f6a7e8c", names: [{ firstName: "Jane", lastName: "Rivera" }], emails: [{ emailAddress: "[email protected]", primary: true }], demographics: { birthDate: "2001-04-15" }, student: { admissions: [{ programMemberships: [{ accountGuid: "a3c5e7f9-1b4d-6a8c-2e4f-8b1d3f5a7e9c", program: "BS Computer Science" }], applicationStatus: "admitted" }] } }; // Map to EDA Contact + Affiliation composite request const sfPayload = { records: [ { attributes: { type: "Contact", referenceId: "refContact" }, Ethos_GUID__c: ethosPerson.personGuid, FirstName: ethosPerson.names[0].firstName, LastName: ethosPerson.names[0].lastName, Email: ethosPerson.emails.find(e => e.primary)?.emailAddress, Birthdate: ethosPerson.demographics.birthDate }, { attributes: { type: "Affiliation__c", referenceId: "refAffiliation" }, Contact__r: { Ethos_GUID__c: ethosPerson.personGuid }, Account__r: { Ethos_GUID__c: ethosPerson.student.admissions[0].programMemberships[0].accountGuid }, Status__c: "Current" } ] }; // POST /services/data/v59.0/composite/tree/ with sfPayload
How we'd take this from discovery to a production-safe cutover — the phases, the canonical mapping, and the edge cases that bite.
This integration connects Ellucian Ethos as the canonical data source to Salesforce Education Cloud's custom data model, synchronizing student records, academic programs, course connections, and enrollment data. The implementation follows a staged approach from discovery through production cutover with rollback capability.
api, refresh_token, and offline_access. Establish middleware (MuleSoft, Boomi, or similar) project with connection endpoints, retry logic (exponential backoff), and webhook/schedule triggers.| Ethos Resource / Field | Salesforce EDA Object | EDA Field / Relationship | Mapping Logic |
|---|---|---|---|
persons.guid |
Contact | Ethos_Person_Id__c (External ID) |
Direct map; used for upsert matching |
students.academicProgram.programGuid |
Affiliation | Account lookup |
Lookup to Program Account via correlation table |
academicRecords.grade |
Academic Record | Grade__c |
Map to EDA grade scale; handle incomplete/missing grades |
enrollments.section.referenceCode |
Course Connection | Course__c lookup |
Match to Course via Course_ID__c or section identifier |
students.enrollmentStatus |
Contact / Affiliation | Status__c |
Map: active→Current, withdrawn→Former; update Affiliation accordingly |
terms.academicTerm.value |
Term | Term_ID__c |
Direct map for upsert; must pre-exist in EDA |
persons.emailAddress |
Contact | Email |
Map to primary email; validate format; flag non-institutional |
admissions.applicationStatus |
Application (EDA) | Application_Status__c |
Map to picklist values; trigger Lead→Contact conversion logic |
Ethos_Person_Id__c as sole upsert key; deduplicate by SSN/ID where permitted.No_Record_Yet__c flag.SystemModstamp comparison; skip update if Salesforce record modified within last sync window.Cutover is executed in a maintenance window with Salesforce EDA in read-only mode. The middleware performs a full extract from Ethos covering all active records with timestamps greater than the last successful sync checkpoint. A validation step compares record counts by entity (Contact, Affiliation, CourseConnection) against Ethos aggregate reports, halting cutover if variance exceeds 0.1%. Upon validation, the middleware enables bidirectional sync and disables the Salesforce manual-entry lock. A rollback script reverts EDA to the pre-cutover snapshot (stored as a weekly export) and re-enables the read-only mode within 15 minutes of triggering. For 30 days post-cutover, a nightly reconciliation report emails discrepancies to the integration owner, and the middleware retains a 90-day event log for audit traceability.
Reading the reference is free. Delivering it under liability — with the safeguards that keep production running through the cutover — is what we do.