---
title: CrewAI
description: Auto-instrument CrewAI so each crew kickoff lands in AgentPing with its total tokens, latency and request count.
section: frameworks
order: 6
---

# CrewAI

Auto-instrument CrewAI (`crewai` on PyPI) so every `Crew.kickoff` and `Crew.kickoff_async` inside an active AgentPing run emits one `llm_call` carrying the crew's aggregated token usage, request count and latency. Python only.

## Install / enable

```bash
pip install "agentping-io[crewai]"
```

```python
import agentping
from crewai import Agent, Crew, Task

agentping.init()
agentping.instrument_crewai()

crew = Crew(agents=[researcher, writer], tasks=[research, draft])

with agentping.run("weekly-brief", customer_id="acme-corp"):
    result = crew.kickoff(inputs={"topic": "Q3 churn"})
```

`instrument_crewai()` patches `Crew.kickoff` and `Crew.kickoff_async` at the class level. Idempotent and global; call it once at module load. Supported `crewai` versions: 1.x. Outside that range the patch is skipped with a single warning.

## Events

| CrewAI call | AgentPing event | What is recorded |
|---|---|---|
| `Crew.kickoff`, `Crew.kickoff_async` returning | `llm_call` | `provider: "crewai"`, input and output tokens summed across every agent and task in the crew (from `crew.usage_metrics`), cached prompt tokens when reported, `request_count` (successful model requests), latency for the whole kickoff. |
| `Crew.kickoff`, `Crew.kickoff_async` raising | `llm_call` with `status: "error"` | `provider: "crewai"`, the exception message and class, latency. The exception is re-raised. |

This is deliberately coarse. CrewAI only reports usage at the crew level, and its agents can each use a different model, so the event carries no `model` and the provider is `crewai`. You get the crew's total tokens, how many requests it made and how long it took, which is enough to alert on runaway crews and to see cost per kickoff once you price it. `kickoff_for_each` is not patched directly; CrewAI runs it as one `kickoff` per input on a copy of the crew, so each input lands as its own `llm_call`.

## Pricing

Because the event has no model, the shipped rate card does not price it. To see cost, add a rate card row for provider `crewai` with a blended per-million rate that matches the model your crew mostly uses, under Spend, Rate cards. Until then the kickoff shows in the unpriced-models list with its token counts. See [Spend](/docs/spend).

## Naming

The run name is whatever you pass to `agentping.run(...)`, typically the crew's job. Agent and task names inside the crew are not on the event; if you want them, emit your own `step` events from a task callback:

```python
def on_task_done(output):
    r = agentping.active_run()
    if r:
        r.event("step", {"kind": "task", "task": output.description[:80], "agent": output.agent})

draft = Task(description="Write the brief", agent=writer, callback=on_task_done)
```

## Source / notes

- Python: `agentping.instrument_crewai()` in [agent-ping-python](https://github.com/agent-ping/agent-ping-python)

For per-agent and per-model detail, run OpenLLMetry (`traceloop-sdk`) or OpenInference's CrewAI instrumentation alongside and export to the [OpenTelemetry](/docs/integrations/opentelemetry) endpoint; each model call then lands individually with its own model and tokens. Use one route or the other for spend so tokens are not counted twice.
