> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# LLM Blueprint

> Theo dõi việc sử dụng token LLM một cách dễ dàng cho việc thanh toán dựa trên mức sử dụng với việc nhập tự động vào Dodo Payments. Hoạt động với AI SDK, OpenAI, Anthropic, OpenRouter, Groq và Google Gemini.

<CardGroup cols={2}>
  <Card title="Quick Start" icon="rocket" href="#quick-start">
    Bắt đầu trong 2 phút với theo dõi token tự động.
  </Card>

  <Card title="API Reference - Events Ingestion" icon="code" href="/api-reference/usage-events/ingest-events">
    Tài liệu API đầy đủ cho việc nhập sự kiện sử dụng.
  </Card>

  <Card title="API Reference - Meters" icon="gauge" href="/api-reference/meters/create-meter">
    Tìm hiểu cách tạo và cấu hình đồng hồ đo để thanh toán.
  </Card>

  <Card title="Usage-Based Billing Guide" icon="arrow-trend-up" href="/developer-resources/usage-based-billing-guide">
    Hướng dẫn toàn diện cho thanh toán theo mức sử dụng với đồng hồ đo.
  </Card>
</CardGroup>

<Info>
  Hoàn hảo cho các ứng dụng SaaS, chatbot AI, công cụ tạo nội dung và bất kỳ ứng dụng hỗ trợ LLM nào cần thanh toán theo mức sử dụng.
</Info>

## Khởi động nhanh

Bắt đầu với việc theo dõi token LLM tự động chỉ trong 2 phút:

<Steps>
  <Step title="Install the SDK">
    Cài đặt Dodo Payments Ingestion Blueprints:

    ```bash theme={null}
    npm install @dodopayments/ingestion-blueprints
    ```
  </Step>

  <Step title="Get Your API Keys">
    Bạn sẽ cần hai khóa API:

    * **Khóa API Dodo Payments**: Lấy từ [Bảng điều khiển Dodo Payments](https://app.dodopayments.com/developer/api-keys)
    * **Khóa API Nhà cung cấp LLM**: Từ AI SDK, OpenAI, Anthropic, Groq, v.v.

    <Tip>
      Lưu trữ khóa API của bạn một cách an toàn trong biến môi trường. Không bao giờ commit chúng vào hệ thống kiểm soát phiên bản.
    </Tip>
  </Step>

  <Step title="Create a Meter in Dodo Payments">
    Trước khi theo dõi mức sử dụng, hãy tạo một đồng hồ đo trong bảng điều khiển Dodo Payments của bạn:

    1. **Đăng nhập** vào [Dodo Payments Dashboard](https://app.dodopayments.com/)
    2. **Điều hướng đến** Products → Meters
    3. **Nhấp** "Create Meter"
    4. **Cấu hình đồng hồ đo** của bạn:
       * **Meter Name**: Chọn tên mô tả (ví dụ: "LLM Token Usage")
       * **Event Name**: Đặt định danh sự kiện độc nhất (ví dụ: `llm.chat_completion`)
       * **Aggregation Type**: Chọn `sum` để cộng các lần xuất token
       * **Over Property**: Chọn thứ cần theo dõi:
         * `inputTokens` - Theo dõi token đầu vào/prompt
         * `outputTokens` - Theo dõi token đầu ra/hoàn thành (bao gồm token suy luận khi áp dụng)
         * `totalTokens` - Theo dõi tổng token đầu vào + đầu ra

    <Info>
      Tên **Event Name** bạn đặt ở đây phải khớp chính xác với những gì bạn truyền vào SDK (phân biệt hoa thường).
    </Info>

    Để biết hướng dẫn chi tiết, xem [Hướng dẫn Thanh toán theo Mức sử dụng](/developer-resources/usage-based-billing-guide).
  </Step>

  <Step title="Track Token Usage">
    Bao bọc client LLM của bạn và bắt đầu theo dõi tự động:

    <CodeGroup>
      ```javascript AI SDK theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import { generateText } from 'ai';
      import { google } from '@ai-sdk/google';

      const llmTracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'aisdk.usage',
      });

      const client = llmTracker.wrap({
        client: { generateText },
        customerId: 'customer_123'
      });

      const response = await client.generateText({
        model: google('gemini-2.0-flash'),
        prompt: 'Hello!',
        maxOutputTokens: 500
      });

      console.log('Usage:', response.usage);
      ```

      ```javascript OpenRouter theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import OpenAI from 'openai';

      const openrouter = new OpenAI({
        baseURL: 'https://openrouter.ai/api/v1',
        apiKey: process.env.OPENROUTER_API_KEY
      });

      const llmTracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'openrouter.usage'
      });

      const client = llmTracker.wrap({
        client: openrouter,
        customerId: 'customer_123'
      });

      const response = await client.chat.completions.create({
        model: 'qwen/qwen3-max',
        messages: [{ role: 'user', content: 'Hello!' }],
        max_tokens: 500
      });

      console.log('Response:', response.choices[0].message.content);
      console.log('Usage:', response.usage);
      ```

      ```javascript OpenAI theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import OpenAI from 'openai';

      // 1. Create your LLM client (normal way)
      const openai = new OpenAI({ 
        apiKey: process.env.OPENAI_API_KEY 
      });

      // 2. Create tracker ONCE at startup
      const tracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode', // Use 'live_mode' for production
        eventName: 'llm.chat_completion' // Match your meter's event name
      });

      // 3. Wrap & use - automatic tracking!
      const client = tracker.wrap({ 
        client: openai, 
        customerId: 'customer_123' 
      });

      // Every API call is now automatically tracked
      const response = await client.chat.completions.create({
        model: 'gpt-4',
        messages: [{ role: 'user', content: 'Hello!' }]
      });

      // ✨ Usage automatically sent to Dodo Payments!
      console.log('Tokens used:', response.usage);
      ```

      ```javascript Anthropic theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import Anthropic from '@anthropic-ai/sdk';

      const anthropic = new Anthropic({ 
        apiKey: process.env.ANTHROPIC_API_KEY 
      });

      const tracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'anthropic.usage'
      });

      const client = tracker.wrap({ 
        client: anthropic, 
        customerId: 'customer_123' 
      });

      const response = await client.messages.create({
        model: 'claude-sonnet-4-0',
        max_tokens: 1024,
        messages: [{ role: 'user', content: 'Hello Claude!' }]
      });

      console.log('Tokens used:', response.usage);
      ```

      ```javascript Groq theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import Groq from 'groq-sdk';

      const groq = new Groq({ 
        apiKey: process.env.GROQ_API_KEY 
      });

      const tracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'groq.usage'
      });

      const client = tracker.wrap({ 
        client: groq, 
        customerId: 'customer_123' 
      });

      const response = await client.chat.completions.create({
        model: 'llama-3.1-8b-instant',
        messages: [{ role: 'user', content: 'Hello!' }]
      });

      console.log('Tokens:', response.usage);
      ```

      ```javascript Google Gemini theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import { GoogleGenAI } from '@google/genai';

      const googleGenai = new GoogleGenAI({
        apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY
      });

      const llmTracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'gemini.usage'
      });

      const client = llmTracker.wrap({
        client: googleGenai,
        customerId: 'customer_123'
      });

      const response = await client.models.generateContent({
        model: 'gemini-2.5-flash',
        contents: 'Why is the sky blue?'
      });

      console.log('Response:', response.text);
      console.log('Usage:', response.usageMetadata);
      ```
    </CodeGroup>

    <Check>
      Hoàn tất! Mỗi cuộc gọi API giờ tự động theo dõi mức sử dụng token và gửi sự kiện đến Dodo Payments để thanh toán.
    </Check>
  </Step>
</Steps>

***

## Cấu hình

### Cấu hình Trình theo dõi

Tạo một trình theo dõi một lần tại khởi động ứng dụng với các tham số yêu cầu sau:

<ParamField path="apiKey" type="string" required>
  Khóa API Dodo Payments của bạn. Lấy từ [trang API Keys](https://app.dodopayments.com/developer/api-keys).

  ```javascript theme={null}
  apiKey: process.env.DODO_PAYMENTS_API_KEY
  ```
</ParamField>

<ParamField path="environment" type="string" required>
  Chế độ môi trường cho bộ theo dõi.

  * `test_mode` - Dùng cho phát triển và thử nghiệm
  * `live_mode` - Dùng cho production

  ```javascript theme={null}
  environment: 'test_mode' // or 'live_mode'
  ```

  <Warning>
    Luôn sử dụng `test_mode` trong quá trình phát triển để tránh ảnh hưởng đến số liệu production.
  </Warning>
</ParamField>

<ParamField path="eventName" type="string" required>
  Tên sự kiện kích hoạt đồng hồ đo của bạn. Phải khớp chính xác với cấu hình meter trên Dodo Payments (phân biệt hoa thường).

  ```javascript theme={null}
  eventName: 'llm.chat_completion'
  ```

  <Info>
    Tên sự kiện này liên kết mức sử dụng bạn theo dõi với đồng hồ đo đúng để tính toán thanh toán.
  </Info>
</ParamField>

### Cấu hình Bọc

Khi bọc client LLM của bạn, cung cấp các tham số sau:

<ParamField path="client" type="object" required>
  Phiên bản client LLM của bạn (OpenAI, Anthropic, Groq, v.v.).

  ```javascript theme={null}
  client: openai
  ```
</ParamField>

<ParamField path="customerId" type="string" required>
  Định danh khách hàng duy nhất cho việc thanh toán. Nên khớp với ID khách hàng trên Dodo Payments.

  ```javascript theme={null}
  customerId: 'customer_123'
  ```

  <Tip>
    Sử dụng ID người dùng hoặc ID khách hàng trong ứng dụng để đảm bảo thanh toán chính xác theo từng khách hàng.
  </Tip>
</ParamField>

<ParamField path="metadata" type="object">
  Dữ liệu bổ sung tùy chọn để đính kèm vào sự kiện theo dõi. Hữu ích cho việc lọc và phân tích.

  ```javascript theme={null}
  metadata: {
    feature: 'chat',
    userTier: 'premium',
    sessionId: 'session_123',
    modelVersion: 'gpt-4'
  }
  ```
</ParamField>

### Ví dụ Cấu hình Hoàn chỉnh

<CodeGroup>
  ```javascript Full Configuration theme={null}
  import { createLLMTracker } from "@dodopayments/ingestion-blueprints";
  import { generateText } from "ai";
  import { google } from "@ai-sdk/google";
  import "dotenv/config";

  async function aiSdkExample() {
    console.log("🤖 AI SDK Simple Usage Example\n");

    try {
      // 1. Create tracker
      const llmTracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY!,
        environment: "test_mode",
        eventName: "your_meter_event_name",
      });

      // 2. Wrap the ai-sdk methods
      const client = llmTracker.wrap({
        client: { generateText },
        customerId: "customer_123",
        metadata: {
          provider: "ai-sdk",
        },
      });

      // 3. Use the wrapped function
      const response = await client.generateText({
        model: google("gemini-2.5-flash"),
        prompt: "Hello, I am a cool guy! Tell me a fun fact.",
        maxOutputTokens: 500,
      });

      console.log(response);
      console.log(response.usage);
      console.log("✅ Automatically tracked for customer\n");
    } catch (error) {
      console.error(error);
    }
  }

  aiSdkExample().catch(console.error);
  ```
</CodeGroup>

<Info>
  **Theo dõi tự động:** SDK tự động theo dõi mức sử dụng token trong nền mà không làm thay đổi phản hồi. Mã của bạn vẫn sạch sẽ và giống như khi sử dụng SDK nhà cung cấp ban đầu.
</Info>

***

## Các Nhà cung cấp Hỗ trợ

LLM Blueprint hoạt động liền mạch với tất cả các nhà cung cấp và tổng hợp LLM lớn:

<AccordionGroup>
  <Accordion title="AI SDK (Vercel)" icon="code">
    Theo dõi mức sử dụng với Vercel AI SDK để hỗ trợ LLM tổng quát.

    <CodeGroup>
      ```javascript AI SDK Integration theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import { generateText } from 'ai';
      import { google } from '@ai-sdk/google';

      const llmTracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'aisdk.usage',
      });

      const client = llmTracker.wrap({
        client: { generateText },
        customerId: 'customer_123',
        metadata: {
          model: 'gemini-2.0-flash',
          feature: 'chat'
        }
      });

      const response = await client.generateText({
        model: google('gemini-2.0-flash'),
        prompt: 'Explain neural networks',
        maxOutputTokens: 500
      });

      console.log('Usage:', response.usage);
      ```
    </CodeGroup>

    **Các chỉ số được theo dõi:**

    * `inputTokens` → `inputTokens`
    * `outputTokens` + `reasoningTokens` → `outputTokens`
    * `totalTokens` → `totalTokens`
    * Tên mô hình

    <Note>
      Khi sử dụng các mô hình có khả năng suy luận qua AI SDK (như Gemini 2.5 Flash của Google với chế độ suy nghĩ), token suy luận tự động được bao gồm trong đếm `outputTokens` để đảm bảo tính toán thanh toán chính xác.
    </Note>
  </Accordion>

  <Accordion title="OpenRouter" icon="route">
    Theo dõi mức sử dụng token trên hơn 200 mô hình thông qua API hợp nhất của OpenRouter.

    <CodeGroup>
      ```javascript OpenRouter Integration theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import OpenAI from 'openai';

      // OpenRouter uses OpenAI-compatible API
      const openrouter = new OpenAI({
        baseURL: 'https://openrouter.ai/api/v1',
        apiKey: process.env.OPENROUTER_API_KEY
      });

      const tracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'openrouter.usage'
      });

      const client = tracker.wrap({ 
        client: openrouter, 
        customerId: 'user_123',
        metadata: { provider: 'openrouter' }
      });

      const response = await client.chat.completions.create({
        model: 'qwen/qwen3-max',
        messages: [{ role: 'user', content: 'What is machine learning?' }],
        max_tokens: 500
      });

      console.log('Response:', response.choices[0].message.content);
      console.log('Usage:', response.usage);
      ```
    </CodeGroup>

    **Các chỉ số được theo dõi:**

    * `prompt_tokens` → `inputTokens`
    * `completion_tokens` → `outputTokens`
    * `total_tokens` → `totalTokens`
    * Tên mô hình

    <Tip>
      OpenRouter cung cấp quyền truy cập vào các mô hình từ OpenAI, Anthropic, Google, Meta và nhiều nhà cung cấp khác thông qua một API duy nhất.
    </Tip>
  </Accordion>

  <Accordion title="OpenAI" icon="robot">
    Theo dõi mức sử dụng token từ các mô hình GPT của OpenAI một cách tự động.

    <CodeGroup>
      ```javascript OpenAI Integration theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import OpenAI from 'openai';

      const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

      const tracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'openai.usage'
      });

      const client = tracker.wrap({ 
        client: openai, 
        customerId: 'user_123' 
      });

      // All OpenAI methods work automatically
      const response = await client.chat.completions.create({
        model: 'gpt-4',
        messages: [{ role: 'user', content: 'Explain quantum computing' }]
      });

      console.log('Total tokens:', response.usage.total_tokens);
      ```
    </CodeGroup>

    **Các chỉ số được theo dõi:**

    * `prompt_tokens` → `inputTokens`
    * `completion_tokens` → `outputTokens`
    * `total_tokens` → `totalTokens`
    * Tên mô hình
  </Accordion>

  <Accordion title="Anthropic Claude" icon="robot">
    Theo dõi mức sử dụng token từ các mô hình Claude của Anthropic.

    <CodeGroup>
      ```javascript Anthropic Integration theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import Anthropic from '@anthropic-ai/sdk';

      const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

      const tracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'anthropic.usage'
      });

      const client = tracker.wrap({ 
        client: anthropic, 
        customerId: 'user_123' 
      });

      const response = await client.messages.create({
        model: 'claude-sonnet-4-0',
        max_tokens: 1024,
        messages: [{ role: 'user', content: 'Explain machine learning' }]
      });

      console.log('Input tokens:', response.usage.input_tokens);
      console.log('Output tokens:', response.usage.output_tokens);
      ```
    </CodeGroup>

    **Các chỉ số được theo dõi:**

    * `input_tokens` → `inputTokens`
    * `output_tokens` → `outputTokens`
    * `totalTokens` được tính toán
    * Tên mô hình
  </Accordion>

  <Accordion title="Groq" icon="gauge-high">
    Theo dõi suy luận LLM siêu nhanh với Groq.

    <CodeGroup>
      ```javascript Groq Integration theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import Groq from 'groq-sdk';

      const groq = new Groq({ apiKey: process.env.GROQ_API_KEY });

      const tracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'groq.usage'
      });

      const client = tracker.wrap({ 
        client: groq, 
        customerId: 'user_123' 
      });

      const response = await client.chat.completions.create({
        model: 'llama-3.1-8b-instant',
        messages: [{ role: 'user', content: 'What is AI?' }]
      });

      console.log('Tokens:', response.usage);
      ```
    </CodeGroup>

    **Các chỉ số được theo dõi:**

    * `prompt_tokens` → `inputTokens`
    * `completion_tokens` → `outputTokens`
    * `total_tokens` → `totalTokens`
    * Tên mô hình
  </Accordion>

  <Accordion title="Google Gemini" icon="sparkles">
    Theo dõi mức sử dụng token từ các mô hình Gemini của Google thông qua Google GenAI SDK.

    <CodeGroup>
      ```javascript Google Gemini Integration theme={null}
      import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
      import { GoogleGenAI } from '@google/genai';

      const googleGenai = new GoogleGenAI({ 
        apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY 
      });

      const tracker = createLLMTracker({
        apiKey: process.env.DODO_PAYMENTS_API_KEY,
        environment: 'test_mode',
        eventName: 'gemini.usage'
      });

      const client = tracker.wrap({ 
        client: googleGenai, 
        customerId: 'user_123' 
      });

      const response = await client.models.generateContent({
        model: 'gemini-2.5-flash',
        contents: 'Explain quantum computing'
      });

      console.log('Response:', response.text);
      console.log('Usage:', response.usageMetadata);
      ```
    </CodeGroup>

    **Các chỉ số được theo dõi:**

    * `promptTokenCount` → `inputTokens`
    * `candidatesTokenCount` + `thoughtsTokenCount` → `outputTokens`
    * `totalTokenCount` → `totalTokens`
    * Phiên bản mô hình

    <Note>
      **Gemini Thinking Mode:** Khi sử dụng các mô hình Gemini có khả năng suy luận/ thinking (như Gemini 2.5 Pro), SDK tự động bao gồm `thoughtsTokenCount` (token suy luận) trong `outputTokens` để phản ánh chính xác toàn bộ chi phí tính toán.
    </Note>
  </Accordion>
</AccordionGroup>

***

## Sử dụng Nâng cao

### Nhiều Nhà cung cấp

Theo dõi việc sử dụng trên các nhà cung cấp LLM khác nhau với các trình theo dõi riêng biệt:

<CodeGroup>
  ```javascript Multiple Provider Setup theme={null}
  import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
  import OpenAI from 'openai';
  import Groq from 'groq-sdk';
  import Anthropic from '@anthropic-ai/sdk';
  import { GoogleGenAI } from '@google/genai';

  // Create separate trackers for different providers
  const openaiTracker = createLLMTracker({
    apiKey: process.env.DODO_PAYMENTS_API_KEY,
    environment: 'live_mode',
    eventName: 'openai.usage'
  });

  const groqTracker = createLLMTracker({
    apiKey: process.env.DODO_PAYMENTS_API_KEY,
    environment: 'live_mode',
    eventName: 'groq.usage'
  });

  const anthropicTracker = createLLMTracker({
    apiKey: process.env.DODO_PAYMENTS_API_KEY,
    environment: 'live_mode',
    eventName: 'anthropic.usage'
  });

  const geminiTracker = createLLMTracker({
    apiKey: process.env.DODO_PAYMENTS_API_KEY,
    environment: 'live_mode',
    eventName: 'gemini.usage'
  });

  const openrouterTracker = createLLMTracker({
    apiKey: process.env.DODO_PAYMENTS_API_KEY,
    environment: 'live_mode',
    eventName: 'openrouter.usage'
  });

  // Initialize clients
  const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
  const groq = new Groq({ apiKey: process.env.GROQ_API_KEY });
  const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
  const googleGenai = new GoogleGenAI({ apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY });
  const openrouter = new OpenAI({ 
    baseURL: 'https://openrouter.ai/api/v1',
    apiKey: process.env.OPENROUTER_API_KEY 
  });

  // Wrap clients
  const trackedOpenAI = openaiTracker.wrap({ client: openai, customerId: 'user_123' });
  const trackedGroq = groqTracker.wrap({ client: groq, customerId: 'user_123' });
  const trackedAnthropic = anthropicTracker.wrap({ client: anthropic, customerId: 'user_123' });
  const trackedGemini = geminiTracker.wrap({ client: googleGenai, customerId: 'user_123' });
  const trackedOpenRouter = openrouterTracker.wrap({ client: openrouter, customerId: 'user_123' });

  // Use whichever provider you need
  const response = await trackedOpenAI.chat.completions.create({...});
  // or
  const geminiResponse = await trackedGemini.models.generateContent({...});
  // or
  const openrouterResponse = await trackedOpenRouter.chat.completions.create({...});
  ```
</CodeGroup>

<Tip>
  Sử dụng tên sự kiện khác nhau cho các nhà cung cấp khác nhau để theo dõi mức sử dụng riêng trong các đồng hồ đo của bạn.
</Tip>

### Tích hợp API Express.js

Ví dụ hoàn chỉnh về việc tích hợp theo dõi LLM vào một API Express.js:

<CodeGroup>
  ```javascript Express.js Server theme={null}
  import express from 'express';
  import { createLLMTracker } from '@dodopayments/ingestion-blueprints';
  import OpenAI from 'openai';

  const app = express();
  app.use(express.json());

  // Initialize OpenAI client
  const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

  // Create tracker once at startup
  const tracker = createLLMTracker({
    apiKey: process.env.DODO_PAYMENTS_API_KEY,
    environment: process.env.NODE_ENV === 'production' ? 'live_mode' : 'test_mode',
    eventName: 'api.chat_completion'
  });

  // Chat endpoint with automatic tracking
  app.post('/api/chat', async (req, res) => {
    try {
      const { message, userId } = req.body;
      
      // Validate input
      if (!message || !userId) {
        return res.status(400).json({ error: 'Missing message or userId' });
      }
      
      // Wrap client for this specific user
      const trackedClient = tracker.wrap({
        client: openai,
        customerId: userId,
        metadata: { 
          endpoint: '/api/chat',
          timestamp: new Date().toISOString()
        }
      });
      
      // Make LLM request - automatically tracked
      const response = await trackedClient.chat.completions.create({
        model: 'gpt-4',
        messages: [{ role: 'user', content: message }],
        temperature: 0.7
      });
      
      const completion = response.choices[0].message.content;
      
      res.json({ 
        message: completion,
        usage: response.usage
      });
    } catch (error) {
      console.error('Chat error:', error);
      res.status(500).json({ error: 'Internal server error' });
    }
  });

  app.listen(3000, () => {
    console.log('Server running on port 3000');
  });
  ```
</CodeGroup>

***

## Những gì được theo dõi

Mỗi cuộc gọi API LLM tự động gửi một sự kiện sử dụng đến Dodo Payments với cấu trúc sau:

<CodeGroup>
  ```json Event Structure theme={null}
  {
    "event_id": "llm_1673123456_abc123",
    "customer_id": "customer_123",
    "event_name": "llm.chat_completion",
    "timestamp": "2024-01-08T10:30:00Z",
    "metadata": {
      "inputTokens": 10,
      "outputTokens": 25,
      "totalTokens": 35,
      "model": "gpt-4",
    }
  }
  ```
</CodeGroup>

### Các Trường Sự kiện

<ParamField path="event_id" type="string">
  Định danh duy nhất cho sự kiện cụ thể này. Được SDK tạo tự động.

  Định dạng: `llm_[timestamp]_[random]`
</ParamField>

<ParamField path="customer_id" type="string">
  ID khách hàng bạn cung cấp khi bao bọc client. Được dùng để thanh toán.
</ParamField>

<ParamField path="event_name" type="string">
  Tên sự kiện kích hoạt đồng hồ đo của bạn. Khớp với cấu hình bộ theo dõi.
</ParamField>

<ParamField path="timestamp" type="string">
  Dấu thời ISO 8601 khi sự kiện xảy ra.
</ParamField>

<ParamField path="metadata" type="object">
  Mức sử dụng token và dữ liệu theo dõi bổ sung:

  * `inputTokens` - Số token đầu vào/prompt đã dùng

  * `outputTokens` - Số token đầu ra/hoàn thành đã dùng (bao gồm token suy luận khi áp dụng)

  * `totalTokens` - Tổng token (đầu vào + đầu ra)

  * `model` - Mô hình LLM được sử dụng (ví dụ: "gpt-4")

  * `provider` - Nhà cung cấp LLM (nếu được bao gồm trong metadata wrapper)

  * Bất kỳ metadata tùy chỉnh nào bạn cung cấp khi bao bọc client

  * `inputTokens` - Số lượng token đầu vào/lời nhắc đã sử dụng

  * `outputTokens` - Số lượng token đầu ra/hoàn thành đã sử dụng (bao gồm token lý do khi có thể)

  * `totalTokens` - Tổng số token (đầu vào + đầu ra)

  * `model` - Mô hình LLM đã sử dụng (ví dụ: "gpt-4")

  * `provider` - Nhà cung cấp LLM (nếu có trong metadata bọc)

  * Bất kỳ metadata tùy chỉnh nào bạn đã cung cấp khi bọc client

  <Note>
    **Token suy luận:** Với các mô hình có khả năng suy luận, `outputTokens` tự động bao gồm cả token hoàn thành và token suy luận.
  </Note>
</ParamField>

<Info>
  Đồng hồ đo Dodo Payments của bạn sử dụng các trường `metadata` (đặc biệt là `inputTokens`, `outputTokens` hoặc `totalTokens`) để tính toán mức sử dụng và thanh toán.
</Info>
