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

# Send extra metadata to the gateway

> Group the gateway calls of the same feature, by tagging its code once.

A feature often makes several LLM calls, for example classifying a ticket, then drafting the reply. Wrap the feature's code in `propagate_metadata` / `propagateMetadata` once: every gateway call made inside carries its `feature_name`, and each pass through the scope is one **feature run**, however many calls it makes. You then see, per feature:

* what it costs in total, per run and per customer, its number of runs, and the models it runs on, in [AI cost](https://docs.weflayr.com/product/ai-cost.md) and [AI margin](https://docs.weflayr.com/product/ai-margin.md);
* alerts when its cost per run or its number of runs moves, in [Alerts](https://docs.weflayr.com/product/alerts.md).

```python Python theme={null}
import weflayr
from openai import OpenAI

weflayr.enable_propagate_metadata_to_gateway()  # once, at startup

client = OpenAI(base_url="https://gateway.weflayr.com/v1", api_key="<WEFLAYR_API_KEY>")

with weflayr.propagate_metadata(feature_name="support-ticket"):
    category = client.responses.create(model="claude-opus-5-5", input=f"Classify: {ticket}")
    reply = client.responses.create(model="claude-opus-5-5", input=f"Reply to: {ticket}")
```

```js Node.js theme={null}
const weflayr = require('weflayr');
const OpenAI = require('openai');

weflayr.setup(); // once, at startup, before enablePropagateMetadataToGateway
weflayr.enablePropagateMetadataToGateway();

const client = new OpenAI({
  baseURL: 'https://gateway.weflayr.com/v1',
  apiKey: process.env.WEFLAYR_API_KEY,
});

await weflayr.propagateMetadata({ featureName: 'support-ticket' }, async () => {
  const category = await client.responses.create({ model: 'claude-opus-5-5', input: `Classify: ${ticket}` });
  const reply = await client.responses.create({ model: 'claude-opus-5-5', input: `Reply to: ${ticket}` });
});
```

## One feature run across several services

Each scope starts a new feature run. When one run spans several services, for example an API classifying the ticket and a worker drafting the reply, create the run's id once with `create_feature_run_uuid()` / `createFeatureRunUuid()`, send it along with the work, and pass it as `feature_run_uuid` / `featureRunUuid` to every scope of the run.

```python Python theme={null}
# In your API
feature_run_uuid = weflayr.create_feature_run_uuid()
with weflayr.propagate_metadata(feature_name="support-ticket", feature_run_uuid=feature_run_uuid):
    ...
queue.send({"ticket": ticket, "feature_run_uuid": feature_run_uuid})

# In your worker
with weflayr.propagate_metadata(feature_name="support-ticket", feature_run_uuid=job["feature_run_uuid"]):
    ...
```

```js Node.js theme={null}
// In your API
const featureRunUuid = weflayr.createFeatureRunUuid();
await weflayr.propagateMetadata({ featureName: 'support-ticket', featureRunUuid }, async () => { /* ... */ });
await queue.send({ ticket, featureRunUuid });

// In your worker
await weflayr.propagateMetadata(
  { featureName: 'support-ticket', featureRunUuid: job.featureRunUuid },
  async () => { /* ... */ },
);
```

## Customer and tags

`propagate_metadata` / `propagateMetadata` also takes `customer_name` and `extra_tags`, applied to every call of the scope. Both can instead be set on each request, in its [`weflayr` field](https://docs.weflayr.com/api/gateway/responses#param-weflayr) (`customer_name` and `tags`). When both set a value, the request's wins.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.