Copy every request, as a trace, to your own monitoring tool — add, change and remove destinations.
Every request can be copied, as a trace, to your own monitoring tool: Langfuse, LangSmith, Datadog, an S3 bucket, a webhook and the rest of the destinations. You add a destination once; each request is sent there after it has been settled.
Every destination route is free and takes a management key. The openai SDK has no observability resource, so call the routes with fetch.
const headers = {
Authorization: `Bearer ${process.env.OPENDUNES_MANAGEMENT_KEY}`,
"Content-Type": "application/json",
};
const res = await fetch("https://opendunes.com/v1/observability/destinations", {
method: "POST",
headers,
body: JSON.stringify({
name: "Souk Bot traces",
type: "langfuse",
config: {
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
secretKey: process.env.LANGFUSE_SECRET_KEY,
},
sampling_rate: 1,
privacy_mode: false, // true leaves the input and output out of every trace
}),
});
const { data: destination } = await res.json(); // 201 — secrets come back maskedA missing setting is a 400 naming it, such as config.secretKey is required for langfuse.
The user field and a session_id travel on the trace, and a destination's filter rules can select on them:
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://opendunes.com/v1",
apiKey: process.env.OPENDUNES_API_KEY,
});
const params = {
model: "anthropic/claude-sonnet-5",
messages: [{ role: "user" as const, content: "Wach kayen iPhone 16?" }],
user: "customer-4521",
session_id: "chat-2026-09-24-001", // not in the openai types; it travels as sent
};
await client.chat.completions.create(params as OpenAI.ChatCompletionCreateParamsNonStreaming);const base = "https://opendunes.com/v1/observability/destinations";
await fetch(base, { headers }); // → { data: [ … ], total_count: n }
await fetch(`${base}/${destination.id}`, {
method: "PATCH",
headers,
body: JSON.stringify({ enabled: false }),
});
await fetch(`${base}/${destination.id}`, { method: "DELETE", headers }); // → { deleted: true }