Appearance
Verdicts and refusals
Every message goes through one gateway, in this order:
firewall and rate limits → size → identity → JSON → SOM envelope, version and payload → grants
→ idempotency → snapshot sequence → story ownership → commit → publish to consumersNothing reaches a consumer unless it passes every step. A message stops at the first step that refuses it; within the SOM step, the bus reports every violation it finds, not just the first.
The response names the rule
json
{
"accepted": false,
"violations": [
{ "source": "sequence", "rule": "sequence_number.not_increasing",
"message": "sequence_number 7 -> 6: must strictly increase…", "path": "/payload/sequence_number" }
]
}ruleis a stable id. Branch on it, never onmessage, which is for people and may change. Every rule id has a page in the rule catalogue.path, when present, is a JSON Pointer into your message.sourcesays who is saying no:
source | Who says no | What it means for you |
|---|---|---|
schema | The SOM 1.0 JSON Schema, or a body that isn't JSON at all (message.not_json) | Your message isn't valid SOM. Fix the producer |
conformance | The SOM conformance rules the schema can't express | Not valid SOM 1.0, for example a pre-1.0 wire version |
sequence | SOM conformance on snapshot order, checked against the story's previous snapshot | Your story state is inconsistent. Send a fresh, complete snapshot |
policy | This bus's operational rules: identity, grants, size, idempotency, story ownership | Not a SOM verdict. Check your credentials, grants, retry logic or which system writes the story |
Keeping policy apart means "the standard says no" is never confused with "this bus says no".
Accepted, with notes
An accepted message may carry tolerated[]: things the bus let through but wants you to know about. A gap in sequence_number, a changed correlation_id, a payload with no schema, fields from a newer 1.x, or a snapshot from a system that doesn't own the story (in a workspace that warns, the default). They use the same shape and rule ids as violations.
Status codes
| Status | Meaning | What to do |
|---|---|---|
202 | Accepted. tolerated[], if present, lists notes | Nothing |
200 | Duplicate of a message already accepted (same message_id, same content) | Nothing. Treat as success |
400 | Not JSON, not valid SOM 1.0, or content refused by policy | Fix the message |
401 | producer.unauthenticated: token missing, malformed, expired, issued before a rotation, or from the wrong environment | Get a new token |
403 | producer.not_registered: valid credentials, but no active connection. principal.not_verified: an AWS role that hasn't proved it's yours yet. tenant.mismatch: another workspace's route. producer.system_id_not_allowed or producer.message_type_not_allowed: outside your grants. request.blocked: refused by the firewall | Check the connection in the portal; for the firewall, ask RND |
409 | A sequence rule, message_id.reused or commit.contention | Send a fresh, complete snapshot with a new message_id |
409 | story.not_owner, in a workspace that refuses it: your system doesn't own the story | Publish from the story's owner, or ask a workspace admin for a hand-off |
413 | message.too_large | Send references, not media |
429 | rate.limited: over a rate limit (see Limits). quota.exceeded: your connection's daily allowance is used up | Back off and retry, honouring Retry-After when present |
409 | message.superseded: a retried snapshot that was recorded but never published, whose story has moved on. Not delivered | Nothing: the newer snapshot supersedes it |
503 | bus.publish_failed or registry.unavailable: not published. message.in_flight: an earlier attempt is less than 30 seconds old and not confirmed published | Retry with the same message_id |
Try it without publishing
The portal's Playground runs the gateway's own checks against your workspace's story state and stops before anything is stored or sent. It checks the message, not your app's grants. To check with your app's grants too, use your workspace's validate route (see Token service and workspace API). More: The Playground.