# Publishing and subscribing

> Publish an event over HTTP, and receive your tenant's over SSE or WebSocket - with no broker client. Messages are CloudEvents 1.0. Product side: Asynchronous…

Guide - Since version 1.5.0 - Flexway v1.6.3 - https://flexway.io/en/docs/developer-async/

> Publish an event over HTTP, and receive **your** tenant's over SSE or WebSocket - with no broker client. Messages are **CloudEvents 1.0**.
>
> Product side: [Asynchronous plane and brokers](https://flexway.io/en/docs/product-async/); operations side: [Publishing and consuming on a broker](https://flexway.io/en/docs/operations-async/).

## Publishing

```bash
curl -i -X POST https://api.example.com/orders/events -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -H 'Idempotency-Key: order-42' -d '{"orderId":"42"}'
# HTTP/1.1 202 Accepted   {"id":"order-42"}
```

| Response | Meaning | What to do |
| --- | --- | --- |
| `202` | The broker **acknowledged** the message | Nothing |
| `428 idempotency_key_required` | The door requires `Idempotency-Key` | Add it |
| `504 upstream_timeout` | **Unknown** outcome: the message may have been written | Send again with the **same** `Idempotency-Key` - it becomes the `id`, consumers deduplicate |
| `503 overloaded` | The gateway's buffer is full | Wait `Retry-After` |
| `503 upstream_unavailable` | The broker is unreachable | Wait `Retry-After` |
| `400` | You sent a `ce-*` header: the attributes are the gateway's | Remove it |
| `415`, `422` | A body of another type, or outside the schema | Fix it |

The tenant, `id`, `source` and trace are set by the gateway. Order is guaranteed per message key only.

## Subscribing over SSE

```bash
curl -N https://api.example.com/orders/stream -H "Authorization: Bearer $TOKEN" -H 'Accept: text/event-stream'
# id: 0:18,1:7,2:11
# event: created
# data: {"specversion":"1.0","id":"order-42","tenant":"acme","data":{"orderId":"42"},...}
```

| Rule | Detail |
| --- | --- |
| Resumption | Come back with `Last-Event-ID`: reading resumes from the channel's recent history |
| Beyond the history | `412 precondition_failed`: open again **without** `Last-Event-ID` |
| Too slow a subscriber | Closed (`event: error`, `overloaded`) |
| Number of streams | Capped per caller |
| Binary payloads | Received as JSON (`datacontenttype: application/json`) |

## Subscribing over WebSocket

Each message is a JSON CloudEvent; acknowledge it within the announced delay:

```javascript
ws.onmessage = (m) => {
  const ev = JSON.parse(m.data);
  handle(ev);
  ws.send(JSON.stringify({ ack: ev.id }));
};
```

| Close | Meaning |
| --- | --- |
| `1008` | A refusal, or a missing acknowledgement within the delay: the message is delivered again on reconnection (**at least once**) |
| `1011` | The broker is down: reconnect after a delay |
| `1013` | Too slow a subscriber |

The last message before the close carries the RFC 9457 problem. Deduplicate on `source` + `id`.
