How-to guide

Carry customer context with a GroupKey

When one queue carries events for many of your customers, the GroupKey is the thread that says whose event this is. Queuey extracts it at ingress, keeps it on the event as context, and can forward it to your target — so the customer identity travels end-to-end.

1 — Extract it at ingress

Configure where the GroupKey comes from — a query parameter, a header, or a top-level field in the body. One source per key:

extraction sources
# 1) From a query parameter
POST /events/ten_yourTenant/orders?key=ACME

# 2) From a header
POST /events/ten_yourTenant/orders
X-Customer-Id: ACME

# 3) From a field in the JSON body (envelope)
POST /events/ten_yourTenant/orders
{ "customer": "ACME", "eventType": "order.created", "payload": { ... } }

The resolved GroupKey is persisted on the event, so you can filter and observe by customer in the console.

2 — Forward it downstream

Opt in to forward the GroupKey as an outbound header (you choose the name) so your receiver knows which customer an event belongs to:

delivery
POST /your/webhook HTTP/1.1
Authorization: Bearer <token>
X-Account-Id: ACME          # the GroupKey, forwarded downstream
Content-Type: application/json

{ "eventType": "order.created", "payload": { ... } }

3 — Forward more than the GroupKey

The GroupKey is one value with one purpose. When your receiver needs more of the original request — a trace id, a region, an order reference — map any number of outbound headers from the same three sources. Each mapping is a name you choose ← where it comes from:

delivery with mapped headers
POST /your/webhook HTTP/1.1
X-Account-Id: ACME               # GroupKey, as before
X-Trace-Id: 7f3a…                # header:X-Acme-Trace   — forwarded from the request
X-Region: eu-north               # query:region          — from ?region=
X-Order-Ref: ORD-1042            # envelope:orderRef     — from the body
Content-Type: application/json

{ "orderRef": "ORD-1042", "eventType": "order.created", "payload": { ... } }
  • Resolved once, at accept. The value is read from the original request and stored on the event, before any payload transform. Every delivery attempt — a retry days later included — sends exactly what arrived. Changing the mapping does not rewrite events already queued.
  • Missing means omitted. If a source holds nothing on a given event, that header is simply left out and the event still delivers. Mark a mapping required only if you want ingress to reject events without it (HTTP 400) — that is an availability decision for the producer, not a delivery detail.
  • Check it against real traffic before saving. The console replays a draft mapping over your last events and shows how many resolved, with example values — so a misspelt field is obvious now, not when the receiver complains. Header and query sources have no history to check (they were never stored); body sources do.
Headers end up in logs
Receivers, proxies and CDNs routinely log request headers — even when they do not log bodies. Do not map body fields that carry personal data, and never map anything that looks like a credential. The console refuses the known credential and transport header names outright (see the reference) and warns on names that merely look like one.

Mapped headers, like the GroupKey header, are not covered by request signing — treat them as context your receiver can use, not as a claim it can verify.

The GroupKey is also your lane key
Use the GroupKey as the partition key and each customer gets its own ordered lane for free — strict per-customer order, parallel across customers.

Optional: a separate partition key

The lane key can equal the GroupKey, or be extracted separately when you want to order by something finer-grained than the customer (e.g. an account within a customer). Both are derived at ingress from the same header / query / body sources.

Related