Cost of code
Costs → Cost of code (/costs?tab=code) shows what your own applications spend on model calls. Each call is traced to the service, HTTP route, function and build that made it, with the waste detectors’ findings and what fixing them could save.
It reads the model-call spans your instrumented applications send. Coding-agent sessions such as Claude Code, Codex and Cursor aren’t included: they’re on the Coding Agents page. Plan seats and extra usage are under Subscriptions.
Set up
Section titled “Set up”Open Settings → API keys in the project the telemetry belongs to and create a key. The key decides which project the spans land in. Keep it in your secret store, not in code.
export SHIELD360_URL=https://app.shield360.ai # or your own Shield360 URLexport SHIELD360_API_KEY=<your API key>With these two variables set, the SDK sends telemetry to Shield360’s authenticated ingest route (/api/ingest/otlp/v1/traces), so you don’t need a collector or an open OTLP port.
Give each service its own application name. It becomes the service filter on the page.
# pip install shield360import shield360
shield360.init(application_name="checkout-api", environment="production")// npm install shield360import shield360 from "shield360";
shield360.init({ applicationName: "checkout-api", environment: "production" });Call init before the model client is created. Any OpenTelemetry GenAI instrumentation that records gen_ai.usage.cost works too.
The SDK records code.function.name and code.file.path on every model call by default (set SHIELD360_CAPTURE_CODE_LOCATION=false to turn it off). To attribute cost per endpoint, also add your web framework’s OpenTelemetry instrumentation so the request’s root span carries http.route:
# pip install opentelemetry-instrumentation-fastapifrom opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
FastAPIInstrumentor.instrument_app(app)// npm install @opentelemetry/instrumentation @opentelemetry/instrumentation-http @opentelemetry/instrumentation-expressimport { registerInstrumentations } from "@opentelemetry/instrumentation";import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
// after shield360.init(...)registerInstrumentations({ instrumentations: [new HttpInstrumentation(), new ExpressInstrumentation()],});The version and commit let you compare cost before and after a deploy, and link a release to its commits. On GitHub Actions, GitLab CI, CircleCI, Vercel and similar platforms the SDK reads them automatically. Elsewhere, set them at deploy time:
export SHIELD360_SERVICE_VERSION=1.42.0export SHIELD360_GIT_COMMIT=$(git rev-parse HEAD)export SHIELD360_GIT_REPOSITORY_URL=https://github.com/acme/checkout-apiOTEL_SERVICE_VERSION and OTEL_RESOURCE_ATTRIBUTES are honoured as well. In Kubernetes, pod labels and annotations fill these at ingest.
Spend comes from the cost recorded on each call. A price table under Manage models sharpens the savings estimates and enables the model-size check.
Make a model call from the service and refresh Costs → Cost of code. New calls appear within a minute. The Attribution panel shows how many calls carry each of route, function, file, build, commit and repository. Use it to find the services that still need steps 3 and 4.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Check |
|---|---|
| The page says there are no model calls | The time range, that the API key belongs to this project, and that the service isn’t a coding agent. |
| Calls appear but Traced to an HTTP route is low | Add the framework instrumentation in step 3. |
| Traced to a build is low | Set the variables in step 4 in the service’s runtime environment, not only in CI. |
| Savings say a price table is missing | Add prices under Manage models. |
The same steps are shown on the page under Set up Cost of code. The section is open while the page has no data.