API Reference

Database API

Manage CDC mappings, versions, promotions, enrichment, and database subscriptions.

The Database API manages domain mappings (table-to-topic configurations), mapping versions, environment promotion, and database subscriptions.

Mappings

List Mappings

GET /api/database/mappings

Returns all mappings scoped to the current application and environment.

Get Mapping

GET /api/database/mappings/:id

Create Mapping

POST /api/database/mappings

Request Body:

{
  "table": "salesforce.exam_session__c",
  "topics": {
    "insert": ["proctoring.session.created"],
    "update": ["proctoring.session.updated"]
  },
  "events": ["insert", "update"],
  "triggerColumns": ["*"],
  "payload": {
    "sid": "$row.sid__c",
    "status": "$row.status__c",
    "installSid": "$enriched.installSid",
    "accountSid": "$enriched.accountSid"
  },
  "when": {
    "or": [
      { "changed": "status__c" },
      { "eq": ["$enriched.deploymentType", "proctored"] }
    ]
  },
  "enrich": [
    {
      "from": "salesforce.application_install__c",
      "fields": { "installSid": "sid__c" }
    },
    {
      "from": "salesforce.account_deployment__c",
      "fields": { "accountSid": "account_sid__c", "deploymentType": "type__c" }
    }
  ],
  "entityKeys": ["installSid", "proctorAccountSid"],
  "environment": "development"
}
FieldRequiredDescription
tableYesSource database table (schema-qualified, e.g. salesforce.exam_session__c)
topicsYesPer-action topic routing map (see Per-Action Topics below)
eventsYesDatabase operations: insert, update, delete
triggerColumnsYesColumns that must change to trigger. Use ["*"] for any column (wildcard). Empty array also means any column
payloadYesOutput field map. Use $row.colName for table columns, $enriched.fieldName for enriched fields, or a static string
whenNoConditional trigger — see Trigger Conditions
enrichNoEnrichment sources — see Enrichment
entityKeysNoArray of payload field names that identify the tenant/entity for subscription filtering
entityKeyNoSingle entity key (legacy, use entityKeys instead)
environmentYesdevelopment, staging, or production

Per-Action Topics

The topics field maps each database operation to one or more concrete topic names. All referenced topics must be pre-created entries in the topics registry.

{
  "topics": {
    "insert": ["proctoring.session.created"],
    "update": ["proctoring.session.updated", "proctoring.session.changed"],
    "delete": ["proctoring.session.deleted"]
  }
}
KeyTypeDescription
insertstring[]Topics to publish to on INSERT operations
updatestring[]Topics to publish to on UPDATE operations
deletestring[]Topics to publish to on DELETE operations

Each action can route to multiple topics (arrays). When a CDC event fires, the reader looks up topics[action] and routes the event to every topic in the array. This enables patterns like publishing to both a specific topic (proctoring.session.updated) and a catch-all topic (proctoring.session.changed) from a single mapping.

If an action is omitted from the map (e.g. no delete key), events for that operation are not routed even if the action is listed in events.

Info

This replaces the previous single topic string field. The per-action model eliminates the need for duplicate mappings when different actions should publish to different topics.

Trigger Column Wildcards

The triggerColumns field supports a special wildcard value:

ValueBehavior
["*"]Fire on any column change (wildcard — skips column filtering entirely)
["status", "ended_at"]Fire only when one of the listed columns changes
[]Fire on any column change (same as wildcard)

Enrichment

Enrichment pulls fields from related tables into the event payload via the Table Relationships API. The enrichment pipeline uses BFS to traverse the relationship graph and builds LEFT JOIN queries.

Each enrichment source specifies:

  • from — the target table to pull data from (must have a relationship path from the mapping's source table)
  • fields — map of { outputFieldName: sourceColumnName }

Enrichment supports multi-hop paths (e.g., session → appinstall → account_deployment). LEFT JOINs ensure that a NULL FK at any intermediate hop doesn't drop the entire result — the enriched field simply resolves to null.

Trigger Conditions

The when field defines conditional logic for selective event routing. Conditions support both table columns and enriched fields.

Condition structure:

{
  "and": [ ...rules ],
  "or":  [ ...rules ]
}

Rule types:

RuleDescriptionExample
changedColumn value changed from previous state (always true for INSERTs){ "changed": "status" }
eqField equals a value{ "eq": ["$row.status", "active"] }
eq (enriched)Enriched field equals a value{ "eq": ["$enriched.deploymentType", "proctored"] }

Field prefixes in eq rules:

  • $row.fieldName — resolves from the new row data
  • $enriched.fieldName — resolves from enriched fields (requires enrichment sources)
  • fieldName (no prefix) — resolves from the new row data

Update Mapping

PATCH /api/database/mappings/:id

Delete Mapping

DELETE /api/database/mappings/:id

Deletion Guard: If a CDC subscription is linked to this mapping, the delete request is rejected with a 409 Conflict response:

{
  "error": {
    "code": "HAS_CDC_SUBSCRIPTION",
    "message": "Cannot delete mapping while a CDC subscription is linked to it. Remove the subscription first.",
    "subscriptionId": "csub_abc123"
  }
}

Remove the CDC subscription before deleting the mapping to avoid orphaned subscriptions.

Get Mappings by Topic

GET /api/database/mappings/topic/:topic

Environment Status

GET /api/database/mappings/status

Returns the promotion status of all mappings across environments. Used by the Environment Grid UI.

Response:

[
  {
    "id": "map_123",
    "table": "sessions",
    "topics": { "insert": ["session.created"], "update": ["session.updated"] },
    "environments": {
      "development": { "version": 3, "active": true },
      "staging": { "version": 2, "active": true },
      "production": { "version": 1, "active": true }
    }
  }
]

Versions

List Versions

GET /api/database/mappings/:id/versions

Create Version Snapshot

POST /api/database/mappings/:id/versions

Request Body:

{
  "environment": "development"
}

Promote Mapping

POST /api/database/mappings/:id/promote

Copies the source environment's latest version into the next environment (dev → staging, staging → prod).

Request Body:

{
  "environment": "staging"
}

Subscriptions

List Subscriptions

GET /api/database/subscriptions

Create Subscription

POST /api/database/subscriptions

Request Body:

{
  "mappingId": "map_123"
}

Activate / Deactivate

POST /api/database/subscriptions/:id/activate
POST /api/database/subscriptions/:id/deactivate

Delivery Logs

GET /api/database/subscriptions/logs?event=database.update