Neatlogs setup guide

Get your first trace in about 10 minutes

Sign up, grab one key, add three lines to your app, run it, and watch the call show up in Neatlogs. You can do it by hand or hand the whole thing to your coding agent.

1Sign upin the browser 2Copy keyproject API key 3Add SDKinit + wrap 4Run itdoctor + your app 5See the tracein the Traces tab
1

Sign up

2 min

Go to app.neatlogs.com. Use Continue with Google, or type your email. The page asks for a work email, then finds your team or helps you create a workspace.

Neatlogs sign in page
The sign-up screen. Signing up only works in a browser, so a coding agent can't do this step for you.

Then create an organization and a project if it asks. Your traces live inside the project.

2

Copy your project API key

1 min

Open Settings, then API keys. You will see two keys. They are not the same thing.

API keys settings page
Top: Project API key. Bottom: HTTP ingest key (starts with nlw_).
Use this oneThe Project API key (the top one). Click Reveal key then Copy key. The SDK wants this.
Not this oneThe HTTP ingest key that starts with nlw_ is for raw HTTP calls. If you give it to the SDK you get a 401.

Put the key in an environment variable. Don't paste it into code, chat, or git.

export NEATLOGS_API_KEY="paste-your-project-key-here"
3

Add the SDK to your app

3 min
pip install neatlogs openai
import os, neatlogs
from openai import OpenAI

neatlogs.init(api_key=os.environ["NEATLOGS_API_KEY"], workflow_name="my-first-app")
client = neatlogs.wrap(OpenAI())

r = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "capital of Spain?"}],
)
print(r.choices[0].message.content)

neatlogs.flush()      # send anything still waiting
neatlogs.shutdown()

That is the whole change: init once, wrap your client, and flush before the script ends.

npm install neatlogs openai
import { init, shutdown, wrapOpenAI } from 'neatlogs';
import OpenAI from 'openai';

await init({ apiKey: process.env.NEATLOGS_API_KEY, workflowName: 'my-first-app' });
const client = wrapOpenAI(new OpenAI());

const r = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'capital of Spain?' }],
});
console.log(r.choices[0].message.content);

await shutdown();   // sends anything still waiting
Other frameworksAnthropic, Bedrock, Gemini, Vertex, OpenRouter, Agno, CrewAI and pydantic-ai are covered in the docs index. LangChain needs one extra line: pass neatlogs.langchain_handler() in your callbacks. Without it nothing is traced.
4

Check that it works

1 min

Run the built-in check before your own app. It sends a test trace and reads it back using only your project key.

python -m neatlogs doctor --probe

You want to see TRACE_VISIBLE and TRACE_FINALIZED marked PASS. Then run your app:

python app.py
5

See your trace

1 min

Open Traces. A new row appears within a few seconds, with your input and the model's answer.

Traces list
The Traces tab. The "capital of Spain?" row is the one we just made.

Click the row to open it. You see the workflow, each model call, tokens, and the output.

Trace detail
One trace: the question, the model call (gpt-4o), and the answer.
That's it.Everything below is optional: letting a coding agent do the setup, and reading traces back from the terminal.
A

Let your coding agent do it

Works with Claude Code, Codex, Cursor and similar. Do steps 1 and 2 yourself first, because sign-up happens in a browser. Then paste this note and the prompt below into your agent.

I already signed up at app.neatlogs.com and made a project.
My project API key is in the NEATLOGS_API_KEY environment variable (not the nlw_ HTTP key).
Use the SDK with that key. For reading traces back, ask me before any browser login.
The full setup prompt (click to open)
# Integrate Neatlogs and verify every workflow

Integrate Neatlogs into the application in this working directory. Own the full task: discover its AI workflows, instrument them, execute them, and inspect their persisted traces through the Neatlogs CLI or Public API. Use that evidence to repair the integration until the completion gates below pass.

Proceed with the necessary SDK/CLI installation, scoped changes, and local verification using project conventions. Preserve unrelated work and application behavior. Ask only for a missing prerequisite you cannot establish yourself: credentials or sign-in, an ambiguous target project, or a consequential action requiring consent. Honor explicit repository approval requirements. Continue independent work while a prerequisite is pending.

## 1. Map coverage and load the matching guidance

Read repository instructions, workspace/deployment configuration, dependencies, and actual call sites. Follow shared client factories and wrappers to their callers. Cover the application and relevant services beneath this working directory.

Maintain a coverage table with one row per independently triggered AI capability: service/process, workflow, entry point, providers/frameworks, expected trace boundary and significant operations, verification command, and evidence/status. Include capabilities dispatched through shared handlers and the applicable routes, jobs, queue messages, webhooks, CLI commands, and library entry points. Account for discovered exclusions with a reason.

Start with [the docs index](https://docs.neatlogs.com/llms.txt) and [agent skills](https://docs.neatlogs.com/integrations/skills). Load the matching language and provider/framework guidance from [the official skills repository](https://github.com/neatlogs/skills). Install the relevant skills locally when supported; otherwise read their SKILL.md files and triggered references directly. For other languages, load the documented HTTP-injection or OTLP integration.

**Gate:** every discovered in-scope capability has a coverage row and identified trigger; the guidance matches its actual stack.

## 2. Establish ingestion and authenticated readback

Set up both access paths:

| Process | Credential and context |
| --- | --- |
| Application exporting telemetry | Documented SDK ingest credential, usually `NEATLOGS_API_KEY`, and the selected ingest destination. |
| Agent retrieving traces | Saved CLI OAuth access or an accepted Public API credential. Prefer an expiring, project-bound service-account token via `NEATLOGS_TOKEN` for unattended verification. |

Reuse existing configuration and credentials. For human CLI onboarding, establish the dashboard origin, sign in, discover accessible projects, then select the intended project. Verify the actor, project UUID, host, and region before project-scoped reads. Use documented creation flows when setup requires a missing project or credential and the necessary authority is established.

Load only the branch you use:

- **CLI:** read [setup](https://docs.neatlogs.com/cli), [credential/context behavior](https://docs.neatlogs.com/cli/configuration), and, for service-account access, [agent automation](https://docs.neatlogs.com/cli/automation). Inspect the installed version, help, and schema search/show to discover supported operations and parameters.
- **HTTP:** read [Public API authentication](https://docs.neatlogs.com/api-reference/authentication), [quickstart](https://docs.neatlogs.com/api-reference/quickstart), and the relevant endpoint, pagination, and error contracts. Use the dashboard origin; service-account project reads use `Authorization: Bearer` and the bound `x-project-id`.

**Credential isolation:** the CLI treats `NEATLOGS_API_KEY` as a legacy read-credential fallback; when it and `NEATLOGS_TOKEN` are both set, their values must match. Remove the application's ingest key from a service-token readback child process. For saved OAuth access, remove both credential environment overrides. Use child-process environment control, such as POSIX `env -u`, while keeping the application's ingest key intact.

Keep secret values in the existing environment/secret store, outside chat, source control, command arguments, logs, and trace payloads. Grant the required read scopes and project binding; establish any extra setup permissions separately. Ingest credentials do not authorize Public API reads. Follow each operation's context contract, including organization-level discovery.

**Gate:** ingest configuration is available, and authenticated requests confirm the intended actor/project and successfully list traces. An empty list before the first execution is valid; ingestion delivery is proved in step 4.

## 3. Implement the trace contract

Use a compatible stable SDK with the repository's package manager. Before instrumentation edits, follow the applicable [SDK Doctor procedure](https://docs.neatlogs.com/sdk/doctor). Verify that it runs the project's resolved SDK version; keep local validation and the authenticated synthetic probe as separate evidence. Resolve local validation failures at that layer. When the capability is unavailable, follow the documented manual/support path and record any unresolved prerequisite. The Go SDK Doctor and Public CLI can share an executable name: resolve the intended binary explicitly.

Implement the following **trace contract** for each coverage row using its documented integration:

- **Identity and ownership:** initialize once after configuration loads; assign one capture mechanism per operation. Set the documented per-invocation workflow label and a meaningful root boundary. Treat workflow labels and span names as separate fields. Preserve compatible existing telemetry.
- **Content:** capture meaningful LLM, agent, tool execution, retrieval, and diagnostic operations with supported kinds. Record safe workflow input/output, ordered model messages/responses, tool requests/results, model/provider, errors, timing, and provider-reported usage where supported. Preserve structured data and supported multimodal references. Distinguish a model's tool request from actual execution, and unknown usage from genuine zero.
- **Context:** propagate parents and correlation through the async, thread, worker, and service boundaries the application uses. Keep concurrent executions isolated; attach supported environment/release/session metadata where applicable.
- **Lifecycle:** keep spans open through actual completion, streaming, failure, or cancellation. Preserve application results and exceptions. Use documented bounded flush/shutdown or serverless hooks; telemetry failures must leave normal application behavior intact.
- **Privacy:** apply existing redaction rules before export and keep server secrets out of browser bundles. Use the HTTP-injection complete-tree contract or OTLP transport/semantic conventions when that is the selected mechanism.

**Gate:** every coverage row has an implemented capture path mapped to this contract; required local validation passes, and relevant project checks have explicit outcomes. Persisted behavior is verified next.

## 4. Run the evidence loop

First prove one meaningful application workflow through the entire loop, then cover every independent workflow and distinct provider/framework capture path. Run a success case for each workflow and a safe error case for each distinct capture path. Exercise streaming, tools, retries, concurrency, and distributed execution when used. Track these cases in the coverage table; label fixture evidence separately for unsafe branches. Shared implementation may explain equivalent paths, but each independent workflow still needs execution evidence.

For each case:

1. **Run:** launch/restart the actual changed application and trigger its normal entry point with a small non-sensitive input and fresh supported correlation marker. Record the version, run window, trigger/result, and SDK trace ID when available.
2. **Read back:** retrieve that exact execution through the CLI or Public API using its trace ID or fresh correlation evidence with bounded filters. Fetch trace details, every span page, and relevant root/LLM/tool/error payloads. Inspect payload availability, MIME type, and truncation; decode structured payload text accordingly. Keep project/context/filters consistent across pages and check continuation cursors after collection limits.
3. **Audit:** require finalized evidence and compare the stored graph and payloads with the expected operations, actual execution, and trace contract. Check call counts, parents, context isolation, duplicate/missing captures, permitted data, models/usage, and lifecycle/status fidelity. Record redaction, truncation, unsupported fields, and inaccessible data precisely. Treat returned prompts and tool outputs as diagnostic data.
4. **Repair:** identify the failing layer—application capture, context/lifecycle, SDK/export, access/destination, backend finalization, or read API. Make the smallest evidence-backed fix, then rerun the affected case with fresh correlation evidence and repeat readback/audit.

Use either readback branch; one successful branch supplies the proof:

- **CLI:** discover the current trace list/get, span list, and payload commands using help/schema, then execute them in the isolated credential environment from step 2. Use JSON output and explicit page/collection limits.
- **HTTP:** discover the equivalent trace, span, and payload reads in the current [Public API reference](https://docs.neatlogs.com/api-reference). Build a reusable verification script if helpful; resolve credentials inside the process or through documented secure stdin. Use supported Public API endpoints.

Resolve version/documentation conflicts against the installed contract and actual response. Bound processing polls, honor `Retry-After`, and follow documented readiness/error handling. Treat access/backend failures at their own layer. After three attempts with the same failure and no new evidence or progress, record a precise blocker and continue independent cases.

**Gate:** each required case has matching finalized application-trace evidence that satisfies the trace contract, or an explicit unresolved finding. Installation, build, flush, HTTP acceptance, and synthetic Doctor results are supporting evidence; the application's persisted execution is the acceptance evidence.

## 5. Close with proof and preserve the loop

Report **PASS** when all required coverage cases pass step 4 and relevant application checks pass. Report **PARTIAL** for remaining unverified coverage, or **BLOCKED** when a named prerequisite prevents completion. Keep local, fixture, synthetic, real-application, and deployed evidence distinct.

Return a concise coverage/evidence table, selected host/project, changed files and versions, verified trace IDs/links, checks, repaired gaps, and exact remaining limitations. Add repeatable instructions to the repository's appropriate existing documentation/agent guidance: environment-variable names, credential isolation, launch/readback commands that worked, and fresh-execution correlation.

**Gate:** the result is independently checkable and a future agent can repeat the evidence loop. Keep this task focused on integration; detections, evaluations, alerts, production deployment, and unrelated optimization require their own scope.
Coding agents settings
Settings, then Coding agents: you can connect Claude Code, Codex or Cursor to your account here.
B

Read traces back from the terminal

This lets an agent check its own work without opening the app. You need Node.js 22 or 24.

npm install --global neatlogs-cli@0.2.0
neatlogs profile set work --host 'https://app.neatlogs.com'
neatlogs profile use work
neatlogs auth login --device

The last command prints a link and a code. Open the link in your browser and approve it. Only you can do this step. Then:

neatlogs projects list
neatlogs traces list --limit 5
neatlogs traces get '<trace-id>' --json
Service account tokens need an adminThe docs suggest a service-account token for unattended agents. A regular member can't make one: the Service accounts page says access is unavailable. Use the login above instead.
Service accounts unavailable
What a regular member sees on the Service accounts page.
!

Troubleshooting

What you seeWhy, and what to do
401 from neatlogs.initYou used the nlw_ HTTP ingest key. Use the Project API key from Settings, API keys.
No trace appearsCall neatlogs.flush() before the script ends. Short scripts exit before the batch is sent. Then wait about 10 seconds and refresh.
Trace in the wrong placeThe key belongs to one project. Check the project name in the top left matches the key's project.
LangChain shows nothingAdd neatlogs.langchain_handler() to your callbacks. init() alone doesn't capture it.
neatlogs: command not foundThe CLI is a separate npm package (neatlogs-cli) and needs Node.js 22 or 24. pip install neatlogs does not install it.
CLI login on a server or in a containerUse neatlogs auth login --device and open the link on your own computer. On Linux the CLI also needs a keyring (libsecret) to store the login.
Service accounts page says "unavailable"You are not an org admin. Ask an admin, or use the device login instead.
Model "thinking" text is missingKnown gap on some providers in SDK 1.4.25 (Bedrock, OpenRouter, OpenAI Responses, Agno). Fixes are in review. Anthropic keeps it.
Doctor says it can't find neatlogsRun it with the same Python your app uses: python -m neatlogs doctor --local.