> This page is for version v2 (default).
> For other versions, use one of these documentation indexes:
> - v2 (default): https://docs.paid.ai/v-2/llms.txt
> - v1: https://docs.paid.ai/v-1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.paid.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.paid.ai/_mcp/server.

# Cost attributed signals

> Track the AI cost behind each signal

## Prerequisites

* A [Paid API key](https://app.paid.ai/settings/api-keys).
* The Paid SDK installed in the service that emits signals and makes AI provider calls.
* [Cost traces](/documentation/getting-started/cost-traces) working for the AI call you want to attribute.
* Optional: [customers](https://app.paid.ai/customers) and [products](https://app.paid.ai/products) with stable external IDs for attribution. You can also create them through the [Products API](/api-reference/api-reference/products/create-product) and [Customers API](/api-reference/api-reference/customers/create-customer).

## Track the AI cost behind each signal

Knowing the cost behind each signal helps you understand your margins. This combines the previous two steps (signals and cost traces) with a dedicated API call that links an agent action to the AI costs captured in the same tracing context.

The one requirement: send the signal from inside a `paid_tracing` context where your AI calls run.

#### Python

```python
from openai import OpenAI
from paid.tracing import initialize_tracing, paid_autoinstrument, paid_tracing, cost_attributed_signal

initialize_tracing(api_key="PAID_API_KEY")
paid_autoinstrument(libraries=["openai"]) # or leave empty to autoinstrument all libraries

openai_client = OpenAI(api_key="OPENAI_API_KEY")

with paid_tracing("your_external_customer_id", external_product_id="your_external_product_id"):
    # ... your business logic, occasional AI calls ...
    openai_client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "Summarize this order."}],
    )
    # ... your business logic, occasional AI calls ...

    # emit a signal (order relative to the AI call doesn't matter)
    res = cost_attributed_signal(
        event_name="email_sent",
        data={"some_data": "some_value"},
    )
    print("Signal sent:", res)
```

## Consuming multiple credits and tracking users

Cost-attributed signals support the same `data` fields as regular signals. Pass `quantity` to consume more than one credit per signal, and include `external_user_id` to route credit spend to a specific user's seat balance:

```python
cost_attributed_signal(
    event_name="document_processed",
    data={
        "quantity": 5,
        "external_user_id": "usr_jane_doe",
        "pages": 47,
    },
)
```

See [First signals](/documentation/getting-started/first-signals#consuming-multiple-credits-per-signal) for details on dynamic credit consumption and [user-level tracking](/documentation/getting-started/first-signals#user-level-tracking-within-a-customer) for per-user attribution.