API / events
Subscribe to Ethos change-notifications and fan them out to your own systems as clean, deduplicated webhooks instead of polling Banner tables.
Ethos exposes change-notifications for resources such as persons, sections, and student-registrations. Rather than polling the underlying Banner tables, subscribe to the notification stream, resolve each change to the current resource representation, and emit a normalized webhook your downstream systems can consume.
A working piece from this integration — no sign-up. The full build handles the edge cases, safeguards, and cutover.
// pull change-notifications, resolve, forward as a normalized webhook GET /consume?limit=100 // Ethos change-notifications // for each change: GET /api/{resource}/{id} // resolve current representation POST https://your-hub/webhooks/ethos { "resource": "student-registrations", "id": "…", "op": "changed", "data": { … } }
How we'd take this from discovery to a production-safe cutover — the phases, the canonical mapping, and the edge cases that bite.
Subscribe to Ellucian Ethos change-notification events and re-publish them as deduplicated, fan-out webhooks to downstream consumers. This replaces polling of Banner (or Colleague) tables with an event-driven pipeline.
persons, courses, sections, academic-loads) your downstream systems need. Pull the current Ethos API OpenAPI spec (available at /api/core/{{version}}/openapi.json) to confirm the change-notification schema for each. List every downstream consumer (Banner table triggers, LMS plugins, identity providers) and decide which events each requires.eventTypes to [CREATE, UPDATE, DELETE] for each required resource type. Target a single receiver endpoint: https://{{your-host}}/api/v1/ethos-events/inbound. Enable includeChangedFields: true to surface only modified attributes. Record the subscriptionId for audit and revocation.X-Ethos-Signature HMAC header (compute HMAC-SHA256(secret, rawBody) and compare). Acknowledge with 202 Accepted immediately; do not process synchronously. Persist the raw event to a durable queue (Azure Service Bus, AWS SQS, or Redis Streams) before responding.{{subscriptionId}}:{{eventId}}. Store keys in Redis with a 24-hour TTL (matching Ethos's replay window). Reject any event whose key already exists with 409 Conflict logged as a benign duplicate.eventId, resourceType, resourceId, eventType, timestamp, and changedFields. Run the pipeline in shadow mode first: emit webhooks to a test endpoint but do not trigger downstream actions.| Ethos Event Field | Webhook Payload Key | Type | Notes |
|---|---|---|---|
eventId |
event.id |
string (UUID) | Use for idempotency key and audit trail. |
eventType |
event.type |
enum: CREATE | UPDATE | DELETE | Maps directly; downstream uses to branch logic. |
resourceType |
resource.kind |
string | E.g., "persons", "sections"; consumer filters on this. |
resourceId |
resource.id |
string | Stable Ellucian GUID; cross-reference with Banner PIDM via Ethos integration table. |
timestamp |
event.occurredAt |
ISO 8601 datetime | Ethos server time; downstream may need to convert to institutional time zone. |
changedFields |
data.changed |
array of strings | Present only on UPDATE; null/empty on CREATE/DELETE. |
subscriptionId |
meta.subscriptionId |
string | Included for traceability back to Ethos admin config. |
X-Ethos-Tenant-Id (header) |
meta.tenantId |
string | Critical for multi-tenant deployments; pass through verbatim. |
eventId under broker restart or network timeout. If deduplication is absent, downstream systems may apply UPDATE twice, corrupting audit columns. Always check the key store before processing.resourceId. Downstream systems that maintain a local cache must treat event.occurredAt as the ordering authority, not arrival sequence.changedFields entry not present in the consumer's expected schema (e.g., a Banner extension attribute). Webhook consumers must ignore unknown keys rather than reject the entire payload.resourceId from Ethos events against the Banner source table on PIDM, flagging any resourceId that has no matching polling record within the same event window. Only decommission the polling path after two consecutive clean reconciliation runs. Maintain an event-sourced audit log of every webhook emitted, including delivery status and retry count, to prove data completeness to auditors. Reading the reference is free. Delivering it under liability — with the safeguards that keep production running through the cutover — is what we do.