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/mappingsReturns all mappings scoped to the current application and environment.
Get Mapping
GET /api/database/mappings/:idCreate Mapping
POST /api/database/mappingsRequest 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"
}| Field | Required | Description |
|---|---|---|
table | Yes | Source database table (schema-qualified, e.g. salesforce.exam_session__c) |
topics | Yes | Per-action topic routing map (see Per-Action Topics below) |
events | Yes | Database operations: insert, update, delete |
triggerColumns | Yes | Columns that must change to trigger. Use ["*"] for any column (wildcard). Empty array also means any column |
payload | Yes | Output field map. Use $row.colName for table columns, $enriched.fieldName for enriched fields, or a static string |
when | No | Conditional trigger — see Trigger Conditions |
enrich | No | Enrichment sources — see Enrichment |
entityKeys | No | Array of payload field names that identify the tenant/entity for subscription filtering |
entityKey | No | Single entity key (legacy, use entityKeys instead) |
environment | Yes | development, 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"]
}
}| Key | Type | Description |
|---|---|---|
insert | string[] | Topics to publish to on INSERT operations |
update | string[] | Topics to publish to on UPDATE operations |
delete | string[] | 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:
| Value | Behavior |
|---|---|
["*"] | 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:
| Rule | Description | Example |
|---|---|---|
changed | Column value changed from previous state (always true for INSERTs) | { "changed": "status" } |
eq | Field 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/:idDelete Mapping
DELETE /api/database/mappings/:idDeletion 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/:topicEnvironment Status
GET /api/database/mappings/statusReturns 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/versionsCreate Version Snapshot
POST /api/database/mappings/:id/versionsRequest Body:
{
"environment": "development"
}Promote Mapping
POST /api/database/mappings/:id/promoteCopies the source environment's latest version into the next environment (dev → staging, staging → prod).
Request Body:
{
"environment": "staging"
}Subscriptions
List Subscriptions
GET /api/database/subscriptionsCreate Subscription
POST /api/database/subscriptionsRequest Body:
{
"mappingId": "map_123"
}Activate / Deactivate
POST /api/database/subscriptions/:id/activate
POST /api/database/subscriptions/:id/deactivateDelivery Logs
GET /api/database/subscriptions/logs?event=database.update