CrewAI Tutorial (TypeScript): adding cost tracking for intermediate developers
This tutorial shows you how to add cost tracking to a CrewAI TypeScript project so every run records model usage, token counts, and estimated spend. You need this when you’re running multiple agents, comparing prompts, or trying to keep an eye on LLM spend before it becomes a surprise on your invoice.
What You'll Need
- •Node.js 18+ and npm
- •A TypeScript CrewAI project already set up
- •
crewaiinstalled in your project - •An LLM provider API key in your environment:
- •
OPENAI_API_KEYfor OpenAI models - •or the provider key your CrewAI setup uses
- •
- •A place to persist usage data:
- •console logs for local development
- •a database or analytics store for production
Step-by-Step
- •Start by installing the packages you need for runtime execution and local cost reporting. I’m using
dotenvso the API key stays out of source control, andtsxso you can run the TypeScript file directly while iterating.
npm install crewai dotenv
npm install -D typescript tsx @types/node
- •Add your environment variables and define a small cost map. CrewAI will give you usage metadata from the run; you convert tokens into dollars with a pricing table that matches the model you’re using.
import "dotenv/config";
export const MODEL_PRICING = {
"gpt-4o-mini": { input: 0.15 / 1_000_000, output: 0.6 / 1_000_000 },
"gpt-4o": { input: 5 / 1_000_000, output: 15 / 1_000_000 },
} as const;
export function estimateCost(
model: keyof typeof MODEL_PRICING,
inputTokens: number,
outputTokens: number,
) {
const pricing = MODEL_PRICING[model];
return inputTokens * pricing.input + outputTokens * pricing.output;
}
- •Build a CrewAI flow with one agent and one task, then run it with an explicit model name so your tracker knows which pricing row to use. The important part is that you capture the result object from execution and inspect its usage fields after the task completes.
import { Agent, Task, Crew } from "crewai";
import { estimateCost } from "./cost";
const agent = new Agent({
role: "Support Analyst",
goal: "Summarize customer issues clearly",
backstory: "You write concise operational summaries for internal teams.",
});
const task = new Task({
description: "Summarize the following ticket in three bullet points.",
expectedOutput: "A short summary with action items.",
agent,
});
const crew = new Crew({
agents: [agent],
tasks: [task],
});
const result = await crew.kickoff({
inputs: {
ticket:
"Customer cannot reset password after receiving verification email twice.",
model: "gpt-4o-mini",
},
});
console.log(result);
- •Read the token usage from the execution result and calculate spend immediately after the run. In production, this is where you’d push a record into Postgres, DynamoDB, or whatever metrics pipeline you already use.
type UsageLike = {
prompt_tokens?: number;
completion_tokens?: number;
};
const usage = (result as unknown as { usage?: UsageLike }).usage ?? {};
const inputTokens = usage.prompt_tokens ?? 0;
const outputTokens = usage.completion_tokens ?? 0;
const model = "gpt-4o-mini";
const estimatedUsd = estimateCost(model, inputTokens, outputTokens);
console.log(
JSON.stringify(
{
model,
inputTokens,
outputTokens,
estimatedUsd: Number(estimatedUsd.toFixed(6)),
},
null,
2,
),
);
- •Wrap the whole thing in a small runner so each invocation writes a clean audit line. This keeps cost tracking close to execution and avoids losing data when multiple agents or tasks are added later.
async function main() {
const startedAt = Date.now();
const result = await crew.kickoff({
inputs: {
ticket:
"Customer cannot reset password after receiving verification email twice.",
model: "gpt-4o-mini",
},
});
const usage = (result as unknown as { usage?: UsageLike }).usage ?? {};
const inputTokens = usage.prompt_tokens ?? 0;
const outputTokens = usage.completion_tokens ?? 0;
const estimatedUsd = estimateCost("gpt-4o-mini", inputTokens, outputTokens);
console.log(
JSON.stringify(
{
durationMs: Date.now() - startedAt,
inputTokens,
outputTokens,
estimatedUsd: Number(estimatedUsd.toFixed(6)),
},
null,
2,
),
);
}
main().catch((error) => {
console.error(error);
process.exit(1);
});
Testing It
Run the script with npx tsx src/index.ts and confirm that the crew returns a normal task result first. Then check that your terminal prints token counts and an estimated USD value after the run.
If usage comes back empty, verify that your provider actually returns token metadata for that model and that CrewAI exposes it in your version. Also confirm your API key is loaded from .env, because missing credentials often look like “zero usage” when the request never really completed.
For production validation, compare your estimated spend against your provider dashboard over several runs. The numbers won’t always match exactly because billing rules vary by provider and cached tokens may be handled differently.
Next Steps
- •Persist per-run usage records into a database table with
run_id,agent_name,model,input_tokens,output_tokens, andestimated_usd - •Add budget guards that stop a workflow when projected monthly spend crosses a threshold
- •Build per-team reporting so product, ops, and finance can see which workflows are expensive
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit