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

# Monocle

> Meter and monetize AI workloads instrumented with Monocle

[Monocle](https://github.com/monocle2ai/monocle) ships with a Paygentic span exporter that streams inference traces into your Paygentic account as CloudEvents. Once configured, Monocle's traces feed your billable metrics directly — no separate instrumentation for billing.

This guide covers the Paygentic-side setup. It assumes you already have Monocle installed and instrumenting your application.

## Before you begin

* An application instrumented with Monocle via `setup_monocle_telemetry(...)`
* A [Paygentic account](https://platform.paygentic.io) (or [sandbox account](/getting-started/environments) for testing)
* An [API key](/api-keys) with `events:create` permission

## Step 1: Define a product and billable metric

In the Paygentic dashboard, create a product (for example, "Monocle Agent") and a [billable metric](/platform/pricing/billable-metrics) that matches the Monocle span you want to bill on.

The Paygentic exporter derives the event `type` from the span's `entity.1.type` attribute, prefixed with `ai.`. For example, an OpenAI chat completion (`entity.1.type = "inference.openai"`) arrives at Paygentic with `type = "ai.inference.openai"`.

Map Monocle spans to billable-metric fields as follows:

| Field           | Value for Monocle                       | Example                       |
| --------------- | --------------------------------------- | ----------------------------- |
| `eventType`     | `ai.` + the Monocle entity type         | `ai.inference.openai`         |
| `valueProperty` | JSONPath into the span's metadata event | `$.total_tokens`              |
| `groupBy`       | Optional dimensions you care about      | `{ "model": "$.model_name" }` |

Create one billable metric per provider you want to bill on. Paygentic rejects spans whose `eventType` has no matching metric with `422` and suppresses them for an hour.

<Note>
  When you use a framework like LangChain or LlamaIndex, the event type still reflects the underlying provider. A LangChain `ChatOpenAI` call emits `ai.inference.openai`, a `ChatAnthropic` call emits `ai.inference.anthropic`, and so on. Unknown or unmapped LLM clients fall back to `ai.inference.generic`.
</Note>

The `data` payload contains the attributes from the span's `metadata` event (plus `span_id`, `trace_id`, and `name`). Common metadata fields across Monocle's provider integrations include `total_tokens`, `completion_tokens`, `prompt_tokens`, and `model_name`.

See [Meter Events](/platform/metering/meter-events) for the full list of aggregation options and JSONPath rules.

<Note>
  Monocle spans can also feed a [cost metric](/platform/metering/cost-tracking) alongside your billable metric, so the same event drives both customer billing and internal margin tracking.
</Note>

## Step 2: Enable the Paygentic exporter

Configure the exporter via environment variables:

```bash theme={null}
export PAYGENTIC_API_KEY=sk_live_YOUR_API_KEY
```

Sandbox keys are prefixed `sk_test_` and live keys `sk_live_`. When targeting the sandbox, also set `PAYGENTIC_SANDBOX=true` so events are routed to `api.sandbox.paygentic.io`. See [Environments](/getting-started/environments) for details.

Then add the `paygentic` exporter to your Monocle setup call:

```python theme={null}
from monocle_apptrace.instrumentor import setup_monocle_telemetry

setup_monocle_telemetry(
    workflow_name="my-app",
    monocle_exporters_list="paygentic",
)
```

Event data should now flow into the **Meters** section of the Paygentic dashboard. Use this view to confirm the integration before moving on.

<Note>
  By default the exporter only exports `inference` spans — other Monocle span types are filtered out. The event `source` field defaults to `"monocle"`; override it per-app with `PAYGENTIC_SOURCE=my-app`.
</Note>

## Step 3: Attach subscriptions via trace scopes

The exporter sets each event's `subject` from a Monocle trace scope. It checks `subscriptionId` first, then falls back to `customerId`. If neither scope is set on the span, the exporter drops the event.

Create a customer, subscribe them to a plan with a price on your Monocle metric, then tag traces with the subscription id before your instrumented workload runs:

```python theme={null}
from monocle_apptrace.instrumentation.common.instrumentor import monocle_trace_scope

with monocle_trace_scope("subscriptionId", "sub_demo_123"):
    # your instrumented workload
    ...
```

See [Customer Lifecycle](/platform/billing/customer-lifecycle) for the full subscription activation flow.

## Troubleshooting

* **Events aren't showing up in the Meters view.** Confirm your billable metric's `eventType` matches the `ai.`-prefixed type the exporter emits (e.g. `ai.inference.openai`, not `inference.openai`). The exporter rejects events with an unknown `type` with `422` and temporarily suppresses them.
* **No subject resolved errors in application logs.** The span has no `subscriptionId` or `customerId` scope — wrap the traced call in `monocle_trace_scope(...)`.
* **Sandbox key with live endpoint (or vice versa).** Set `PAYGENTIC_SANDBOX=true` when using an `sk_test_` key.

## Next steps

* [Billable Metrics](/platform/pricing/billable-metrics) — pricing models and aggregation options for metered usage
* [Cost Tracking](/platform/metering/cost-tracking) — track provider costs alongside customer billing
* [Customer Lifecycle](/platform/billing/customer-lifecycle) — how subscriptions activate and renew
