Integrating Signals with Cost Tracking

Overview

This guide shows you how to integrate cost tracking with Signals in your AI product workflow. By linking these two together, you can:

  • Automatically attribute AI provider costs (OpenAI, Anthropic, etc.) to specific business events
  • Track the true cost of achieving business outcomes (e.g., booking a meeting, sending an email, processing an image or a document)
  • Generate accurate invoices that reflect both usage-based pricing and actual AI costs

Prerequisites

Before you begin, make sure you have:

  • Created an API key in the Paid dashboard
  • Installed the Paid SDK for your language
  • Configured at least one Product with Signals
  • Set up your customer and order records

Note: This feature is currently available in Python and Node.js SDKs.

How It Works

In a typical AI product workflow, your event processing logic might look like this:

1. Receive event (e.g., "prospect replied to email")
2. Process event → make AI calls to generate response
3. Send response
4. Send signal to Paid

To link AI costs with signals, you need to:

  1. Process your AI calls as usual with your AI provider
  2. Send signals to Paid using the Paid SDK

This allows Paid to track your business outcomes and attribute costs accordingly.

Important: Cost Tracking Rules

Only send ONE signal per business outcome

If you send multiple signals for the same business outcome, the costs may be double-counted across multiple signals. The pattern should be:

  • Multiple AI calls + ONE signal = Costs attributed to that signal
  • Multiple signals for same outcome = Send only one signal per business outcome to avoid double-counting

Basic Integration Pattern

Here’s the recommended pattern for integrating cost tracking with signals using the SDK:

1from paid import Paid
2from openai import OpenAI
3
4# Initialize clients
5paid_client = Paid(token="YOUR_PAID_API_KEY")
6openai_client = OpenAI(api_key="<OPENAI_API_KEY>")
7
8def process_event(event, customer_id: str, product_id: str):
9 """
10 Process an event and send signal via SDK
11 """
12 # Step 1: Make AI calls
13 response = openai_client.chat.completions.create(
14 model="gpt-4",
15 messages=[
16 {"role": "system", "content": "You are an AI SDR assistant"},
17 {"role": "user", "content": event.content}
18 ]
19 )
20
21 # Step 2: Your business logic
22 send_response(response.choices[0].message.content)
23
24 # Step 3: Send signal via SDK
25 paid_client.signals.create_signals(
26 signals=[{
27 "event_name": "email_sent",
28 "customer": {"external_customer_id": customer_id},
29 "attribution": {"external_product_id": product_id},
30 "data": {"response_length": len(response.choices[0].message.content)}
31 }]
32 )
33
34# Call your event processor
35process_event(incoming_event, "customer_123", "agent_123")

Real-World Example: AI SDR Product

Let’s walk through a complete example of an AI SDR product that processes email replies and sends signals via the SDK.

1from paid import Paid
2from openai import OpenAI
3
4# Initialize clients
5paid_client = Paid(token="YOUR_PAID_API_KEY")
6openai_client = OpenAI(api_key="<OPENAI_API_KEY>")
7
8def handle_email_reply(email, customer_id: str):
9 """
10 Handle incoming email reply from prospect
11 """
12 # AI call #1: Analyze sentiment
13 sentiment_response = openai_client.chat.completions.create(
14 model="gpt-4",
15 messages=[
16 {"role": "system", "content": "Analyze email sentiment"},
17 {"role": "user", "content": email.body}
18 ]
19 )
20
21 sentiment = sentiment_response.choices[0].message.content
22
23 # AI call #2: Generate response
24 reply_response = openai_client.chat.completions.create(
25 model="gpt-4",
26 messages=[
27 {"role": "system", "content": f"Generate reply. Sentiment: {sentiment}"},
28 {"role": "user", "content": email.body}
29 ]
30 )
31
32 reply_text = reply_response.choices[0].message.content
33
34 # Business logic: Send the email
35 send_email(
36 to=email.sender,
37 subject=f"Re: {email.subject}",
38 body=reply_text
39 )
40
41 # Send signal via SDK
42 paid_client.signals.create_signals(
43 signals=[{
44 "event_name": "email_reply_processed",
45 "customer": {"external_customer_id": customer_id},
46 "attribution": {"external_product_id": "ai_sdr_product"},
47 "data": {
48 "sentiment": sentiment,
49 "reply_length": len(reply_text)
50 },
51 "idempotency_key": f"email_reply_{email.id}"
52 }]
53 )
54
55# Process incoming email
56handle_email_reply(incoming_email, "acme_account_123")

Event Loop Integration

Most AI products run in an event loop, processing events continuously. Here’s how to integrate signal tracking in that pattern:

1from paid import Paid
2from openai import OpenAI
3
4# Initialize clients once
5paid_client = Paid(token="YOUR_PAID_API_KEY")
6openai_client = OpenAI(api_key="<OPENAI_API_KEY>")
7
8def send_signal(event_name: str, customer_id: str, product_id: str, data: dict = None):
9 """Helper function to send signals"""
10 signal = {
11 "event_name": event_name,
12 "customer": {"external_customer_id": customer_id},
13 "attribution": {"external_product_id": product_id}
14 }
15 if data:
16 signal["data"] = data
17
18 paid_client.signals.create_signals(signals=[signal])
19
20def process_event(event, customer_id: str, product_id: str):
21 """Process a single agent event"""
22
23 # Make AI calls as needed
24 if event.type == "email_received":
25 response = openai_client.chat.completions.create(
26 model="gpt-4",
27 messages=[{"role": "user", "content": event.content}]
28 )
29 handle_email_response(response)
30
31 # Send signal
32 send_signal("email_processed", customer_id, product_id)
33
34 elif event.type == "call_completed":
35 # Different AI calls for call processing
36 summary = openai_client.chat.completions.create(
37 model="gpt-4",
38 messages=[{"role": "user", "content": f"Summarize: {event.transcript}"}]
39 )
40
41 send_signal("call_summarized", customer_id, product_id)
42
43# Event loop
44while True:
45 event = get_next_event() # Your event queue
46 if event:
47 process_event(event, "customer_123", "agent_123")

Best Practices

1. One Signal Per Business Outcome

Each business outcome should have one signal:

1from paid import Paid
2
3paid_client = Paid(token="YOUR_PAID_API_KEY")
4
5def send_signal(event_name, customer_id, product_id, data=None):
6 signal = {
7 "event_name": event_name,
8 "customer": {"external_customer_id": customer_id},
9 "attribution": {"external_product_id": product_id},
10 "data": data or {}
11 }
12 paid_client.signals.create_signals(signals=[signal])
13
14# ✅ Good: One signal per outcome
15def book_meeting(prospect, customer_id):
16 # Multiple AI calls OK
17 analyze_calendar(prospect)
18 generate_invite(prospect)
19 send_confirmation(prospect)
20
21 # Single signal for the outcome
22 send_signal("meeting_booked", customer_id, "agent_123")
23
24# ❌ Bad: Multiple signals for same workflow
25def process_workflow(prospect, customer_id):
26 analyze_calendar(prospect)
27 send_signal("calendar_analyzed", customer_id, "agent_123") # Too granular
28
29 generate_invite(prospect)
30 send_signal("invite_generated", customer_id, "agent_123") # Too granular

2. Use Idempotency Keys

Always include idempotency keys to prevent duplicate signals:

1from paid import Paid
2
3paid_client = Paid(token="YOUR_PAID_API_KEY")
4
5signal = {
6 "event_name": "email_sent",
7 "customer": {"external_customer_id": "customer_123"},
8 "attribution": {"external_product_id": "agent_123"},
9 "idempotency_key": f"email_{email_id}_{timestamp}" # Unique per event
10}
11
12paid_client.signals.create_signals(signals=[signal])

Troubleshooting

Signals Not Appearing in Dashboard

If signals aren’t showing up:

  1. Check API key: Verify your API key is valid and has the correct permissions
  2. Check customer exists: The customer ID must exist in your Paid organization
  3. Check product exists: If using attribution, the product must exist
  4. Check response: Verify the API response shows ingested: 1

Duplicate Signals

If you’re seeing duplicate signals:

  • Add idempotencyKey to your signals
  • Use a unique identifier for each business event (e.g., {event_type}_{entity_id}_{timestamp})

Next Steps

Need Help?

Additional Resources