Fast check
Before debugging deeply, verify the first integration path:- Install
@pylva/sdkfor TypeScript orpylva-sdkfor Python. - Create an Agent SDK key and store it as
PYLVA_API_KEY. - Call
initbefore the provider call you want to track. - Wrap one real provider call with a
customer_idandstep. - Wait for the SDK flush interval, or flush explicitly in a short script.
- Check the dashboard for the same customer and step.
Install or import fails
| Symptom | Likely cause | Fix |
|---|---|---|
TypeScript cannot import @pylva/sdk. | The package is not installed in the runtime project. | Run pnpm add @pylva/sdk in the app or agent package that makes provider calls. |
Python cannot import pylva. | The PyPI package name and import name are different. | Install with pip install pylva-sdk, then import with import pylva. |
| LangGraph events do not appear. | LangGraph owns the model call, so provider auto-patching may not see the call. | Use the LangGraph callback path in the SDK docs and pass metadata.pylva_customer_id. |
API key or init problems
| Symptom | Likely cause | Fix |
|---|---|---|
InvalidApiKeyError during init. | The key is missing, malformed, or not an Agent SDK key. Data import keys use pv_cli_* and fail SDK format validation. | Create an Agent SDK key in Settings -> API keys and store it as PYLVA_API_KEY. |
SDK logs API key was rejected. | The key was revoked, mistyped, expired, or not valid for the current project. | Create or rotate an Agent SDK key, update the runtime secret, and restart the process. |
403 WRONG_SCOPE. | A valid key is being used with the wrong endpoint family. For example, an Admin API key can have a pv_live_* prefix but is not an Agent SDK key. | Use an Agent SDK key for SDK telemetry. See API keys. |
SDK not initialized. | A SDK helper ran before init. | Call init({ apiKey: process.env.PYLVA_API_KEY! }) or pylva.init(api_key=os.environ["PYLVA_API_KEY"]) during process startup. |
No events in the dashboard
| Symptom | Likely cause | Fix |
|---|---|---|
| The provider call succeeds, but the dashboard is empty. | The SDK flushes in the background, about every 5 seconds by default. | Wait a few seconds and refresh the dashboard. In short scripts, call flush before exit. |
| A local script exits immediately after one call. | The process may exit before the buffered event is sent. | In TypeScript, call await flush(). In Python sync scripts, call asyncio.run(pylva.flush()). |
| Events appear without the expected customer or step. | The provider call was not inside a tracking context, or the LangGraph callback metadata did not include a customer id. | Wrap the call with track or track_context, or pass metadata.pylva_customer_id in LangGraph. |
| Events never appear from a provider path. | The provider or framework path may not be auto-instrumented. | Check Supported Integrations, use the callback path for LangGraph/LangChain, or report usage explicitly for unsupported paths. |
| Events go to the wrong deployment. | A self-hosted runtime is using the cloud endpoint, or a cloud runtime has a stale endpoint override. | Omit endpoint for Pylva Cloud. For self-hosted deployments, pass the deployment origin consistently. |
Flush a short script
TypeScript:API responses and warnings
| Symptom | Likely cause | Fix |
|---|---|---|
401 INVALID_API_KEY. | The key is missing, invalid, revoked, or expired. | Create a new Agent SDK key and update the runtime secret. |
403 WRONG_SCOPE. | The key is valid, but not allowed for the endpoint. | Use an Agent SDK key for SDK telemetry, rules, pricing, and budget sync. |
429 RATE_LIMIT_EXCEEDED. | The key exceeded the per-key request limit. | Reduce flush frequency, batch events through the SDK, and retry after the Retry-After header. |
400 VALIDATION_ERROR. | A direct API request does not match the wire schema. | Prefer the SDK. If calling the API directly, use the full event shape from Submit telemetry events. |
pricing not yet configured. | Pylva accepted usage, but does not yet have pricing for that provider/model or metric. | Add the missing pricing in the dashboard before relying on margin or billing reports. |
Missing cost sources
For the full coverage workflow, see Cost Source Discovery.| Symptom | Likely cause | Fix |
|---|---|---|
| A vendor bill is higher than Pylva usage. | A non-LLM source may not be reported, or a provider path may not be auto-instrumented. | Inventory the paid source, add reportUsage or report_usage, and run pylva validate to check for unapproved sources. |
pylva validate --ci fails. | The repository contains a newly detected source that is not approved in .pylva/approved-sources.json. | Run pylva validate --approve locally, declare the source with a Data import key, and commit the updated approval file. |
| Spend unexpectedly drops to zero for one source. | Instrumentation may have been removed, renamed, or deployed without the right runtime path. | Check recent code changes, metric names, and source health alerts before treating the cost drop as real savings. |
Budget hard stops
For safe rollout guidance, see Controls Workflow.| Symptom | Likely cause | Fix |
|---|---|---|
PylvaBudgetExceeded is thrown. | An active hard-stop budget rule was cached by the SDK and blocked the next provider call before spend increased. | Catch PylvaBudgetExceeded and return a product-specific fallback such as a cached answer, smaller model path, queued job, or human handoff. |
| Calls are not blocked while Pylva is unreachable. | Pylva is designed to fail open when pricing, rules, or backend state is unavailable. | Check rule activation and SDK cache timing. Hard stops block only when the SDK has the active rule state needed to enforce safely. |
Webhook alerts
For the full delivery workflow, see Alert Delivery And Webhooks.| Symptom | Likely cause | Fix |
|---|---|---|
| An expected alert did not arrive. | The rule has no enabled alert channel, the webhook config is disabled, or delivery failed after retries. | Check the rule’s alert channels, webhook enabled state, and the dead-letter queue. |
| Webhook signature verification fails. | The receiver is verifying a parsed body, stale secret, wrong timestamp header, or malformed signature. | Verify the raw request body with X-Pylva-Signature, X-Pylva-Timestamp, and the saved signing secret. |
| A DLQ entry appears. | Pylva could not deliver the alert after retries, or the webhook config was deleted before dispatch. | Fix the receiver or channel configuration, then retry the DLQ entry. Dismiss it only when no follow-up is needed. |