Events feed
Read changes with GET /api/v1/musiccompanion/events. Use an organization API key with the musiccompanion.api permission. Events are tenant scoped. This feed does not require an entitlement check and does not push webhook deliveries.
Polling
GET /api/v1/musiccompanion/events?limit=100&types=entity.created,entity.updated
Authorization: Bearer YOUR_API_KEY
The response contains events, nextCursor, and hasMore. Each event contains id, type, occurredAt, product, resourceKind, resourceId, dmrn, sourceSystem, batchId, schemaVersion, and data. Payloads contain identifiers and small facts, not resource snapshots. Fetch the resource separately when you need its current state. DMRN is null when the resource has no external reference. Standalone analysis uploads can have a null entity identifier.
The cursor is an opaque, versioned token; do not construct it from an event ID.
Save each page's nextCursor only after successfully processing the page. Send it as after on the next request. When the page is empty, nextCursor is null: keep your previous cursor. hasMore indicates that another page was available when the request ran. The page size defaults to 100 and accepts 1 through 500; other values, unknown event types and malformed cursors return 400.
An event may appear more than once; dedupe on id. Delivery is at least once. Retrying the same cursor is safe. Keep a separate cursor for each type filter; changing the filter while keeping a cursor does not replay earlier events of newly selected types.
Events are ordered by transaction ID, with event ID as a tie-breaker; this is not timestamp order. Transactions that are still open can temporarily hold back newer committed events, so an empty page does not prove there were no recent changes. Continue polling from the same cursor. Events and the corresponding writes commit together.
Poll once every five seconds or slower. There is a separate limit of 60 event requests per minute per key; on 429, wait for the Retry-After duration. Normal pre-authentication IP limits also apply.
Retention and event catalog
Design consumers for a 30-day replay window. Age-based purge ships with the webhook delivery package; until then older events may remain, but consumers must not depend on that. If a consumer falls behind the window, reconcile resources through the resource APIs before resuming incremental reads. The feed does not currently detect expired cursors for you.
The OpenAPI DomainEvent schema is generated from the event registry and lists each payload and its description. Families include entities, relations, versions, assets, markers, molecules, analyses, MusicMaster sync and assignments, integration health, and jobs. Episode and transcription events are recorded for active aircheck. subscribers; the musiccompanion. feed does not expose aircheck. events. ping is reserved for the later delivery package.
Payload extensions are additive. Breaking payload changes get a new event type. Entity events are published from the start; the internal coverage report identifies writes still needing migration. No historical backfill is performed. Attaching a DMRN to an entity records entity.updated with changedFields: ["externalReferences"]; repeating an attach that is already in place records nothing.
API writes use public-api:<keyId> as sourceSystem unless an integration binding maps the key to a source such as dabis. This supports downstream echo suppression without including credentials in events.