Skip to content
Docs

From install to your first trace, in about five minutes.

Python, Node.js, Express and NestJS, plus tagging customers, alerts and every setting.

Getting started

Alye records every LLM call your services make: model, tokens, cost, latency, time to first token, errors and retries. Setup takes about five minutes per service.

  1. Create an account and open Setup.
  2. Create an SDK key. Store it as the environment variable ALYE_API_KEY, never in code.
  3. Add the SDK to each service and give it a name, as below.
  4. Run the service. Calls appear on the Overview within a few seconds.

Python

Python 3.10 or newer. Calls through the official OpenAI, Anthropic and Google GenAI clients are recorded automatically, sync and async, streaming included.

pip install alye
export ALYE_API_KEY=alye_live_...

import alye
alye.init(service="support-reply", env="production")

Node.js and TypeScript

Node 20 or newer, ESM or CommonJS, types included. Wrap each client once where you create it.

npm install alye

import * as alye from "alye";
import OpenAI from "openai";

alye.init({ service: "support-reply", env: "production" });
const openai = alye.wrap(new OpenAI());

alye.wrap() works with openai (including Azure and OpenAI-compatible providers), @anthropic-ai/sdk and @google/genai.

Express

Each request becomes one trace with its model calls inside. Requests that made no model calls aren't sent.

import { alyeExpress } from "alye/express";

app.use(alyeExpress({ tags: (req) => ({ customerId: req.header("x-customer-id") }) }));

NestJS

The module starts Alye and adds an interceptor for HTTP, GraphQL and microservice handlers. Call app.enableShutdownHooks() so queued calls are sent on shutdown.

import { AlyeModule } from "alye/nestjs";

@Module({ imports: [AlyeModule.forRoot({ service: "orders-api" })] })
export class AppModule {}

Tag customers

Optional. If your app serves many customers, tag each request with your own customer ID (an account or tenant ID, not a name or email). Tags carry through every await.

# Python
with alye.context(customer_id="northwind", session_id=ticket.id):
    answer = run_agent(ticket)

// Node.js
await alye.context({ customerId: "northwind" }, () => runAgent(ticket));

Group steps into traces

Wrap an agent run or a job in a span, and the model calls inside become its children, so one run shows as a single trace with its steps.

@alye.trace()
def answer_ticket(ticket): ...

with alye.span("retrieve_context", data_source="support-kb"):
    docs = search(query)

Alerts

Alerts are set in the app and checked every minute. Watch spend, the monthly forecast, error rate, p95 latency, number of calls, or a service that stops reporting, for all services, each service, one model or one customer. Owners and admins add email, Slack or Microsoft Teams channels under Settings › Alert channels.

OpenTelemetry

Already sending GenAI spans? Point your exporter at Alye. Use the JSON protocol.

OTEL_EXPORTER_OTLP_ENDPOINT=https://llm-api.onruyl.com/ingest
OTEL_EXPORTER_OTLP_PROTOCOL=http/json
OTEL_EXPORTER_OTLP_HEADERS="x-api-key=alye_live_..."

Settings

Every option can be passed to init() or set as an environment variable.

Environment variableWhat it doesDefault
ALYE_API_KEYYour SDK keyNone: calls print to the console
ALYE_SERVICEOne name per microserviceunknown_service
ALYE_ENVEnvironmentproduction
ALYE_CAPTURE_CONTENTSend prompts and responses (masked)Off
ALYE_REDACT_PIIMask emails, phones, cards and keysOn
ALYE_SAMPLE_RATEShare of traces to keep (failures always kept)1
ALYE_REGIONWhere calls run, for regional pricesDetected for Bedrock and Vertex AI
ALYE_DISABLEDTurn the SDK offOff

Privacy

  • Prompts and responses are not sent unless you turn on content capture.
  • When they are, emails, phone numbers, card numbers and API keys are masked inside your service before anything is sent. Add your own patterns if you need more.
  • Content is cut to a maximum length, 8,000 characters by default.