group compete for each message, and a message that matches several members goes only to the member it is closest to.
A group decides who receives a message, not when. It is not an ordering key like an SQS FIFO message group: nothing is ordered or serialized.
Subscribe two roles in one group
Open one stream per role, each with its own query and the samegroup:
lead is this member’s score minus the best score among the other members that also matched. It appears only on grouped frames, and only when another member also matched; a member that won uncontested gets a frame without it. 0 means a tie, and every tied member receives the message.
Read lead as a confidence signal. A small lead says the message sat between two roles. A consistently small lead between the same two roles says their queries overlap, and one of them needs more specific anchors.
The group field
group is optional on POST /v1/subscribe: 1 to 64 characters of letters, digits, - and _. Omit it and the subscription receives every message it matches, exactly as before.
Members are compared by score, which is why the kinds must agree: a
CONTRAST member scores lower than a DISTANCE member for an equally good match.
Who competes
- One account, one namespace. A group is the set of your account’s open subscriptions in one namespace that share a name. Every API key on your account shares your group names, so any of your keys can join your group. Another account’s group with the same name never competes with yours.
- Only open streams. Once Semantik sees that a member’s stream has closed, the next-closest open member receives what it would have won. Until then, messages that member wins are lost with the stream, so close streams you are done with rather than abandoning them.
- No runner-up delivery. A message genuinely relevant to two members reaches only the closer one unless they tie exactly.
What changes for the subscriber
A member’sseq values have gaps for messages another member won. In a group, a gap does not by itself mean a lost message.
Messages are still dropped when the winning member’s stream is not read fast enough, as for any subscription. A dropped message is not passed to the next member, so read every member’s stream promptly.
Everything else in Delivery and idempotency applies unchanged: delivery is at-least-once, and frames carry identifiers, not bodies.
Write role queries that compete well
For each role, write a few short anchors in the words its messages use, plus oneOR’d sentence stating what the role is responsible for and naming the concrete things it handles. The two queries above follow that pattern. Short anchors alone, or the sentence alone, each rank the right owner first less often than the two together.
Keep every member in the same shape: the same clause kinds, the same metric, all OR or all AND.
When not to use a group
- Consumers that each need their own copy, such as an audit log next to a worker. Leave them ungrouped.
- Load-balancing identical workers. Members with the same query tie on every message and all receive it.
- Ordering. Matches are delivered concurrently and are not ordered, in a group or out of one.

