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

# Quickstart

> Get started with Greenflash in 10 minutes or less.

export const SignUpButton = ({text = 'Get started', description = 'Get started with Greenflash in minutes. Set up your first product and start capturing conversations.', showDescription = true}) => {
  return <div className="sign-up-cta">
      {showDescription && <div className="sign-up-content">
          <div className="sign-up-description">{description}</div>
        </div>}
      <a href="https://www.greenflash.ai/sign-up" target="_blank" rel="noopener noreferrer" className="sign-up-button">
        <span>{text}</span>
        <svg className="sign-up-arrow" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M6 3L11 8L6 13" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </a>
    </div>;
};

Let's get you up and running with Greenflash. By the end of this guide, you'll have conversations flowing into your dashboard and be ready to start understanding how your users interact with your AI products.

## Create your account

First things first:

<SignUpButton />

Once you've signed up and created an organization, you'll land on your dashboard. That's home base.

## Add your first Product

In Greenflash, **Products** are how you organize everything. Think of them as containers for the AI features you want to track—whether that's a chatbot, an AI agent, an embedded copilot, or an internal tool.

To create one:

1. Click `Create Product` on your dashboard (or find it in the `Products` page in the sidebar)
2. Fill in the details and add any collaborators
3. Hit `Create`

You'll see a **Product ID** on the next screen. This is what ties your conversations and ratings to this Product. Save it somewhere handy, or just come back here later—it's not going anywhere.

<Note>Already been invited to an existing organization? Ask the owner to add you to the Product you'll be working with.</Note>

### Keep dev and prod separate

We recommend creating separate Products for development and production. This way you can test your integration freely without muddying your real data.

## Integrate Greenflash

<Tip>
  **Using Claude Code or another Skills-compatible agent?** Skip the manual setup — the [Greenflash agent skill](/features/agent-skill) can handle the entire integration for you. Run `/greenflash-onboard` and it will install the SDK, create the client, and wire up conversation logging in your codebase automatically.
</Tip>

### API keys

Greenflash uses API keys for authentication. You'll pass yours in the `Authorization` header as a Bearer token.

Head to the `API Keys` page in the sidebar to create one. Once you have it, add it to your environment:

```bash theme={"theme":{"light":"github-light","dark":"vesper"}}
GREENFLASH_API_KEY=your_api_key_here
```

<Note>Our SDKs look for this exact name by default. If you'd rather use a different name, no problem—just pass the key explicitly when initializing.</Note>

### Installing the SDK

We have SDKs for Python and backend JavaScript/TypeScript (Node.js, Bun, Deno—take your pick).

```bash install_typescript.sh theme={"theme":{"light":"github-light","dark":"vesper"}}
pnpm install greenflash
```

```bash install_python.sh theme={"theme":{"light":"github-light","dark":"vesper"}}
pip install --pre greenflash
```

### Initializing the SDK

Here's how to get the client ready. If you've set `GREENFLASH_API_KEY` in your environment, the SDKs will pick it up automatically.

<CodeGroup>
  ```javascript init-greenflash.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  import Greenflash from 'greenflash';

  const client = new Greenflash({
    apiKey: process.env['GREENFLASH_API_KEY'], // This is the default and can be omitted
  });
  ```

  ```python init_async_greenflash.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import os
  from greenflash import AsyncGreenflash

  # we recommend using async requests and NOT waiting for the response to not block your main thread
  client = AsyncGreenflash(
      api_key=os.environ.get("GREENFLASH_API_KEY"),  # This is the default and can be omitted
  )
  ```

  ```python init_sync_greenflash.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import os
  from greenflash import Greenflash

  # if you must use sync requests, you can use the Greenflash class instead of AsyncGreenflash
  client = Greenflash(
      api_key=os.environ.get("GREENFLASH_API_KEY"),  # This is the default and can be omitted
  )
  ```
</CodeGroup>

**Python users:** For better performance, consider installing the aiohttp version:

```bash install_aiohttp.sh theme={"theme":{"light":"github-light","dark":"vesper"}}
pip install greenflash[aiohttp]
```

See the [Python SDK documentation](https://github.com/greenflash-ai/python?tab=readme-ov-file#with-aiohttp) for more details.

### Using the API directly

Prefer raw HTTP? All the same functionality is available at `https://www.greenflash.ai/api/v1`. The SDKs are just wrappers around these endpoints.

## Sending data to Greenflash

Now for the fun part—actually sending data. Here's what you can log:

* **Messages and conversations** between users and your AI
* **User profiles** so you can track individuals over time
* **Organizations** to group users together
* **Ratings** when users give feedback
* **Business events** to tie conversations to real outcomes

### Messages and conversations

This is the core of Greenflash. The `/messages` endpoint lets you log what your users and AI are saying to each other.

<Warning>
  Both the TypeScript and Python SDKs support async requests. **Use them.** You don't want to block your main thread waiting for logging calls to complete—your users are waiting for their AI response.
</Warning>

You can send messages one at a time as they happen, or batch up a whole conversation in a single request. Whatever fits your architecture.

<Note>
  **Conversation identifiers:** Use `externalConversationId` with your own IDs (recommended for most integrations). Greenflash returns a `conversationId` in the response—you can use either for subsequent requests. Always include `productId` when starting a new conversation.
</Note>

#### Simple chat messages

For straightforward chat apps, just use the `role` field to mark who said what: `user`, `assistant`, or `system`.

<CodeGroup>
  ```javascript simple-messages-sdk.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  const params = {
    externalUserId: 'YOUR_USER_ID',
    externalConversationId: 'YOUR_CONVERSATION_ID',
    productId: 'YOUR_PRODUCT_ID',
    model: 'gpt-4-turbo',  // Optional: track which AI model was used
    messages: [
      { role: 'user', content: 'What is the weather like today?' },
      { role: 'assistant', content: 'I can help you check the weather. What city are you in?' }
    ],
  };

  // not recommended to await the response if it would block your LLM's response to the user
  client.messages.create(params);
  ```

  ```python simple_messages_sdk.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import asyncio

  async def main() -> None:
    # awaiting is required for async support in python
    create_response = await client.messages.create(
        external_user_id="YOUR_USER_ID",
        external_conversation_id="YOUR_CONVERSATION_ID",
        product_id="YOUR_PRODUCT_ID",
        model="gpt-4-turbo",  # Optional: track which AI model was used
        messages=[
            {
                "role": "user",
                "content": "What is the weather like today?",
            },
            {
                "role": "assistant",
                "content": "I can help you check the weather. What city are you in?",
            }
        ],
    )

  asyncio.run(main())
  ```

  ```javascript simple-messages-api.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  const apiKey = process.env.GREENFLASH_API_KEY;

  const messageData = {
    productId: 'YOUR_PRODUCT_ID',
    externalConversationId: 'YOUR_CONVERSATION_ID',
    externalUserId: 'YOUR_USER_ID',
    model: 'gpt-4-turbo',  // Optional: track which AI model was used
    messages: [
      {
        role: 'user',
        content: 'What is the weather like today?'
      },
      {
        role: 'assistant',
        content: 'I can help you check the weather. What city are you in?'
      }
    ]
  }

  const response = fetch('https://www.greenflash.ai/api/v1/messages', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(messageData)
  });
  ```

  ```python simple_messages_api.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import os
  import requests

  api_key = os.environ.get('GREENFLASH_API_KEY')

  message_data = {
      'productId': 'YOUR_PRODUCT_ID',
      'externalConversationId': 'YOUR_CONVERSATION_ID',
      'externalUserId': 'YOUR_USER_ID',
      'model': 'gpt-4-turbo',  # Optional: track which AI model was used
      'messages': [
          {
              'role': 'user',
              'content': 'What is the weather like today?'
          },
          {
              'role': 'assistant',
              'content': 'I can help you check the weather. What city are you in?'
          }
      ]
  }

  response = requests.post(
      'https://www.greenflash.ai/api/v1/messages',
      headers={
          'Authorization': f'Bearer {api_key}',
          'Content-Type': 'application/json'
      },
      json=message_data
  )
  ```

  ```bash simple-messages-api.sh theme={"theme":{"light":"github-light","dark":"vesper"}}
  curl -X POST 'https://www.greenflash.ai/api/v1/messages' \
    -H "Authorization: Bearer $GREENFLASH_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
      "productId": "YOUR_PRODUCT_ID",
      "externalConversationId": "YOUR_CONVERSATION_ID",
      "externalUserId": "YOUR_USER_ID",
      "model": "gpt-4-turbo",
      "messages": [
        {
          "role": "user",
          "content": "What is the weather like today?"
        },
        {
          "role": "assistant",
          "content": "I can help you check the weather. What city are you in?"
        }
      ]
    }'
  ```
</CodeGroup>

<Note>
  **About billing:** Message `content` counts toward your token limit at the full rate. System prompts and template variables count at 50%. All other data (tool calls, agentic messages, etc.) does not count.
</Note>

#### Agentic workflows

Building something more sophisticated? AI agents with tool use, chain-of-thought reasoning, or complex message threading? The `messageType` field gives you fine-grained control.

<CodeGroup>
  ```javascript agentic-messages-api.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  const apiKey = process.env.GREENFLASH_API_KEY;

  const agenticData = {
    productId: 'YOUR_PRODUCT_ID',
    externalConversationId: 'YOUR_CONVERSATION_ID',
    externalUserId: 'YOUR_USER_ID',
    messages: [
      {
        messageType: 'user_message',
        content: 'What is the weather in San Francisco?',
        externalMessageId: 'user_msg_1'
      },
      {
        messageType: 'thought',
        content: 'I need to call the weather API to get current conditions for San Francisco.',
        parentExternalMessageId: 'user_msg_1'
      },
      {
        messageType: 'tool_call',
        toolName: 'get_weather',
        input: { 'city': 'San Francisco', 'units': 'fahrenheit' },
        content: 'Calling weather API for San Francisco',
        externalMessageId: 'tool_call_1'
      },
      {
        messageType: 'observation',
        output: { 'temperature': 68, 'condition': 'sunny', 'humidity': 65 },
        content: 'Weather data retrieved successfully',
        parentExternalMessageId: 'tool_call_1'
      },
      {
        messageType: 'final_response',
        content: 'The weather in San Francisco is currently 68°F and sunny with 65% humidity.',
        context: 'Retrieved from weather API at 2024-01-15T10:30:00Z'
      }
    ]
  }

  const response = fetch('https://www.greenflash.ai/api/v1/messages', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(agenticData)
  });
  ```

  ```python agentic_messages_api.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import os
  import requests

  api_key = os.environ.get('GREENFLASH_API_KEY')

  agentic_data = {
      'productId': 'YOUR_PRODUCT_ID',
      'externalConversationId': 'YOUR_CONVERSATION_ID',
      'externalUserId': 'YOUR_USER_ID',
      'messages': [
          {
              'messageType': 'user_message',
              'content': 'What is the weather in San Francisco?',
              'externalMessageId': 'user_msg_1'
          },
          {
              'messageType': 'thought',
              'content': 'I need to call the weather API to get current conditions for San Francisco.',
              'parentExternalMessageId': 'user_msg_1'
          },
          {
              'messageType': 'tool_call',
              'toolName': 'get_weather',
              'input': {'city': 'San Francisco', 'units': 'fahrenheit'},
              'content': 'Calling weather API for San Francisco',
              'externalMessageId': 'tool_call_1'
          },
          {
              'messageType': 'observation',
              'output': {'temperature': 68, 'condition': 'sunny', 'humidity': 65},
              'content': 'Weather data retrieved successfully',
              'parentExternalMessageId': 'tool_call_1'
          },
          {
              'messageType': 'final_response',
              'content': 'The weather in San Francisco is currently 68°F and sunny with 65% humidity.',
              'context': 'Retrieved from weather API at 2024-01-15T10:30:00Z'
          }
      ]
  }

  response = requests.post(
      'https://www.greenflash.ai/api/v1/messages',
      headers={
          'Authorization': f'Bearer {api_key}',
          'Content-Type': 'application/json'
      },
      json=agentic_data
  )
  ```

  ```bash agentic-messages-api.sh theme={"theme":{"light":"github-light","dark":"vesper"}}
  curl -X POST 'https://www.greenflash.ai/api/v1/messages' \
    -H "Authorization: Bearer $GREENFLASH_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
      "productId": "YOUR_PRODUCT_ID",
      "externalConversationId": "YOUR_CONVERSATION_ID",
      "externalUserId": "YOUR_USER_ID",
      "messages": [
        {
          "messageType": "user_message",
          "content": "What is the weather in San Francisco?",
          "externalMessageId": "user_msg_1"
        },
        {
          "messageType": "thought",
          "content": "I need to call the weather API to get current conditions for San Francisco.",
          "parentExternalMessageId": "user_msg_1"
        },
        {
          "messageType": "tool_call",
          "toolName": "get_weather",
          "input": {"city": "San Francisco", "units": "fahrenheit"},
          "content": "Calling weather API for San Francisco",
          "externalMessageId": "tool_call_1"
        },
        {
          "messageType": "observation",
          "output": {"temperature": 68, "condition": "sunny", "humidity": 65},
          "content": "Weather data retrieved successfully",
          "parentExternalMessageId": "tool_call_1"
        },
        {
          "messageType": "final_response",
          "content": "The weather in San Francisco is currently 68°F and sunny with 65% humidity.",
          "context": "Retrieved from weather API at 2024-01-15T10:30:00Z"
        }
      ]
    }'
  ```
</CodeGroup>

Here's what's happening in that example:

* **Message Types**: Different `messageType` values let you distinguish thoughts, tool calls, observations, and final responses
* **Tool Integration**: Track what tools your agent called with `toolName`, `input`, and `output`
* **Message Threading**: Use `parentExternalMessageId` to show how messages relate to each other
* **Context Tracking**: Add extra context about where data came from or when things happened
* **External IDs**: Your own identifiers for referencing specific messages later

Check out the full [messages API reference](https://docs.greenflash.ai/api-reference/log-conversations-and-messages) for everything you can do—system prompts, metadata, custom timestamps, and more.

<Tip>
  **Handling high volume?** Both `/messages` and `/events` support sampling via `sampleRate` (0-1) and `forceSample`. Log a percentage of requests to control costs while ensuring critical data always gets through. See the [Sampling documentation](/features/sampling) for details.
</Tip>

#### Automatic message de-duplication

If you include `externalMessageId` on your messages, Greenflash automatically de-duplicates them within a conversation. This means you can safely resend a batch of messages with new messages appended to the end — previously ingested messages will be skipped and only new ones will be inserted and analyzed.

This is useful when you're sending an entire conversation history on each request rather than just the latest turn. Each message in the response includes a `status` field (`"created"` or `"deduplicated"`) so you know exactly what happened.

```json theme={"theme":{"light":"github-light","dark":"vesper"}}
// First request: sends 2 messages
{
  "messages": [
    { "externalMessageId": "msg-1", "role": "user", "content": "Hello" },
    { "externalMessageId": "msg-2", "role": "assistant", "content": "Hi!" }
  ]
}

// Second request: resends the same 2 + adds 1 new
{
  "messages": [
    { "externalMessageId": "msg-1", "role": "user", "content": "Hello" },       // deduplicated
    { "externalMessageId": "msg-2", "role": "assistant", "content": "Hi!" },     // deduplicated
    { "externalMessageId": "msg-3", "role": "user", "content": "How are you?" }  // created
  ]
}
```

<Note>
  Messages without `externalMessageId` are always inserted — de-duplication only applies when an external ID is provided.
</Note>

### Identifying users

When someone logs into your product, call the `/users` endpoint with a stable identifier. This lets Greenflash connect all their conversations over time.

<Note>Privacy-conscious? Hash the user ID before sending it. What matters is consistency—the same user should always have the same ID.</Note>

Only `externalUserId` is required, but the more you send (name, email, etc.), the easier it'll be to find specific users in the dashboard.

You can also link users to organizations by passing `externalOrganizationId`. If that org doesn't exist yet, we'll create it automatically.

<CodeGroup>
  ```javascript users-sdk.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  const params = {
    externalUserId: 'YOUR_USER_ID',  // required
    externalOrganizationId: 'YOUR_ORGANIZATION_ID',  // optional
    name: 'John Doe',
    email: 'john.doe@example.com',
    phone: '123-456-7890',
    properties: {
      'custom_field': 'custom_value'
    }
  };

  client.users.create(params);
  ```

  ```python users_sdk.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import asyncio

  async def main() -> None:
    response = await client.users.create(
        external_user_id="YOUR_USER_ID",  # required
        external_organization_id="YOUR_ORGANIZATION_ID",  # optional
        name="John Doe",
        email="john.doe@example.com",
        phone="123-456-7890",
        properties={
            "custom_field": "custom_value"
        }
    )

  asyncio.run(main())
  ```

  ```javascript users-api.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  const apiKey = process.env.GREENFLASH_API_KEY;

  const userData = {
    externalUserId: 'YOUR_USER_ID',  // required
    externalOrganizationId: 'YOUR_ORGANIZATION_ID',  // optional
    name: 'John Doe',
    email: 'john.doe@example.com',
    phone: '123-456-7890',
    properties: {
      'custom_field': 'custom_value'
    }
  }

  const response = await fetch('https://www.greenflash.ai/api/v1/users', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(userData)
  });
  ```

  ```python users_api.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import os
  import requests

  api_key = os.environ.get('GREENFLASH_API_KEY')

  user_data = {
      'externalUserId': 'YOUR_USER_ID',  # required
      'externalOrganizationId': 'YOUR_ORGANIZATION_ID',  # optional
      'name': 'John Doe',
      'email': 'john.doe@example.com',
      'phone': '123-456-7890',
      'properties': {
          'custom_field': 'custom_value'
      }
  }

  response = requests.post(
      'https://www.greenflash.ai/api/v1/users',
      headers={
          'Authorization': f'Bearer {api_key}',
          'Content-Type': 'application/json'
      },
      json=user_data
  )
  ```

  ```bash users.sh theme={"theme":{"light":"github-light","dark":"vesper"}}
  curl -X POST 'https://www.greenflash.ai/api/v1/users' \
    -H "Authorization: Bearer $GREENFLASH_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
      "externalUserId": "YOUR_USER_ID",
      "externalOrganizationId": "YOUR_ORGANIZATION_ID",
      "name": "John Doe",
      "email": "john.doe@example.com",
      "phone": "123-456-7890",
      "properties": {
        "custom_field": "custom_value"
      }
    }'
  ```
</CodeGroup>

See the full [users API reference](https://docs.greenflash.ai/api-reference/create-or-update-a-user-profile) for all the fields you can send.

### Identifying organizations

Want to group users by company or team? The `/organizations` endpoint has you covered.

<Note>You can also create organizations implicitly by passing `externalOrganizationId` when creating users. If the org doesn't exist, it gets created automatically.</Note>

Just `externalOrganizationId` is required. Throw anything else you want into `properties`.

<CodeGroup>
  ```javascript organizations-sdk.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  const params = {
    externalOrganizationId: 'YOUR_ORGANIZATION_ID',  // required
    properties: {
      'custom_field': 'custom_value'
    }
  };

  client.organizations.create(params);
  ```

  ```python organizations_sdk.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import asyncio

  async def main() -> None:
    response = await client.organizations.create(
        external_organization_id="YOUR_ORGANIZATION_ID",  # required
        properties={
            "custom_field": "custom_value"
        }
    )

  asyncio.run(main())
  ```

  ```javascript organizations-api.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  const apiKey = process.env.GREENFLASH_API_KEY;

  const organizationData = {
    externalOrganizationId: 'YOUR_ORGANIZATION_ID',  // required
    properties: {
      'custom_field': 'custom_value'
    }
  }

  const response = await fetch('https://www.greenflash.ai/api/v1/organizations', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(organizationData)
  });
  ```

  ```python organizations_api.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import os
  import requests

  api_key = os.environ.get('GREENFLASH_API_KEY')

  organization_data = {
      'externalOrganizationId': 'YOUR_ORGANIZATION_ID',  # required
      'properties': {
          'custom_field': 'custom_value'
      }
  }

  response = requests.post(
      'https://www.greenflash.ai/api/v1/organizations',
      headers={
          'Authorization': f'Bearer {api_key}',
          'Content-Type': 'application/json'
      },
      json=organization_data
  )
  ```

  ```bash organizations.sh theme={"theme":{"light":"github-light","dark":"vesper"}}
  curl -X POST 'https://www.greenflash.ai/api/v1/organizations' \
    -H "Authorization: Bearer $GREENFLASH_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
      "externalOrganizationId": "YOUR_ORGANIZATION_ID",
      "properties": {
        "custom_field": "custom_value"
      }
    }'
  ```
</CodeGroup>

See the full [organizations API reference](https://docs.greenflash.ai/api-reference/create-or-update-an-organization) for more options.

### Ratings

When users give feedback—thumbs up, star ratings, whatever you're collecting—send it to the `/ratings` endpoint. You can rate a specific message or an entire conversation.

<CodeGroup>
  ```javascript ratings-sdk.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  const params = {
    externalConversationId: 'YOUR_CONVERSATION_ID',
    rating: 4,
    ratingMin: 1,
    ratingMax: 5,
    feedback: 'Very helpful response!'  // optional
  };

  client.ratings.create(params);
  ```

  ```python ratings_sdk.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import asyncio

  async def main() -> None:
    response = await client.ratings.create(
        external_conversation_id="YOUR_CONVERSATION_ID",
        rating=4,
        rating_min=1,
        rating_max=5,
        feedback="Very helpful response!"  # optional
    )

  asyncio.run(main())
  ```

  ```javascript ratings.js theme={"theme":{"light":"github-light","dark":"vesper"}}
  const apiKey = process.env.GREENFLASH_API_KEY;

  const ratingData = {
    externalConversationId: 'YOUR_CONVERSATION_ID',
    rating: 4,
    ratingMin: 1,
    ratingMax: 5,
    feedback: 'Very helpful response!'  // optional
  }

  const response = await fetch('https://www.greenflash.ai/api/v1/ratings', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(ratingData)
  });
  ```

  ```python ratings.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import os
  import requests

  api_key = os.environ.get('GREENFLASH_API_KEY')

  rating_data = {
      'externalConversationId': 'YOUR_CONVERSATION_ID',
      'rating': 4,
      'ratingMin': 1,
      'ratingMax': 5,
      'feedback': 'Very helpful response!'  # optional
  }

  response = requests.post(
      'https://www.greenflash.ai/api/v1/ratings',
      headers={
          'Authorization': f'Bearer {api_key}',
          'Content-Type': 'application/json'
      },
      json=rating_data
  )
  ```

  ```bash ratings.sh theme={"theme":{"light":"github-light","dark":"vesper"}}
  curl -X POST 'https://www.greenflash.ai/api/v1/ratings' \
    -H "Authorization: Bearer $GREENFLASH_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
      "externalConversationId": "YOUR_CONVERSATION_ID",
      "rating": 4,
      "ratingMin": 1,
      "ratingMax": 5,
      "feedback": "Very helpful response!"
    }'
  ```
</CodeGroup>

See the full [ratings API reference](https://docs.greenflash.ai/api-reference/log-conversation-or-message-ratings) for all the ways you can capture feedback.

### Business events

This is where things get interesting. The `/events` endpoint lets you tie conversations to real business outcomes—purchases, signups, feature adoption, whatever matters to you.

Did a user convert after chatting with your AI? Log it. Now you can actually measure ROI.

<CodeGroup>
  ```javascript events-sdk.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
  const params = {
    eventType: 'purchase',
    productId: 'YOUR_PRODUCT_ID',
    externalUserId: 'YOUR_USER_ID',
    externalConversationId: 'YOUR_CONVERSATION_ID',  // optional
    influence: 'positive',  // optional: 'positive', 'negative', or 'neutral'
    value: '99.99',
    valueType: 'currency',
    properties: {  // optional
      'product_name': 'Premium Plan',
      'subscription_length': '12 months'
    }
  };

  client.events.create(params);
  ```

  ```python events_sdk.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import asyncio

  async def main() -> None:
    response = await client.events.create(
        event_type="purchase",
        product_id="YOUR_PRODUCT_ID",
        external_user_id="YOUR_USER_ID",
        external_conversation_id="YOUR_CONVERSATION_ID",  # optional
        influence="positive",  # optional: 'positive', 'negative', or 'neutral'
        value="99.99",
        value_type="currency",
        properties={  # optional
            "product_name": "Premium Plan",
            "subscription_length": "12 months"
        }
    )

  asyncio.run(main())
  ```

  ```javascript events.js theme={"theme":{"light":"github-light","dark":"vesper"}}
  const apiKey = process.env.GREENFLASH_API_KEY;

  const eventData = {
    eventType: 'purchase',
    productId: 'YOUR_PRODUCT_ID',
    externalUserId: 'YOUR_USER_ID',
    externalConversationId: 'YOUR_CONVERSATION_ID',  // optional
    influence: 'positive',  // optional: 'positive', 'negative', or 'neutral'
    value: '99.99',
    valueType: 'currency',
    properties: {  // optional
      'product_name': 'Premium Plan',
      'subscription_length': '12 months'
    }
  }

  const response = await fetch('https://www.greenflash.ai/api/v1/events', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(eventData)
  });
  ```

  ```python events.py theme={"theme":{"light":"github-light","dark":"vesper"}}
  import os
  import requests

  api_key = os.environ.get('GREENFLASH_API_KEY')

  event_data = {
      'eventType': 'purchase',
      'productId': 'YOUR_PRODUCT_ID',
      'externalUserId': 'YOUR_USER_ID',
      'externalConversationId': 'YOUR_CONVERSATION_ID',  # optional
      'influence': 'positive',  # optional: 'positive', 'negative', or 'neutral'
      'value': '99.99',
      'valueType': 'currency',
      'properties': {  # optional
          'product_name': 'Premium Plan',
          'subscription_length': '12 months'
      }
  }

  response = requests.post(
      'https://www.greenflash.ai/api/v1/events',
      headers={
          'Authorization': f'Bearer {api_key}',
          'Content-Type': 'application/json'
      },
      json=event_data
  )
  ```

  ```bash events.sh theme={"theme":{"light":"github-light","dark":"vesper"}}
  curl -X POST 'https://www.greenflash.ai/api/v1/events' \
    -H "Authorization: Bearer $GREENFLASH_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
      "eventType": "purchase",
      "productId": "YOUR_PRODUCT_ID",
      "externalUserId": "YOUR_USER_ID",
      "externalConversationId": "YOUR_CONVERSATION_ID",
      "influence": "positive",
      "value": "99.99",
      "valueType": "currency",
      "properties": {
        "product_name": "Premium Plan",
        "subscription_length": "12 months"
      }
    }'
  ```
</CodeGroup>

See the full [events API reference](https://docs.greenflash.ai/api-reference/log-business-conversion-events) for all the ways you can track business outcomes.
