Skip to main content
@devtune/client provides typed methods for every operation in the public API. It uses fetch and has no runtime dependencies. Use ESM in Node 20+ or a modern fetch-capable runtime. Keep project API keys in server-side environment variables.
Installation from npm will be available after release. Publication has not been verified. The installation command below applies after the package is published.

Project configuration

Create a project API key in API Keys in the account sidebar. Select the scopes your integration needs, then set DEVTUNE_API_KEY and DEVTUNE_PROJECT_ID in your environment. The key must belong to that project. See authentication.
The client binds projectId once. Method names match the public API’s operation names. Pass other resource identifiers in path, filters in query and JSON in body. Responses retain their envelope, metadata and nullable fields. An unspecified success schema returns unknown, so narrow the value before using it. Explicitly bodyless successes return void, including HTTP 204/205 or an explicitly empty content map. The client accepts an empty body when the response is bodyless or unspecified. Declared JSON content requires nonempty valid JSON.
Exported types include ProjectClient, OperationId, OperationInput<'listActions'>, OperationResponse<'listActions'> and the generated OpenAPI operations, paths and components. Types preserve the API’s required and optional fields. UUIDs, numeric ranges and cross-field constraints are validated by the API.

Metrics and coverage

Use the operation’s supported fixed windows and the returned window dates. Citation stats with coverage.status === 'unavailable' and stats === null mean the window has no measurement yet. Keep that state distinct from a measured zero. AI Traffic returns project-wide sensor state alongside traffic totals. Domain and path filters narrow totals, not sensor state. no_recent_traffic means a healthy sensor was quiet; inactive needs attention. The browser snippet does not establish server-side answer fetch or 404 coverage.

Managed-agent runs

Launching an agent can spend credits. Use triggerManagedAgentRun only for an explicitly intended task with the required agents.run scope, available evidence and credits, and a key creator who belongs to the project with manage permission. Reading status also requires agents.read. Save a UUID with the intended request before launching, and supply it as requestIdempotencyKey. Reuse that same key with the same agent and inputs if you explicitly retry after a lost response. A new key can start another charged run. The client never retries launches automatically. The packaged recipes/managed-agent.ts requires these environment inputs:
  • DEVTUNE_API_KEY and DEVTUNE_PROJECT_ID
  • DEVTUNE_APPROVED_METERED_RUN=true, acknowledging the intended metered task
  • DEVTUNE_AGENT_KEY and DEVTUNE_AGENT_INSTRUCTIONS
  • DEVTUNE_RUN_IDEMPOTENCY_KEY, the saved request UUID
It launches once, prints the task ID and waits at most 20 polls within two minutes. If waiting ends, resume getManagedAgentRun with that task ID. Cancelling the request does not cancel the server run. Completed drafts still need human approval before publishing.

Shipped Action Results

Get an existing measurement’s interventionId from listOutcomesLedger. The API keeps its /outcomes/ path and operation name for compatibility. Results compare observed before/after windows. They show what moved, not what caused it. Preserve evidence quality, null deltas, still_measuring and unmeasured states. Missing conversion measurements are null, not zero.

Pagination

Actions use page and pageSize with returned totalPages. Managed-agent runs and Results use pagination.hasMore and pagination.nextCursor. Keep filters unchanged when continuing. Action edits return hasMore and nextCursor directly inside data. Analytics search rollups require their returned generation with subsequent offsets. Bound loops and stop if continuation metadata is missing or inconsistent. listVisibilityResponses returns only the latest 20 successful executions and has no cursor. It cannot retrieve complete history and is not a sample for calculating visibility rates. Use the measurement summary operations for those rates.

Timeouts and errors

The default timeout is 30 seconds for the entire call, including retries, waits and response body reading. Configure timeoutMs on the client or a call, up to five minutes, and pass signal for cancellation.
GET requests retry network failures and HTTP 408, 429, 500, 502, 503 and 504 up to twice. Set maxRetries from 0 to 5 to change the read budget. The client respects Retry-After seconds or HTTP dates, falling back to X-RateLimit-Reset Unix seconds. A required wait beyond the remaining budget returns the HTTP error immediately. POST, PATCH, PUT and DELETE are never retried automatically. DevTuneHttpError includes status, operation ID, attempts, sanitized documented error fields, retry timing and rate limits. DevTuneNetworkError reports connection failure, DevTuneAbortError reports cancellation or timeout, and DevTuneProtocolError reports malformed success JSON or a success response that contradicts its documented status/body contract. The client never logs credentials or retains raw request headers or network causes. A timeout after a write may mean the server accepted it; inspect state before deciding to retry. For compatible environments and tests, configure baseUrl, including the API root such as /api/v2, and a custom fetch implementation. Redirects are refused.

Runnable recipes

The package includes actions-report.ts, metrics.ts, managed-agent.ts and action-results.ts with a shared environment.ts in its recipes/ directory. Copy the directory into an ESM project with the client installed. Set the required environment variables, then run:
The Actions report reads at most 10 pages and reports when that bound prevents a complete report. The Results recipe reads an existing intervention; it does not ship or mark an action live. Read recipes call the API when run. The managed-agent recipe can spend credits when its explicit metered-task input is set.