Problem 1
Every team opens its own broker
Producers plugged straight into Kafka, with no contract or quota.
Flexway's answer: A channel exists only if the AsyncAPI declares it; publishing goes through the gateway.
Asynchronous
Publish to Kafka, AMQP or MQTT from HTTP, under an AsyncAPI contract, with the same identity and quotas as everything else; signed, replayable outgoing webhooks.
8 of the 9 shown delivered · since v1.5.0
What you expect from this domain
minimum and maximum bounds on validated payloads; clinical rules stay with the servicePartly · next to be scheduled1.7.0); condition on the real state: candidate; physical safety systems stay independentPartly · next to be scheduled

Problem 1
Producers plugged straight into Kafka, with no contract or quota.
Flexway's answer: A channel exists only if the AsyncAPI declares it; publishing goes through the gateway.
Problem 2
An HTTP client waits for an answer a consumer will process later.
Flexway's answer: The gateway answers 202 with an id and publishes in a CloudEvents envelope.
Problem 3
The receiver can neither check the origin nor replay.
Flexway's answer: Signed, replayable webhooks, under the same audit.
Every step is a decision readable in the trace and in the console.
Asynchronous - Domain diagram: who calls, the decision steps, what is called, and where a request is refused.
undeclared channel: refused
The applications that call your APIs: each request goes through Flexway, which checks the contract and the identity before reaching your systems.
Routes through here
The partner companies that consume your APIs: identified by a client certificate or an API key, under a quota per tenant.
Routes through here
The channel must be declared in the AsyncAPI contract; an undeclared channel is refused before any publication.
Routes through here
Flexway checks who is calling (OIDC token, API key or client certificate) and reads the tenant from the identity; no valid identity: 401.
Routes through here
A token bucket per caller limits its rate; beyond it: 429 with Retry-After and the RateLimit headers.
Routes through here
The message is put in a CloudEvents 1.0 envelope, so every consumer reads it the same way.
Routes through here
Flexway publishes the message on your Kafka, AMQP or MQTT broker, as a client of that broker.
Routes through here
The caller gets a 202 with an identifier: the message is accepted, what follows is asynchronous.
Routes through here
Your Kafka cluster: Flexway publishes on it the events received over HTTP, under contract, in a CloudEvents envelope.
Routes through here
Your AMQP and MQTT brokers: Flexway publishes on them as a client of the broker, under an AsyncAPI contract.
Routes through here
Your partners' systems: they receive your events as signed, replayable webhooks.
Routes through here
The essentials of each topic, with its status in the published release; unfold a card for the full text.
The asynchronous plane has its AsyncAPI 3.0 or 3.1 contract: what is published or consumed is exactly what is declared, checked at load.
The asynchronous plane has its contract, just as the synchronous one has OpenAPI: contracts.asyncapi loads an AsyncAPI 3.0.0 or 3.1.0 document, validated against the embedded official schema. Channels, their messages and their schemas come from the contract; a send or receive operation names its broker with x-flexway-upstream. The HTTP entry point is an OpenAPI operation marked x-flexway-publish or x-flexway-subscribe.
The invariant stays the same: published or consumed = declared. An operation with no broker, an entry point to a missing operation or one in the opposite direction, a body with a different schema from the message, or a message without a JSON schema (Avro, Protobuf) are refused at load, all reported in one pass. A refusal is stated, never ignored.
An HTTP client publishes without a broker client: the body is validated, wrapped in CloudEvents, and the gateway answers 202 only after the broker acknowledges.
An HTTP client, or an agent through an MCP tool, publishes without embedding a broker client. The body is read in full within a bound, checked against the message schema, then wrapped in CloudEvents 1.0 binary mode (structured on MQTT 3.1.1). The gateway answers 202 only after the broker acknowledges: acks=all from an idempotent Kafka producer, AMQP confirms, MQTT PUBACK at QoS 1. An Idempotency-Key becomes the event id, and idempotency: required makes it mandatory (428 otherwise).
The buffer is bounded per broker and per replica (max_in_flight, 1,024 by default): beyond it, an immediate 503 overloaded, never a queue that grows with the outage. A circuit breaker per broker gives 503 upstream_unavailable; exceeding the budget gives 504 upstream_timeout, meaning the outcome is unknown.
The gateway authenticates to the broker (SASL, mTLS, secrets by reference); the caller travels as CloudEvents attributes - tenant always, traceparent, authid and authtype only if the message declares them - and a ce-* header supplied by the caller is refused (400). A message published through a REST route carries the same audit line and the same authorisation verdict as a synchronous call.
Browsers and mobiles consume a stream over SSE or WebSocket without speaking the broker's protocol, each subscriber receiving only what its verified values name.
A browser or a mobile app consumes a stream without speaking the broker's protocol. Over SSE, delivery fans out: one consumer per channel and per replica, whatever the number of subscribers; resumption uses Last-Event-ID from the channel's in-memory history (history, 64 by default), with 412 beyond it. Over WebSocket, delivery is at least once: the position advances only after {"ack": "<id>"}, otherwise the connection is closed after ack_timeout and the message is delivered again.
A subscriber receives only what its verified values name: a bound channel parameter (x-flexway-bind: tenant, subject or claim:<name>) or the tenant attribute filtered on headers, never on data. A channel that is neither bound, nor filtered, nor declared public is refused at load. Public access is declared explicitly (x-flexway-public: true on the receive operation) and is still counted per address and overall.
The buffer is bounded per stream, a subscriber that is too slow is closed, and max_streams caps streams per caller and per replica (429 too_many_streams). Durable state - positions, groups - stays in the broker: the gateway remains stateless. Subscribing an agent to a stream through an MCP tool is upcoming.
Kafka, AMQP and MQTT go through the same admission as HTTP traffic (identity, quota, audit, trace), the gateway reaching each broker as a client.
Kafka, AMQP 0-9-1 (and AMQPS) and MQTT go through the same admission as HTTP traffic: identity, quota, audit, trace. The gateway reaches a broker as a client, never through a broker listener, and a contract operation is never relayed as is to a broker. Upstreams are declared with upstreams.*.protocol (kafka, amqp, mqtt), with brokers, protocol_version and sasl, whose password is a reference.
On consumption, both CloudEvents modes are read according to each binding's rule: application/cloudevents+json as structured, binary otherwise. Errors on the asynchronous plane are expressed as a CloudEvents attribute, as they are expressed in RFC 9457 over HTTP. The configuration reloads hot: an unchanged broker client is reused, and one client per subscription costs connections, hence the max_streams cap.
A receive operation delivers a tenant's events to a declared target, signed in the Standard Webhooks format, with bounded retries and a replayable dead-letter queue.
A receive operation can deliver to a declared target (x-flexway-deliver, upstream protocol: webhook). Consumption runs in a group shared by the replicas, one replica per message, in the Standard Webhooks format: webhook-id equal to the event id, an HMAC-SHA256 signature covering the attributes, two active secrets for rotation, a structured CloudEvent as the body. A partner thus receives its tenant's events without access to the broker.
The address is checked at connection time: loopback, link-local and cloud metadata addresses are always refused, private ranges only with allow_private, with no proxy and no redirect. Retries are bounded (retries.max, retries.max_delay) and honour Retry-After, with a circuit breaker per target. The position advances only after a 2xx; once retries are exhausted or on a 4xx refusal, the intact event goes to the declared dead-letter queue with problemcode and problemstatus, from where it can be replayed.
A delivery has no caller: a channel bound to a caller fact (subject, claim) cannot be delivered by webhook, and a delivery without a tenant or without a dead-letter queue is refused at load.
The native Kafka proxy connects Kafka clients directly to the gateway, with virtual clusters and topics per tenant.
The delivered asynchronous plane mediates between HTTP and brokers. The native Kafka proxy goes further: Kafka clients connecting directly to the gateway, with virtual clusters and topics per tenant.
It comes with ACLs and quotas per Kafka client, then field-level encryption of messages at the proxy. The state of these three features in this release, read from the product's catalogue, is shown below.
No complete example for this domain in release v1.6.3 yet: one will come with an upcoming release.
What is delivered in the published release v1.6.3, and what is coming; a feature is never shown as delivered before its release.
| Feature | Status |
|---|---|
| AsyncAPI as the source of the asynchronous plane | Delivered · v1.5.0 |
| Kafka publishing under contract, CloudEvents envelope | Delivered · v1.5.0 |
| Mediation of the synchronous to asynchronous boundary | Delivered · v1.5.0 |
| AMQP(S) and MQTT | Delivered · v1.5.0 |
| Signed, replayable outgoing webhooks | Delivered · v1.5.0 |
| Native Kafka proxy: Kafka clients on the gateway, virtual clusters and topics per tenant | Delivered · v1.6.1 |
| ACLs and quotas per Kafka client at the native proxy | In part |
| Message field encryption at the native proxy | Delivered · v1.6.1 |
| Console: Kafka clients and clusters, connections per tenant, refusals by cause, encryption and built-in alert rules | Delivered · v1.6.1 |
The other expectations of this domain
external-call covers HTTP; asynchronous commands: candidateTo be scheduledFlexwiz is a young company: you talk directly with the person who founds it. Tell us what you want to run through Flexway. We talk about your infrastructure and your digital sovereignty requirements.
Online booking is coming soon; until then, an e-mail is enough.