Direct Integration
If you cannot use the Python SDK — different language, different AI provider, or strict SDK version constraints — you can POST events directly to the Intake API.
Fully flexible. You define the event schema. Weflayr stores whatever JSON you send, subject only to
event_id and event_type being present. Custom event types are stored and surfaced as-is.
Pattern
- Generate a UUID for the call — share it across
.before,.after,.error - POST
.beforeimmediately (before the LLM call) - POST
.afteron success,.erroron failure — includeelapsed_ms
cURL
# Before
curl -X POST https://api.weflayr.com/$CLIENT_ID/ \
-H "Authorization: Bearer $CLIENT_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event_id": "550e8400-e29b-41d4-a716-446655440000",
"event_type": "custom.inference.before",
"model": "llama-3.1-70b",
"provider": "together-ai",
"tags": {"feature": "translation", "customer": "acme"}
}'
# After (same event_id)
curl -X POST https://api.weflayr.com/$CLIENT_ID/ \
-H "Authorization: Bearer $CLIENT_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event_id": "550e8400-e29b-41d4-a716-446655440000",
"event_type": "custom.inference.after",
"model": "llama-3.1-70b",
"elapsed_ms": 1230.5,
"prompt_tokens": 412,
"completion_tokens": 87,
"tags": {"feature": "translation", "customer": "acme"}
}'
Python (httpx)
import httpx, uuid, time
INTAKE_URL = "https://api.weflayr.com"
CLIENT_ID = "your-client-id"
SECRET = "your-client-secret"
endpoint = f"{INTAKE_URL}/{CLIENT_ID}/"
headers = {"Authorization": f"Bearer {SECRET}"}
def track(model, fn, tags=None):
event_id = str(uuid.uuid4())
base = {"event_id": event_id, "model": model, "tags": tags or {}}
with httpx.Client() as client:
client.post(endpoint, json={**base, "event_type": "my.call.before"}, headers=headers)
start = time.perf_counter()
try:
result = fn()
except Exception as exc:
elapsed = round((time.perf_counter() - start) * 1000, 1)
client.post(endpoint, json={
**base,
"event_type": "my.call.error",
"elapsed_ms": elapsed,
"error_type": type(exc).__name__,
"error_message": str(exc),
}, headers=headers)
raise
elapsed = round((time.perf_counter() - start) * 1000, 1)
client.post(endpoint, json={**base, "event_type": "my.call.after", "elapsed_ms": elapsed}, headers=headers)
return result
JavaScript (fetch)
const INTAKE = 'https://api.weflayr.com';
const CLIENT_ID = 'your-client-id';
const SECRET = 'your-client-secret';
const endpoint = `${INTAKE}/${CLIENT_ID}/`;
const headers = {
'Authorization': `Bearer ${SECRET}`,
'Content-Type': 'application/json',
};
// Fire-and-forget helper
const post = (body) =>
fetch(endpoint, { method: 'POST', headers, body: JSON.stringify(body) })
.catch(() => {});
async function track(model, fn, tags = {}) {
const eventId = crypto.randomUUID();
const base = { event_id: eventId, model, tags };
post({ ...base, event_type: 'my.call.before' });
const start = performance.now();
try {
const result = await fn();
const elapsed_ms = Math.round(performance.now() - start);
post({ ...base, event_type: 'my.call.after', elapsed_ms });
return result;
} catch (err) {
const elapsed_ms = Math.round(performance.now() - start);
post({ ...base, event_type: 'my.call.error', elapsed_ms,
error_type: err.name, error_message: err.message });
throw err;
}
}