> ## Documentation Index
> Fetch the complete documentation index at: https://archie.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Event Bus

> Publish an event once and deliver it to many places at the same time. Create topics, add subscriptions with a two-step wizard — to a queue, your project's API, or an external endpoint — filter by event type, and watch every delivery in the Activity tab.

The **Event Bus** lets your app announce that something happened — an order was created, a user signed up — and have that single announcement delivered to **every interested subscriber at once**. You publish one event to a **topic**; each **subscription** on that topic receives its own copy and delivers it to its target.

Open **Backend → App Services → Event Bus** to manage it.

<Note>
  Topics and subscriptions are per **environment**. Publishing to the `orders` topic in `development` never reaches subscriptions in `production`.
</Note>

## The three pieces

| Piece            | What it is                                                                                                                                   |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **Topic**        | A named channel you publish events to (e.g., `orders`, `users`).                                                                             |
| **Event**        | A single announcement: an **event type** (e.g., `orders.created`) plus a JSON **payload**.                                                   |
| **Subscription** | A rule attached to a topic that says *"when an event matches this filter, deliver it here"* — to a queue, your API, or an external endpoint. |

One topic can have many subscriptions, and each gets an **independent copy** of every matching event. That independence is the whole point: a slow or failing subscriber never affects the others.

## Topics

The Event Bus landing view lists your topics in a table — **Name**, **Events (24 h)**, **Subscriptions**, and **Failed** (the number of failing deliveries, so an unhealthy topic stands out at a glance) — plus a per-row actions menu. Creating a topic needs only a name (retention lives under Advanced).

<Steps>
  <Step title="Create a topic">
    Click **New topic**, give it a name, and create it. The infrastructure is provisioned automatically for this environment.
  </Step>

  <Step title="Open the topic">
    Click the topic to open its detail, which has three tabs: **Subscriptions**, **Publish test**, and **Activity**.
  </Step>
</Steps>

## Add a subscription (the two-step wizard)

The subscription wizard is the heart of the Event Bus. It answers two questions.

### Step 1 — Which events?

Choose which events this subscription reacts to:

| Mode               | Matches                    | Example                                                  |
| ------------------ | -------------------------- | -------------------------------------------------------- |
| **All events**     | Every event on the topic.  | `orders.created`, `orders.shipped`, …                    |
| **One exact type** | Only the type you name.    | only `orders.created`                                    |
| **Pattern**        | A single-segment wildcard. | `orders.*` matches `orders.created` and `orders.shipped` |

A live preview shows which of the topic's recent event types would match, so you can confirm before moving on.

### Step 2 — Where should it go?

Pick a target. This is where "internal" versus "external" matters.

<CardGroup cols={3}>
  <Card title="Queue" icon="layer-group">
    Deliver each matching event into one of your existing queues, to be processed by a worker in the background.
  </Card>

  <Card title="Your API" icon="server">
    Deliver to your **own project's** API (GraphQL or REST). Authentication is handled for you — no URL, no secret.
  </Card>

  <Card title="External endpoint" icon="globe">
    Deliver to an **outside** HTTPS service you own, with your choice of authentication and a signature they can verify.
  </Card>
</CardGroup>

#### Target: Queue

Select one of your existing queues in the same environment (or create one inline). Each subscribed queue receives its own copy of every matching event — this is the classic **fan-out then process** pattern covered in [Using them together](/docs/features/backend/app-services/queues-and-event-bus/using-them-together).

#### Target: Your API (internal — the default)

When the destination is your own project, Archie resolves the address and authentication for you. There is **no URL to paste and no secret to manage**.

* **GraphQL** — Archie targets your project's GraphQL endpoint (the same one the [GraphQL API Explorer](/docs/features/backend/graphql-api-explorer/overview) uses). You only provide the **mutation template** that turns the event into a write. The event is available to the template so its fields can populate the mutation's input.
* **REST** — pick one of your project's generated REST endpoints (resource and method) from the [REST API Explorer](/docs/features/backend/rest-api-explorer/overview). Nothing else to configure.

<Note>
  Internal delivery carries your project and environment context automatically, so the event lands as an authenticated call scoped to the right tenant. This is why the internal option is the default and the simplest to set up.
</Note>

#### Target: External endpoint

When the destination is a system **outside** Archie, you provide the details and Archie protects the delivery:

<Steps>
  <Step title="Enter the URL">
    An **HTTPS** URL is required. Archie blocks internal, loopback, and cloud-metadata addresses (an SSRF safeguard), so an external target must be a genuine public endpoint.

    The URL can include **dynamic parameters** that are filled in from each event's payload at delivery time. Three styles work — `{field}`, `[field]` and `:field` — and each is replaced by the matching top-level field of the event. For example `https://api.partner.com/orders/{orderId}/status` with an event payload `{ "orderId": 42 }` is delivered to `…/orders/42/status`. The SSRF checks run on the **final** address, and a placeholder with no matching field is left as-is (so the delivery visibly fails rather than going somewhere unexpected).
  </Step>

  <Step title="Choose the HTTP method">
    Pick the verb Archie uses to deliver: **POST** (default), **PUT**, **PATCH**, or **DELETE**. The event is sent as the request body.
  </Step>

  <Step title="Choose authentication">
    Pick one:

    * **None**
    * **Bearer token** — sent as an `Authorization: Bearer …` header.
    * **Custom headers** — one or more name/value pairs (e.g., `X-Api-Key`, `X-Tenant`). Add and remove rows as needed. They are sent on **every** delivery.

    Credentials and custom-header values are **encrypted at rest** and never shown again — Archie only displays the header **names** afterward. Archie's own headers (the signature, `Content-Type`, and the `X-Archie-*` metadata) always take precedence, so a custom header can't override them.
  </Step>

  <Step title="Copy the signing secret (shown once)">
    Archie generates an **HMAC signing secret** and shows it **one time**. Copy and store it securely — you won't be able to see it again. Every delivery is signed with it, so your receiver can verify the request genuinely came from Archie.
  </Step>

  <Step title="Send a test">
    Send a test event and confirm your endpoint returns a success status.
  </Step>
</Steps>

<Warning>
  The external signing secret is displayed **only at creation time**. If you lose it, rotate it by recreating the subscription. Verify the signature on your side before trusting a delivery.
</Warning>

<Note>
  Any subscription can carry an optional **description** (a short label like "Notify fulfilment"). For endpoint targets it is also delivered with the event — as a `subscriptionDescription` field in the body and an `X-Archie-Subscription-Description` header — so the receiver can tell which subscription a delivery came from.
</Note>

## The subscription list

Each topic's **Subscriptions** tab shows every subscription with its filter, its target (an icon plus a friendly label — e.g., "your API · POST /orders" for internal, or a truncated URL for external), and controls:

| Control           | What it does                                                                                                                                            |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Active toggle** | Pause or resume delivery to an endpoint subscription without deleting it. Paused subscriptions stop receiving new events until you switch them back on. |
| **Delete (×)**    | Remove the subscription. Existing delivery history is retained for reference.                                                                           |

## Publish a test event

The **Publish test** tab lets you fire an event by hand to see the whole chain work end to end:

<Steps>
  <Step title="Choose an event type">
    Type an event type (recent ones are suggested), e.g., `orders.created`.
  </Step>

  <Step title="Write the payload">
    Provide a JSON payload in the editor.
  </Step>

  <Step title="Publish">
    Click **Publish**. Archie reports the result for each subscription — for example, a queue's depth increasing, an endpoint returning `200 OK`, or a subscription **skipped** because its filter didn't match.
  </Step>
</Steps>

You can also publish from your app:

```graphql theme={null}
mutation {
  publishEvent(
    topic: "orders"
    eventType: "orders.created"
    payload: "{\"orderId\":\"A-1024\",\"total\":51.25}"
  ) {
    messageId
  }
}
```

## Watch deliveries in Activity

The **Activity** tab is your audit trail of what actually happened. It lists delivery attempts newest-first:

| Column       | Meaning                                                                                       |
| ------------ | --------------------------------------------------------------------------------------------- |
| **Date**     | When the attempt occurred.                                                                    |
| **Event**    | The event type that was delivered.                                                            |
| **Status**   | The outcome — a green `2xx` on success, or a red status code (e.g., `429`, `500`) on failure. |
| **Attempts** | How many times this delivery has been tried.                                                  |

Use the **Failed only** toggle to focus on problems, and the pager to move through history. Endpoint deliveries are **retried automatically** with increasing back-off; if they keep failing they land in that subscription's **error list (dead-letter queue)**, from which you can redrive them once the cause is fixed.

<Note>
  Delivery history is written for endpoint targets (your API and external endpoints). Queue targets don't produce delivery rows here — instead, watch the **Pending** count and error list on the destination [queue](/docs/features/backend/app-services/queues-and-event-bus/queues).
</Note>

## Common questions

<AccordionGroup>
  <Accordion title="What's the difference between an event type and a topic?">
    A **topic** is the channel (e.g., `orders`). An **event type** is the specific thing that happened on it (e.g., `orders.created`). Subscriptions filter by event type within a topic.
  </Accordion>

  <Accordion title="Do all subscribers get the event at the same time?">
    Each matching subscription gets its **own copy**, delivered independently. If one subscriber is slow or failing, the others are unaffected.
  </Accordion>

  <Accordion title="When should I deliver to my own API vs an external endpoint?">
    Use **Your API (internal)** when the reaction is a write in your own project — it needs no configuration and no secret. Use **External endpoint** when you're notifying a system outside Archie that you own.
  </Accordion>

  <Accordion title="A subscription shows as failing — what do I check?">
    Open **Activity**, filter to **Failed only**, and read the status codes. A `4xx` usually means the target rejected the request (auth, validation); a `5xx` or timeout usually means the target was unavailable. Fix the cause, then redrive the subscription's error list.
  </Accordion>

  <Accordion title="Can I temporarily stop a subscription without losing it?">
    Yes — switch its **Active** toggle off. It stops receiving new events and keeps its configuration and history; switch it back on to resume.
  </Accordion>
</AccordionGroup>

## Next

<CardGroup cols={2}>
  <Card title="Using them together" icon="diagram-project" href="/docs/features/backend/app-services/queues-and-event-bus/using-them-together">
    Fan an event out to several queues and process each copy in the background.
  </Card>

  <Card title="Reference & FAQ" icon="book" href="/docs/features/backend/app-services/queues-and-event-bus/reference">
    Operations, limits, statuses, and troubleshooting.
  </Card>
</CardGroup>
