Skip to main content

Differences Between Streaming API V1 and V2

Streaming API V2 covers the same core workflow as V1 — create a subscription, stream batches of events, commit cursors, monitor progress — but with a number of behavioral changes. This page summarizes them for teams migrating an existing V1 integration.

URL path

V1 endpoints are under /api/v1/subscriptions/**. V2 endpoints drop the version segment, not the /api prefix: /api/subscriptions/**.

Required headers

Authentication is unchanged from V1 — see Authentication.

Every V2 request must also include an Accept: application/vnd.mambu.v2+json header. Without it, the request is treated as V1.

Create subscription: initial_cursors is no longer supported

The initial_cursors parameter is no longer supported, and read_from no longer accepts cursors as a value. The only supported values for read_from are begin and end.

V2 request bodyV1 request body
{
"owning_application": "applicationName6",
"consumer_group": "consumerGroup",
"event_types": [
"mrn.event.TENANT_NAME.streamingapi.savings_deposit",
"mrn.event.TENANT_NAME.streamingapi.client_created"
],
"read_from": "end"
}
{
"owning_application": "applicationName6",
"consumer_group": "consumerGroup",
"event_types": [
"mrn.event.TENANT_NAME.streamingapi.savings_deposit",
"mrn.event.TENANT_NAME.streamingapi.client_created"
],
"read_from": "cursors",
"initial_cursors": [
{
"event_type": "mrn.event.TENANT_NAME.streamingapi.savings_deposit",
"offset": "001-0001-000000000000000620",
"partition": "0"
}
]
}

Create subscription: a subscription count limit was introduced

A limit on the total number of subscriptions has been implemented. The default limit is 5 subscriptions, but this is a configurable value and can be set to any positive integer on request. A subscription is considered unique based on the combination of owning_application, consumer_group, and event_types — redundant calls with the exact same values for these three fields don't count against the limit.

If the limit is breached:

HTTP/1.1 422
Content-Type: application/problem+json
Content-Length: 45

{
"message": "Subscription limit of 5 reached"
}
note

The OpenAPI spec's own 422 example doesn't yet show this error body (it reuses an unrelated placeholder). The body above is confirmed correct.

Consume events: batches can now contain multiple event types

Batches were previously homogeneous (all events in a batch shared one event type). In V2, cursor.event_type is always MIXED; to identify the type of each event in a batch, use events[].metadata.event_type instead, which is unchanged.

{
"cursor": {
"partition": "shardId-000000000000",
"offset": "49673591198887640830612221074728717584752617270261317634",
"event_type": "MIXED",
"cursor_token": "3b0123a1-532e-4dd3-81ec-aa71a2dd443f"
},
"events": [
{
"metadata": {
"eid": "de45b84d-0684-485e-841e-2ab384931f46",
"occurred_at": "2026-04-15T06:19:58.589Z",
"content_type": "application/json",
"category": "DATA",
"event_type": "mrn.event.TENANT_NAME.streamingapi.savings_deposit"
},
"body": {
"account_id": "GUPO179",
"account_name": "product1",
"client_id": "967244213",
"transaction_id": "186714413",
"amount": "100.00",
"datetime": "2026-04-15 06:19:58"
},
"template_name": "deposit transaction 3"
}
]
}

Cursor offset and partition format changed

FieldV1 formatV2 format
partitionSimple integer, e.g. 0, 1shardId-000000000000, shardId-000000000001, etc.
offset001-0001-00000000000000062049673591198887640830612221074728717584752617270261317634

This affects Subscription Cursors and Committing Cursors. Cursor values are opaque and shouldn't be parsed by clients, but if your integration logs, stores, or validates their format or length, this change will affect it.

A maximum event size limit was introduced

Default limit is 10 KB, and can be increased up to 10 MB (though large events are discouraged due to their impact on streaming latency and throughput). A new error field on event metadata carries details when a size threshold is breached:

"error": {
"code": "MAX_MESSAGE_SIZE_LIMIT_EXCEEDED",
"reason": "Event size 368 bytes exceeds of 10 bytes for event 4028c0819d903d2c019d903d90b100ce",
"location": "communications/messages/4028c0819d903d2c019d903d90b100ce"
}

Consumer scaling is now a fixed number, independent of event type count

The number of supported consumers per subscription is now a fixed value (typically 4, 6, or 8), rather than (number of event types) × 3 as in V1.

Consumer stats: fixed partition count, updated response shape

The consumer stats response no longer depends on the number of event types in the subscription — it now returns a fixed number of partitions:

{
"items": [
{
"partitions": [
{ "partition": "shardId-000000000000", "state": "ACTIVE", "consumer_lag_seconds": 2 },
{ "partition": "shardId-000000000001", "state": "ACTIVE", "consumer_lag_seconds": 1 },
{ "partition": "shardId-000000000002", "state": "ACTIVE", "consumer_lag_seconds": 0 },
{ "partition": "shardId-000000000003", "state": "ACTIVE", "consumer_lag_seconds": 0 }
]
}
]
}

eid changes from UUID to TSID

Every event's metadata.eid changes from a UUID to a TSID (Time-Sorted Unique Identifier).

PreviousNew
Examplefde622d5-f975-4786-8e1d-d328c29761f90R4ZANE59TB94
Length36 characters13 characters
Character sethex digits and hyphensCrockford Base32 (0-9, A-Z excluding I, L, O, U)
Orderingrandomroughly time-sortable

eid is still a required, non-empty string — only its internal format changed, and the format: uuid hint is removed from the schema. This does not affect the X-Mambu-StreamId header, which remains a UUID.

You're affected if your integration:

  • parses eid into a UUID/GUID type (java.util.UUID, .NET Guid, Python uuid.UUID) — deserialization will fail;
  • stores eid in a UUID/uniqueidentifier column, or a CHAR(36) column with a UUID constraint;
  • validates payloads against the OpenAPI/JSON Schema with format assertion enabled;
  • regex-matches eid against a UUID pattern or assumes a fixed 36-character length.

You're not affected if you treat eid as an opaque string used only for de-duplication / idempotency checks.

What to do: treat eid as an opaque string, widen storage to at least VARCHAR(64) and drop UUID constraints, remove UUID format validation, and regenerate any generated API clients from the updated spec.

New: producer stats API

A new endpoint reports the number of unpublished events — events generated by the system but not yet available for consumption. In a healthy system this should stay close to 0; a rising count may indicate a processing issue.

curl -X GET --location "https://localhost/api/streaming/publisher/stats"
HTTP/2 200 OK
content-type: application/vnd.mambu.v2+json

{
"unpublished_events": 1670
}
note

This endpoint isn't in subscriptions_v2_swagger.json, so it has no generated request/response reference page yet.