---
title: Overview
description: Fully typed SDKs for Python and JavaScript/TypeScript with unified setup, instrumentation, and advanced guidance.
category: SDKs
---

# Langfuse SDKs

Langfuse offers two SDKs:

- **Python SDK v4** <a href="https://github.com/langfuse/langfuse-python"><img className="inline" alt="GitHub repository langfuse/langfuse-python" src="https://img.shields.io/badge/repo-langfuse--python-blue?style=flat-square&logo=GitHub" /></a> <a href="https://pypi.org/project/langfuse/"><img className="inline" src="https://img.shields.io/pypi/v/langfuse?style=flat-square&label=pypi+langfuse" alt="PyPi langfuse" /></a>
- **JS/TS SDK v5** <a href="https://github.com/langfuse/langfuse-js"><img className="inline" alt="GitHub repository langfuse/langfuse-js" src="https://img.shields.io/badge/repo-langfuse--js-blue?style=flat-square&logo=GitHub" /></a> <a href="https://www.npmjs.com/package/@langfuse/tracing"><img className="inline" src="https://img.shields.io/npm/v/@langfuse/tracing?style=flat-square&label=npm+@langfuse/tracing" alt="NPM @langfuse/tracing" /></a>
- [**Other Languages**](#other-languages) via OpenTelemetry

The Langfuse SDKs are the recommended way to create [custom observations and traces](/docs/observability/sdk/instrumentation#custom-instrumentation) and use the Langfuse [prompt-management](/docs/prompt-management/overview) and [evaluation](/docs/evaluation/overview) features.

**Key benefits**

- Based on [OpenTelemetry](https://opentelemetry.io/), so you can use any OTEL-based instrumentation library for your LLM stack.
- Fully [async requests](/docs/observability/data-model#background-processing), meaning Langfuse adds almost no latency.
- Interoperable with Langfuse [native integrations](/integrations).
- Accurate latency tracking via synchronous timestamps.
- IDs available for downstream use.
- Great DX when nesting observations.
- Cannot break your application: SDK errors are caught and logged.

This section documents tracing related features of the Langfuse SDK. To use the Langfuse SDK for [prompt management](/docs/prompt-management/overview) and [evaluation](/docs/evaluation/overview), visit their respective documentation.

<Details>
<Summary>Requirements for self-hosted Langfuse</Summary>

| SDK                  | Minimum self-hosted server version                                    | Notes                                                      |
| -------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------- |
| Python SDK v3 and v4 | [≥ 3.63.0](https://github.com/langfuse/langfuse/releases/tag/v3.63.0) | Observations API v2 and Metrics API v2 require Langfuse v4 |
| JS/TS SDK v4 and v5  | [≥ 3.63.0](https://github.com/langfuse/langfuse/releases/tag/v3.63.0) | Observations API v2 and Metrics API v2 require Langfuse v4 |

Langfuse Cloud always satisfies these minimums. See the [self-hosted compatibility matrix](/self-hosting/upgrade/versioning#sdk-server) for the full picture per server version, and [Versions & Compatibility](/docs/compatibility) for Langfuse Cloud.

</Details>

<Details>
<Summary>Legacy documentation</Summary>

This documentation is for the latest versions of the Langfuse SDKs.

- Documentation for the legacy Python SDK v3 can be found [here](https://python-sdk-v3.docs-snapshot.langfuse.com/docs/observability/sdk/overview/).
- Documentation for the legacy TypeScript SDK v4 can be found [here](https://js-sdk-v4-docs-snapshot.langfuse.com/docs/observability/sdk/overview/).

</Details>

## Quickstart

Follow the quickstart guide to get the first trace into Langfuse. See the [setup](#setup) section for more details.

<LangTabs items={["Python SDK", "JS/TS SDK"]}>
<Tab title="Python SDK">

**1. Install package:**

```bash
pip install langfuse
```

**2. Add credentials:**

```bash filename=".env"
LANGFUSE_SECRET_KEY = "sk-lf-..."
LANGFUSE_PUBLIC_KEY = "pk-lf-..."
LANGFUSE_BASE_URL = "https://cloud.langfuse.com" # 🇪🇺 EU region
# Other Langfuse data regions include 🇺🇸 US: https://us.cloud.langfuse.com, 🇯🇵 Japan: https://jp.cloud.langfuse.com and ⚕️ HIPAA: https://hipaa.cloud.langfuse.com
```

**3. Instrument your application:**

Instrumentation means adding code that records what’s happening in your application so it can be sent to Langfuse. There are three main ways of instrumenting your code with the Python SDK.

In this example we will use the [context manager](/docs/observability/sdk/instrumentation#context-manager). You can also use the [decorator](/docs/observability/sdk/instrumentation#observe-wrapper) or create [manual observations](/docs/observability/sdk/instrumentation#manual-observations).

```python
from langfuse import get_client

langfuse = get_client()

# Create a span using a context manager
with langfuse.start_as_current_observation(as_type="span", name="process-request") as span:
    # Your processing logic here
    span.update(output="Processing complete")

    # Create a nested generation for an LLM call
    with langfuse.start_as_current_observation(as_type="generation", name="llm-response", model="gpt-3.5-turbo") as generation:
        # Your LLM call logic here
        generation.update(output="Generated response")

# All spans are automatically closed when exiting their context blocks


# Flush events in short-lived applications
langfuse.flush()
```

_[When should I call `langfuse.flush()`?](/docs/observability/data-model#background-processing)_

**4. Run your application and see the trace in Langfuse:**

<Frame>
![First trace in Langfuse](/images/docs/observability/first-trace-python.png)
</Frame>

See the [trace in Langfuse](https://cloud.langfuse.com/project/cloramnkj0002jz088vzn1ja4/traces/b8789d62464dc7627016d9748a48ad0d?observation=5c7c133ec919ded7&timestamp=2025-12-03T14:56:19.285Z).

</Tab>
<Tab title="JS/TS SDK">

**1. Install packages:**

```bash
npm install @langfuse/tracing @langfuse/otel @opentelemetry/sdk-node
```

**2. Set environment variables:**

```bash filename=".env"
LANGFUSE_SECRET_KEY = "sk-lf-..."
LANGFUSE_PUBLIC_KEY = "pk-lf-..."
LANGFUSE_BASE_URL = "https://cloud.langfuse.com" # 🇪🇺 EU region
# Other Langfuse data regions include 🇺🇸 US: https://us.cloud.langfuse.com, 🇯🇵 Japan: https://jp.cloud.langfuse.com and ⚕️ HIPAA: https://hipaa.cloud.langfuse.com
```

**3. Initialize OpenTelemetry:**

Create an `instrumentation.ts` to register the Langfuse span processor so traces reach Langfuse.

```ts filename="instrumentation.ts" /LangfuseSpanProcessor/
import { NodeSDK } from "@opentelemetry/sdk-node";
import { LangfuseSpanProcessor } from "@langfuse/otel";

export const sdk = new NodeSDK({
  spanProcessors: [new LangfuseSpanProcessor()],
});

sdk.start();
```

Import this file at the top of your app's entry point (e.g., `index.ts`).

**4. Instrument your app:**

Instrumentation means adding code that records what’s happening in your application so it can be sent to Langfuse. There are three main ways of instrumenting your code with the TypeScript SDK.

In this example we will use the [context manager](/docs/observability/sdk/instrumentation#context-manager). You can also use the [decorator](/docs/observability/sdk/instrumentation#observe-wrapper) or create [manual observations](/docs/observability/sdk/instrumentation#manual-observations).

```ts filename="index.ts" /startActiveObservation/
import { sdk } from "./instrumentation";
import { startActiveObservation } from "@langfuse/tracing";

async function main() {
  await startActiveObservation("my-first-trace", async (span) => {
    span.update({
      input: "Hello, Langfuse!",
      output: "This is my first trace!",
    });
  });
}

// Shutdown flushes events and is required for short-lived applications
main().finally(() => sdk.shutdown());
```

_[When do I need to use `shutdown()`?](/docs/observability/data-model#background-processing)_

**5. Run your application and see the trace in Langfuse:**

```bash
npx tsx index.ts
```

<Frame>
![First trace in Langfuse](/images/docs/observability/first-trace.png)
</Frame>

See the [trace in Langfuse](https://cloud.langfuse.com/project/cloramnkj0002jz088vzn1ja4/traces/ef10df7b3f9e4a8adc834c18934bace0?timestamp=2025-12-03T14%3A44%3A10.907Z&observation=c71b480595bbe18c).

</Tab>
</LangTabs>

## Setup

This section covers all detail of setting up the Langfuse SDKs. Follow the [Quickstart](#quickstart) guide to create your first trace.

<Steps>

### Install the SDK

<LangTabs items={["Python SDK", "JS/TS SDK"]}>
<Tab title="Python SDK">

Pip install the [Langfuse Python SDK](https://pypi.org/project/langfuse/).

```bash
pip install langfuse
```

</Tab>
<Tab title="JS/TS SDK">

The Langfuse JS/TS SDK is designed to be modular. Install the relevant packages for a full tracing setup:

```bash
npm install @langfuse/tracing @langfuse/otel @opentelemetry/sdk-node
```

Here's an overview of the available packages for the TypeScript SDK:

| Package                                                                        | Description                                                            | Environment  |
| :----------------------------------------------------------------------------- | :--------------------------------------------------------------------- | :----------- |
| [**`@langfuse/core`**](https://www.npmjs.com/package/@langfuse/core)           | Core utilities, types, and logger shared across packages.              | Universal JS |
| [**`@langfuse/client`**](https://www.npmjs.com/package/@langfuse/client)       | Client for features like prompts, datasets, and scores.                | Universal JS |
| [**`@langfuse/browser`**](https://www.npmjs.com/package/@langfuse/browser)     | Browser-safe client for public-key score ingestion.                    | Browser      |
| [**`@langfuse/tracing`**](https://www.npmjs.com/package/@langfuse/tracing)     | Core OpenTelemetry-based tracing functions (`startObservation`, etc.). | Universal JS |
| [**`@langfuse/otel`**](https://www.npmjs.com/package/@langfuse/otel)           | The `LangfuseSpanProcessor` to export traces to Langfuse.              | Node.js ≥ 20 |
| [**`@langfuse/openai`**](https://www.npmjs.com/package/@langfuse/openai)       | Automatic tracing integration for the OpenAI SDK.                      | Universal JS |
| [**`@langfuse/langchain`**](https://www.npmjs.com/package/@langfuse/langchain) | CallbackHandler for tracing LangChain applications.                    | Universal JS |

</Tab>
</LangTabs>

### Configure credentials

To authenticate with Langfuse, add your Langfuse credentials as environment variables. You can get your credentials by signing up for a free [Langfuse Cloud](https://langfuse.com/cloud) account or by [self-hosting Langfuse](https://langfuse.com/self-hosting).

If you are self-hosting Langfuse or using a [data region](/security/data-regions) other than the default (EU, https://cloud.langfuse.com), ensure you configure the base URL argument or the `LANGFUSE_BASE_URL` environment variable.

You can also pass the credentials [directly to the constructor](#client-setup).

```bash filename=".env"
LANGFUSE_SECRET_KEY = "sk-lf-..."
LANGFUSE_PUBLIC_KEY = "pk-lf-..."
LANGFUSE_BASE_URL = "https://cloud.langfuse.com" # 🇪🇺 EU region
# Other Langfuse data regions include 🇺🇸 US: https://us.cloud.langfuse.com, 🇯🇵 Japan: https://jp.cloud.langfuse.com and ⚕️ HIPAA: https://hipaa.cloud.langfuse.com
```

### Initialize OpenTelemetry (JS/TS only)

<LangTabs items={["Python SDK", "JS/TS SDK"]}>
<Tab title="Python SDK">

The Python SDK automatically sets up OpenTelemetry when [initializing the client](#client-setup).

By default, the SDK exports Langfuse + GenAI/LLM spans. To customize this, use `should_export_span` (recommended). `blocked_instrumentation_scopes` still works but is deprecated and planned for removal in a future version.

</Tab>
<Tab title="JS/TS SDK">

The JS/TS SDK's tracing is built on top of OpenTelemetry, so you need to set up the OpenTelemetry SDK. The [`LangfuseSpanProcessor`](https://langfuse-js-git-main-langfuse.vercel.app/classes/_langfuse_otel.LangfuseSpanProcessor.html) is the key component that sends traces to Langfuse.

```ts filename="instrumentation.ts" /LangfuseSpanProcessor/
import { NodeSDK } from "@opentelemetry/sdk-node";
import { LangfuseSpanProcessor } from "@langfuse/otel";

const sdk = new NodeSDK({
  spanProcessors: [new LangfuseSpanProcessor()],
});

sdk.start();
```

By default, the processor exports Langfuse + GenAI/LLM spans. To customize this, use `shouldExportSpan`.

For more options to configure the [`LangfuseSpanProcessor`](https://langfuse-js-git-main-langfuse.vercel.app/classes/_langfuse_otel.LangfuseSpanProcessor.html) such as masking, filtering, and more, see [advanced features](/docs/observability/sdk/advanced-features#filtering-by-instrumentation-scope).

You can learn more about setting up OpenTelemetry in your JS environment [here](https://opentelemetry.io/docs/languages/js/getting-started/nodejs/).

**Next.js users:**

If you are using Next.js, you can register the `LangfuseSpanProcessor` via `registerOTel` from `@vercel/otel` as long as you are on `@vercel/otel` v2 or later. [Earlier versions did not support the OpenTelemetry JS SDK v2](https://github.com/vercel/otel/issues/154) on which the `@langfuse/tracing` and `@langfuse/otel` packages are based; this was resolved in `@vercel/otel` v2. The `NodeSDK` setup described above also works and carries no version requirement.

[See here for a full example for the Vercel AI SDK with NextJS on Vercel](/docs/observability/sdk/typescript/instrumentation#native-instrumentation).

</Tab>
</LangTabs>

### Client Setup [#client-setup]

<LangTabs items={["Python SDK", "JS/TS SDK"]}>
<Tab title="Python SDK">

Initialize the Langfuse client with [`get_client()`](https://python.reference.langfuse.com/langfuse#get_client) to interact with Langfuse. It will automatically use the environment variables you set above.

```python filename="Initialize client"
from langfuse import get_client

langfuse = get_client()

# Verify connection
if langfuse.auth_check():
    print("Langfuse client is authenticated and ready!")
else:
    print("Authentication failed. Please check your credentials and host.")
```

The Langfuse client is a singleton. It can be accessed anywhere in your application using the [`get_client()`](https://python.reference.langfuse.com/langfuse#get_client) function.

<Details>
<Summary>Alternative: Configure via constructor</Summary>

Optionally, you can initialize the client via [`Langfuse()`](https://python.reference.langfuse.com/langfuse#Langfuse) to pass in configuration options (see below). Otherwise, it is created automatically when you call [`get_client()`](https://python.reference.langfuse.com/langfuse#get_client) based on environment variables.

If you create multiple `Langfuse` instances with the same `public_key`, the singleton instance is reused and new arguments are ignored.

```python filename="Initialize client"
from langfuse import Langfuse

langfuse = Langfuse(
  public_key="your-public-key",
  secret_key="your-secret-key",
  base_url="https://cloud.langfuse.com", # 🇪🇺 EU region
  # Other Langfuse data regions include 🇺🇸 US: https://us.cloud.langfuse.com, 🇯🇵 Japan: https://jp.cloud.langfuse.com and ⚕️ HIPAA: https://hipaa.cloud.langfuse.com
)
```

All key configuration options are listed in the [Python SDK reference](https://python.reference.langfuse.com/langfuse#Langfuse).

</Details>

</Tab>
<Tab title="JS/TS SDK">

Initialize the [`LangfuseClient`](https://langfuse-js-git-main-langfuse.vercel.app/classes/_langfuse_client.LangfuseClient.html) to interact with Langfuse. The client will automatically use the environment variables you set above.

```ts filename="client.ts"
import { LangfuseClient } from "@langfuse/client";

const langfuse = new LangfuseClient();
```

<Details>
<Summary>Alternative: Configure via constructor</Summary>

You can also pass the Langfuse credentials directly to the constructor:

```ts filename="client.ts"
import { LangfuseClient } from "@langfuse/client";

const langfuse = new LangfuseClient({
  publicKey: "your-public-key",
  secretKey: "your-secret-key",
  baseUrl: "https://cloud.langfuse.com", // or your self-hosted instance
});
```

</Details>

</Tab>
</LangTabs>

### Use the SDK

With the SDK set up, you can:

- [Instrument your application](/docs/observability/sdk/instrumentation#custom-observations)
- Use [Langfuse Prompt Management](/docs/prompt-management/get-started)
- Run [Experiments](/docs/evaluation/experiments/experiments-via-sdk) and create [Scores](/docs/evaluation/evaluation-methods/custom-scores)
- [Query data](/docs/api-and-data-platform/features/query-via-sdk)

</Steps>

## OpenTelemetry foundation

The Langfuse SDKs are built on top of [OpenTelemetry](https://opentelemetry.io/). This provides:

- **Standardization** with the wider observability ecosystem and tooling.
- **Robust context propagation** so nested spans stay connected, even across async workloads.
- **Attribute propagation** to keep `userId`, `sessionId`, `metadata`, `version`, and `tags` aligned across observations.
- **Ecosystem interoperability** meaning third-party instrumentations automatically appear inside Langfuse traces.

The following diagram shows how Langfuse maps to native OpenTelemetry concepts:

```mermaid
graph TD
    subgraph OTEL_Core_Concepts ["OpenTelemetry"]
        direction LR
        OTEL_Trace["OTel Trace"]
        Root_OTEL_Span["Root OTel Span"]
        Child_OTEL_Span["Child OTel Span"]

        OTEL_Trace -- is defined by --> Root_OTEL_Span
        Root_OTEL_Span -- Hierarchy via <br/> Context Propagation --> Child_OTEL_Span
    end

    subgraph Langfuse_Mapping ["Langfuse"]
        direction LR
        LF_Trace["Langfuse Trace"]
        LF_Observation["Langfuse Observation <br/> (typed as either Span, Generation or Event)"]

        LF_Trace -- Collects one or more --> LF_Observation
    end

    OTEL_Trace -.->|shares ID with | LF_Trace

    Root_OTEL_Span -.->|Mapped to| LF_Observation
    Child_OTEL_Span -.->|Mapped to| LF_Observation

    Root_OTEL_Span -.->|sets default input and output | LF_Trace
    Root_OTEL_Span -.->|can hold trace attributes| LF_Trace
    Child_OTEL_Span -.->|can hold trace attributes| LF_Trace

    classDef otel fill:#D6EAF8,stroke:#3498DB,stroke-width:2px,color:#000;
    classDef langfuse fill:#D5F5E3,stroke:#2ECC71,stroke-width:2px,color:#000;
    class OTEL_Trace,Root_OTEL_Span,Child_OTEL_Span otel;
    class LF_Trace,LF_Observation langfuse;
```

- [**OTel Trace**](https://opentelemetry.io/docs/concepts/observability-primer/#distributed-traces): An OTel-trace represents the entire lifecycle of a request or transaction as it moves through your application and its services. A trace is typically a sequence of operations, like an LLM generating a response followed by a parsing step. The root (first) span created in a sequence defines the OTel trace. OTel traces do not have a start and end time, they are defined by the root span.
- [**OTel Span**](https://opentelemetry.io/docs/concepts/observability-primer/#spans): A span represents a single unit of work or operation within a trace. Spans have a start and end time, a name, and can have attributes (key-value pairs of metadata). Spans can be nested to create a hierarchy, showing parent-child relationships between operations.
- [**Langfuse Trace**](/docs/observability/data-model#observations-and-traces): A Langfuse trace is the set of observations that share a `trace_id`, plus shared attributes such as `session_id` and `user_id`. It shares the same ID as the OTel trace. Trace attributes are set via specific OTel span attributes and can be propagated to all child observations with `propagate_attributes()` (see Attribute Propagation below). Overall input and output belong on the root observation; trace-level input/output is deprecated in Langfuse v4.
- [**Langfuse Observation**](/docs/observability/data-model#observations-and-traces): In Langfuse terminology, an "observation" is a Langfuse-specific representation of an OTel span. It can be a generic span (Langfuse-span), a specialized "generation" (Langfuse-generation), a point-in-time event (Langfuse-event), or [other observation types](/docs/observability/features/observation-types).
  - **Langfuse Span**: A Langfuse-span is a generic OTel span in Langfuse, designed for non-LLM operations.
  - **Langfuse Generation**: A Langfuse-generation is a specialized type of OTel span in Langfuse, designed specifically for Large Language Model (LLM) calls. It includes additional fields like `model`, `model_parameters`, `usage_details` (tokens), and `cost_details`.
  - **Langfuse Event**: A Langfuse-event tracks a point in time action.
  - [**Other observation types**](/docs/observability/features/observation-types): Langfuse supports other observation types such as tool calls, RAG retrieval steps, etc.
- **Context Propagation**: OpenTelemetry automatically handles the propagation of the current trace and span context. This means when you call another function (whether it's also traced by Langfuse, an OTel-instrumented library, or a manually created span), the new span will automatically become a child of the currently active span, forming a correct trace hierarchy.
- [**Attribute Propagation**](/docs/observability/sdk/instrumentation#add-attributes): Certain trace attributes (`user_id`, `session_id`, `metadata`, `version`, `tags`, and request-scoped `environment` in the Python SDK) can be automatically propagated to all child observations using `propagate_attributes()`. This ensures consistent attribute coverage across all observations in a trace. See the [instrumentation docs](/docs/observability/sdk/python/instrumentation#propagating-trace-attributes) for details.

The Langfuse SDKs provide wrappers around OTel spans ([`LangfuseSpan`](https://python.reference.langfuse.com/langfuse#LangfuseSpan), [`LangfuseGeneration`](https://python.reference.langfuse.com/langfuse#LangfuseGeneration)) that offer convenient methods for interacting with Langfuse-specific features like scoring and media handling, while still being native OTel spans under the hood. You can also use these wrapper objects to add Langfuse trace attributes via [`update_trace()`](https://python.reference.langfuse.com/langfuse#LangfuseEvent.update) or use [`propagate_attributes()`](https://python.reference.langfuse.com/langfuse#propagate_attributes) for automatic propagation to all child observations.

## Learn more

- [Instrument your app](/docs/observability/sdk/instrumentation)
- [Advanced features](/docs/observability/sdk/advanced-features)
- [Upgrade path](/docs/observability/sdk/upgrade-path)
- [Troubleshooting & FAQ](/docs/observability/sdk/troubleshooting-and-faq)
- [Python API reference](https://python.reference.langfuse.com)
- [JS/TS API reference](https://js.reference.langfuse.com/)

## Other languages

Langfuse maintains SDKs for Python and JavaScript/TypeScript. For other languages, you can use our [OpenTelemetry endpoint](/integrations/native/opentelemetry) to instrument your application and use the [public API](/docs/api-and-data-platform/features/public-api) to use Langfuse prompt management, evaluation, and querying.

### Instrumentation

To instrument your application, you can send OpenTelemetry spans to the [Langfuse OTel endpoint](/integrations/native/opentelemetry). For this, you can use the following OpenTelemetry SDKs:

- [JetBrains Tracy for Kotlin/Java](https://github.com/JetBrains/tracy)
- [OpenTelemetry Java](https://opentelemetry.io/docs/languages/java/)
- [OpenTelemetry .NET](https://opentelemetry.io/docs/languages/net/)
- [OpenTelemetry Go](https://opentelemetry.io/docs/languages/go/)
- [OpenTelemetry C++](https://opentelemetry.io/docs/languages/cpp/)
- [OpenTelemetry Erlang/Elixir](https://opentelemetry.io/docs/languages/erlang/)
- [OpenTelemetry Ruby](https://opentelemetry.io/docs/languages/ruby/)
- [OpenTelemetry PHP](https://opentelemetry.io/docs/languages/php/)
- [OpenTelemetry Rust](https://opentelemetry.io/docs/languages/rust/)
- [OpenTelemetry Swift](https://opentelemetry.io/docs/languages/swift/)

### Prompt management, evaluation, and querying:

To use other Langfuse features, you can use the [public API](/docs/api-and-data-platform/features/public-api) to integrate Langfuse from any runtime. We also provide a list of community-maintained SDKs [here](https://github.com/langfuse/langfuse-examples?tab=readme-ov-file#community-maintained-sdks).

<!-- agent-instructions -->

---

## Agent Instructions

This page is part of the [Langfuse](https://langfuse.com) documentation, published as plain Markdown for AI agents. Every page is available as Markdown by appending `.md` to its URL, or by sending an `Accept: text/markdown` header. This page: `https://langfuse.com/docs/observability/sdk/overview.md`.

### Querying these docs

If the answer is not on this page, query the documentation instead of guessing:

- **Semantic search** across all Langfuse docs, returning an answer with the relevant pages and excerpts. Ask a specific, self-contained question:

  ```bash
  curl -sG "https://langfuse.com/api/search-docs" --data-urlencode "query=How do I trace a LangGraph agent?"
  ```

- **Index of every page**: <https://langfuse.com/llms.txt>, with per-section indexes [llms-docs.txt](https://langfuse.com/llms-docs.txt), [llms-integrations.txt](https://langfuse.com/llms-integrations.txt), and [llms-self-hosting.txt](https://langfuse.com/llms-self-hosting.txt).

### Before writing Langfuse code

- **Install the [Langfuse Agent Skill](https://langfuse.com/docs/api-and-data-platform/features/agent-skill).** It encodes Langfuse's own best practices for instrumentation, prompt management, and evaluation, and materially improves results.
- **Read [What does a good trace look like?](https://langfuse.com/docs/observability/best-practices.md)** before instrumenting an application.
- **Verify endpoints, parameters, and response fields** against the [API reference](https://api.reference.langfuse.com) instead of inferring them from code examples.
- **Use the [Langfuse CLI](https://langfuse.com/docs/api-and-data-platform/features/cli)** (`npx langfuse-cli api <resource> <action>`) to read or write traces, prompts, datasets, and scores from the terminal.

Found an error in these docs? Please open an issue at <https://github.com/langfuse/langfuse-docs/issues>.
