Skip to content

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.

Create an API key

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.

Terminal window
export SHIELD360_URL=https://app.shield360.ai # or your own Shield360 URL
export 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.

Install the SDK and initialise it

Give each service its own application name. It becomes the service filter on the page.

# pip install shield360
import shield360
shield360.init(application_name="checkout-api", environment="production")
// npm install shield360
import 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.

Trace calls to routes and code

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-fastapi
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
FastAPIInstrumentor.instrument_app(app)
// npm install @opentelemetry/instrumentation @opentelemetry/instrumentation-http @opentelemetry/instrumentation-express
import { 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()],
});
Tag each build

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:

Terminal window
export SHIELD360_SERVICE_VERSION=1.42.0
export SHIELD360_GIT_COMMIT=$(git rev-parse HEAD)
export SHIELD360_GIT_REPOSITORY_URL=https://github.com/acme/checkout-api

OTEL_SERVICE_VERSION and OTEL_RESOURCE_ATTRIBUTES are honoured as well. In Kubernetes, pod labels and annotations fill these at ingest.

Check model prices

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.

Verify

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.

SymptomCheck
The page says there are no model callsThe 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 lowAdd the framework instrumentation in step 3.
Traced to a build is lowSet the variables in step 4 in the service’s runtime environment, not only in CI.
Savings say a price table is missingAdd 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.