Direct Integration

If you cannot use the Python or JS SDK, or face specific limitations 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

  1. Generate a UUID for the call share it across before, after, error
  2. POST before immediately (before the LLM call)
  3. POST after on success, error on failure include elapsed_ms and the response part you want weflayr to reuse.

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"}
  }'

SDK example

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
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;
  }
}