Skip to main content
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: 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.
Already been invited to an existing organization? Ask the owner to add you to the Product you’ll be working with.

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

Using Claude Code or another Skills-compatible agent? Skip the manual setup — the Greenflash 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.

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:
GREENFLASH_API_KEY=your_api_key_here
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.

Installing the SDK

We have SDKs for Python and backend JavaScript/TypeScript (Node.js, Bun, Deno—take your pick).
install_typescript.sh
pnpm install greenflash
install_python.sh
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.
import Greenflash from 'greenflash';

const client = new Greenflash({
  apiKey: process.env['GREENFLASH_API_KEY'], // This is the default and can be omitted
});
Python users: For better performance, consider installing the aiohttp version:
install_aiohttp.sh
pip install greenflash[aiohttp]
See the Python SDK documentation 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.
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.
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.
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.

Simple chat messages

For straightforward chat apps, just use the role field to mark who said what: user, assistant, or system.
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);
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.

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.
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)
});
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 for everything you can do—system prompts, metadata, custom timestamps, and more.
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 for details.

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.
// 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
  ]
}
Messages without externalMessageId are always inserted — de-duplication only applies when an external ID is provided.

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.
Privacy-conscious? Hash the user ID before sending it. What matters is consistency—the same user should always have the same ID.
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.
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);
See the full users API reference for all the fields you can send.

Identifying organizations

Want to group users by company or team? The /organizations endpoint has you covered.
You can also create organizations implicitly by passing externalOrganizationId when creating users. If the org doesn’t exist, it gets created automatically.
Just externalOrganizationId is required. Throw anything else you want into properties.
const params = {
  externalOrganizationId: 'YOUR_ORGANIZATION_ID',  // required
  properties: {
    'custom_field': 'custom_value'
  }
};

client.organizations.create(params);
See the full organizations API reference 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.
const params = {
  externalConversationId: 'YOUR_CONVERSATION_ID',
  rating: 4,
  ratingMin: 1,
  ratingMax: 5,
  feedback: 'Very helpful response!'  // optional
};

client.ratings.create(params);
See the full ratings API reference 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.
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);
See the full events API reference for all the ways you can track business outcomes.