OpenAI — Example Configuration
A complete configuration that monitors all supported OpenAI API routes.
Full coverage
const { weflayr_setup, weflayr_instrument } = require('weflayr');
weflayr_setup({
intake_url: process.env.WEFLAYR_INTAKE_URL,
client_id: process.env.WEFLAYR_CLIENT_ID,
client_secret: process.env.WEFLAYR_CLIENT_SECRET,
methods: [
{ call: 'chat.completions.create' },
{ call: 'completions.create' },
{ call: 'embeddings.create' },
{ call: 'responses.create' },
{
call: 'audio.speech.create',
middleware: (args) => ({ char_count: args?.input?.length ?? 0 }),
},
{ call: 'audio.transcriptions.create' },
{ call: 'audio.translations.create' },
],
});
const OpenAI = require('openai');
const client = weflayr_instrument(new OpenAI({ apiKey: process.env.OPENAI_API_KEY }));
import os
from openai import OpenAI
from weflayr import weflayr_setup, weflayr_instrument
weflayr_setup({
"intake_url": os.environ["WEFLAYR_INTAKE_URL"],
"client_id": os.environ["WEFLAYR_CLIENT_ID"],
"client_secret": os.environ["WEFLAYR_CLIENT_SECRET"],
"methods": [
{"call": "chat.completions.create"},
{"call": "completions.create"},
{"call": "embeddings.create"},
{"call": "responses.create"},
{
"call": "audio.speech.create",
"middleware": lambda args, resp: {"char_count": len(args.get("input") or "")},
},
{"call": "audio.transcriptions.create"},
{"call": "audio.translations.create"},
],
})
client = weflayr_instrument(OpenAI(api_key=os.environ["OPENAI_API_KEY"]))
Redacting sensitive content
Pass an ignore_fields function to strip message content from events while keeping metadata. The function receives a deep clone of the payload — the original args forwarded to OpenAI are never affected.
weflayr_setup({
intake_url: process.env.WEFLAYR_INTAKE_URL,
client_id: process.env.WEFLAYR_CLIENT_ID,
client_secret: process.env.WEFLAYR_CLIENT_SECRET,
ignore_fields: (data) => {
(data.messages ?? []).forEach(m => delete m.content);
(data.choices ?? []).forEach(c => { if (c.message) delete c.message.content; });
return data;
},
methods: [
{ call: 'chat.completions.create' },
],
});
def ignore_fn(data):
for m in (data.get("messages") or []):
m.pop("content", None)
for c in (data.get("choices") or []):
if c.get("message"):
c["message"].pop("content", None)
return data
weflayr_setup({
"intake_url": os.environ["WEFLAYR_INTAKE_URL"],
"client_id": os.environ["WEFLAYR_CLIENT_ID"],
"client_secret": os.environ["WEFLAYR_CLIENT_SECRET"],
"ignore_fields": ignore_fn,
"methods": [{"call": "chat.completions.create"}],
})
To keep only specific fields, use allow_fields instead:
weflayr_setup({
// ...
allow_fields: (data) => ({
model: data.model,
usage: data.usage,
}),
methods: [{ call: 'chat.completions.create' }],
});
weflayr_setup({
# ...
"allow_fields": lambda data: {"model": data.get("model"), "usage": data.get("usage")},
"methods": [{"call": "chat.completions.create"}],
})
ignore_fields and allow_fields are mutually exclusive — setting both blocks all events.
Tagging calls
Pass __weflayr_tags on any instrumented call to slice analytics by feature, customer, or environment. The field is stripped before the request reaches OpenAI.
await client.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: 'Hello' }],
__weflayr_tags: {
provider: 'openai',
feature: 'support-chat',
customer_id: 'acme-corp',
env: 'production',
},
});
client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
__weflayr_tags={
"provider": "openai",
"feature": "support-chat",
"customer_id": "acme-corp",
"env": "production",
},
)
Image generation
Add images.generate to methods to track gpt-image-1 calls. The model returns token usage (input_tokens, output_tokens) in response.usage, so cost is computed the same way as chat completions.
When the response includes base64-encoded images (b64_json), each image object can be several megabytes. Always strip it via ignore_fields:
const { weflayr_setup, weflayr_instrument } = require('weflayr');
weflayr_setup({
intake_url: process.env.WEFLAYR_INTAKE_URL,
client_id: process.env.WEFLAYR_CLIENT_ID,
client_secret: process.env.WEFLAYR_CLIENT_SECRET,
ignore_fields: (data) => {
(data.data ?? []).forEach(img => delete img.b64_json);
return data;
},
methods: [
{ call: 'images.generate' },
],
});
const OpenAI = require('openai');
const client = weflayr_instrument(new OpenAI({ apiKey: process.env.OPENAI_API_KEY }));
import os
from openai import OpenAI
from weflayr import weflayr_setup, weflayr_instrument
def ignore_b64(data):
for img in (data.get("data") or []):
img.pop("b64_json", None)
return data
weflayr_setup({
"intake_url": os.environ["WEFLAYR_INTAKE_URL"],
"client_id": os.environ["WEFLAYR_CLIENT_ID"],
"client_secret": os.environ["WEFLAYR_CLIENT_SECRET"],
"ignore_fields": ignore_b64,
"methods": [{"call": "images.generate"}],
})
client = weflayr_instrument(OpenAI(api_key=os.environ["OPENAI_API_KEY"]))
The filter is safe to apply unconditionally when the model returns URLs instead of base64, b64_json is absent and the loop is a no-op.
Middleware
Use middleware on a method to attach computed fields to events. The function receives (args, response) — response is null on before events.
{
call: 'audio.speech.create',
middleware: (args, response) => ({
char_count: args?.input?.length ?? 0,
}),
}
{
"call": "audio.speech.create",
"middleware": lambda args, resp: {"char_count": len(args.get("input") or "")},
}
The returned object is merged into the event payload.