Documentation

Quick start

Install

terminal
pip install farol-sdk

Run this in your terminal in the same environment where your agent runs. If you're using a virtual environment, make sure it's activated first.

Not sure what a virtual environment is? Skip this and just run pip install farol-sdk directly in your terminal.

πŸ’‘ Using a venv?

python -m venv venv
source venv/bin/activate  # Mac/Linux
venv\Scripts\activate     # Windows
pip install farol-sdk

Get your API key

Copy your API key from your Farol dashboard. You'll find it at the top of the page after signing in.

Get your API key β†’

Wrap your agent

Replace the API key placeholder with your real key from Step 2, and give your agent a name. Everything else can stay as-is.
from farol import trace
from anthropic import Anthropic

client = Anthropic()

@trace(agent_name="my-agent", farol_key="frl_your_key_here")
def my_agent(task, run=None):
    run["topic"] = task

    with run.span("llm_call", type="llm") as span:
        response = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=1024,
            messages=[{"role": "user", "content": task}]
        )
        span.input_tokens = response.usage.input_tokens
        span.output_tokens = response.usage.output_tokens

    return response.content[0].text

Run your agent normally

your agent file
# Just call your function as usual β€” Farol tracks everything automatically
result = my_agent("your task here")

Open your Farol dashboard β€” you'll see the run appear within seconds, with cost, duration, token usage and any errors automatically tracked.

See it in your dashboard

Curious what it looks like? See a live example with real data.

View live demo β†’

Webhook integrations

On Builder plans and above (see pricing), you can add a webhook URL in Account settings. Farol sends a JSON POST when a cost anomaly is detected. Use the steps below to wire common destinations.

Farol sends this JSON payload to your webhook URL when a cost anomaly is detected:

webhook payload
{
  "event": "cost_anomaly",
  "agent": "research-agent",
  "topic": "Weekly data pipeline run",
  "reason": "Cost 3.2Γ— above median baseline (median: $0.000078, actual: $0.000248)",
  "cost_usd": 0.000248,
  "timestamp": "2026-04-12T10:00:00.000Z",
  "dashboard": "https://usefarol.dev/app"
}

Farol expects a 2xx response. Failed deliveries are logged in Account settings.

Discord
  • Open your Discord server and go to Server Settings (click the server name at the top left).
  • Navigate to Integrations β†’ Webhooks β†’ New Webhook.
  • Choose a channel, give it a name, then click Copy Webhook URL.
  • Paste the URL in Farol Settings β†’ Webhook section and click Save.
Google Chat
  • Open Google Chat and go to the Space where you want alerts (Spaces are group channels).
  • Click the Space name at the top β†’ Apps & Integrations β†’ Add webhooks.
  • Give it a name, click Save, then copy the webhook URL.
  • Paste the URL in Farol Settings β†’ Webhook section and click Save.
Telegram

Telegram requires a custom payload format that differs from Farol's standard JSON. The easiest way to connect is via Zapier or Make (see below) β€” create a Catch Hook, then add a step to send a Telegram message using the bot action.

You'll still need a Telegram bot β€” create one with @BotFather to get your token, then use it in Zapier/Make.

Zapier / Make

A Catch Hook is a trigger that gives you a unique URL. When Farol sends data to that URL, your Zap or scenario runs automatically.

  • Create a Catch Hook trigger in Zapier or Make.
  • Copy the webhook URL and paste it in Farol Settings.
  • For example: receive a Farol alert β†’ send a Telegram message, create a Notion entry, or page your team in PagerDuty.

SDK reference

Node.js SDK β€” Install with npm install @usefarol/sdk. Full TypeScript support. See npmjs.com/package/@usefarol/sdk.

The trace decorator wraps your function and passes a run dict for steps, tokens, and timing.

ParameterDescription
agent_name Required. Display name for this agent in the dashboard.
farol_key Required. API key from the dashboard; ties runs to your account.
model Optional. Model label for display. Default "unknown".
cost_per_1k_input_tokens Optional. USD per 1k input (prompt) tokens. Default 0.00025 (Claude Haiku).
cost_per_1k_output_tokens Optional. USD per 1k output (completion) tokens. Default 0.00125 (Claude Haiku).
farol_endpoint Optional. Custom ingest URL. Default points to Farol's hosted endpoint.
capture_io Optional. Set True to store prompt inputs and outputs in the dashboard. Default False. Handle with care β€” prompts may contain sensitive data.
sample_rate Optional. Fraction of successful runs to send (0.0–1.0). Errors always sent. Default 1.0.

Node.js trace() options

OptionDescription
sampleRate Fraction of successful runs to send (0.0–1.0). Errors always sent. Default 1.0.
example β€” custom pricing
# Prices vary by model β€” check your provider's pricing page
@trace(
    agent_name="my-agent",
    farol_key="frl_your_key_here",
    cost_per_1k_input_tokens=0.00025,   # Claude Haiku input price
    cost_per_1k_output_tokens=0.00125,  # Claude Haiku output price
)

Spans β€” tracking steps inside a run

Use run.span() to record individual steps inside your agent β€” tool calls, LLM calls, database lookups, etc.

example β€” tool and LLM spans
with run.span("web_search", type="tool", metadata={"url": url}) as span:
    result = search(url)

with run.span("llm_call", type="llm") as span:
    response = llm.call(prompt)
    span.input_tokens = response.usage.input_tokens
    span.output_tokens = response.usage.output_tokens
    span.input = prompt      # only stored if capture_io=True
    span.output = response.text
FieldDescription
name Required. Label for this span in the trace timeline.
type Optional. "tool" or "llm". Default "tool".
metadata Optional. Dict of extra info shown in the trace panel.
span.input_tokens Token count for input (LLM spans).
span.output_tokens Token count for output (LLM spans).
span.input Prompt text β€” only stored if capture_io=True.
span.output Response text β€” only stored if capture_io=True.
span.error Automatically set if your code raises an error inside the span.

Note: Farol currently supports sequential spans only. Parallel or concurrent spans (e.g. multiple tool calls firing simultaneously) will be recorded but may not display in the correct order in the trace timeline. Full parallel span support is on the roadmap.

Dashboard

The dashboard has four sections:

  • Overview β€” KPI cards (total runs, success rate, avg duration with p95, total cost) and 4 charts. Filter by period (7/30/90 days) and agent.
  • Runs β€” full runs table. Columns: Agent, Topic, Model, Status, Quality, Anomaly, Steps, Duration, Tokens, Cost, Error, Timestamp. Click any row to open the trace timeline showing all spans. Search by topic, filter by agent, export to CSV (Starter+).
  • Agents β€” one card per agent showing total runs, success rate, avg cost, avg duration, last run. Click a card to open a detailed modal with charts and runs filtered to that agent.
  • Alerts β€” cost anomaly alerts and performance regression alerts. Clicking an alert opens the trace for that run.

FAQ

Does Farol store my prompts?

No β€” by default Farol only stores run metadata: timing, tokens, cost, and errors. Prompt inputs and outputs are never stored unless you explicitly set capture_io=True in the @trace decorator. Even with capture_io=True, inputs and outputs are truncated at 50,000 characters.

Is Farol secure?

Yes. All data is encrypted in transit (TLS 1.3) and at rest (AES-256). Prompts are never stored by default β€” only run metadata is tracked. Data is hosted in EU infrastructure (AWS Paris). See our Security page for full details.

How do I track multiple steps in my agent?

Use run.span() as a context manager inside your traced function. Each span appears as a step in the trace timeline. See the Spans section above for full details.

Which frameworks does Farol support?

Any Python code path: the SDK is a decorator. LangChain, CrewAI, custom loopsβ€”wrap the entrypoint and update run with token counts (and optional steps) however your stack exposes them.

What counts as an event for billing?

Each span inside a run counts as one event. A run with 3 spans (e.g. 2 tool calls + 1 LLM call) counts as 3 events. A run with no spans counts as 1 event.

Which Python versions does Farol support?

Farol SDK supports Python 3.8 and above.

How does cost anomaly detection work?

After enough successful runs for the same agent, Farol compares the current cost to a rolling baseline (median and spread). Large jumpsβ€”relative to that baselineβ€”flag as anomalies so you catch bill spikes early.

Can I use Farol without a Farol key?

The decorator runs without a key, but runs are not tied to your dashboard and are not synced under your account. Pass farol_key from the app to attribute runs to you.

How long does Farol store my data?

Run data, traces, and spans are stored for as long as your account is active. There are no automatic expiry windows β€” your data stays available for historical analysis. Deleting your account permanently removes all runs, traces, and associated data. You can delete your account at any time from Account settings.