Docs
PnLSaver API and OpenAPI
PnLSaver publishes the same read-only HTTP API used by its web interface, plus an OpenAPI 3.1 contract that agents and developer tools can inspect automatically.
Start with the machine-readable contract
Use https://pnlsaver.com as the server URL. The API accepts public wallet addresses and requires no API key or authentication. Endpoints are rate-limited and intended for bounded, interactive portfolio reads rather than bulk indexing.
Versioning and deprecation
The stable public contract is API version 1. Send API-Version: 1 on any /api request. For compatibility, omitting the header currently selects version 1; every API response returns API-Version with the version that handled it. A different value returns a structured unsupported_api_version error instead of silently selecting another contract.
- Backward-compatible fields and operations may be added within version 1. Clients should ignore response fields they do not understand.
- A breaking request or response change requires a new API-Version value and a separately documented migration path.
- No API version is currently deprecated. API responses link to this policy with rel=deprecation even before a deprecation begins.
- When a version is deprecated, responses will add the RFC 9745 Deprecation header using an @timestamp and link to migration guidance. If retirement is scheduled, Sunset will use an HTTP date no earlier than the deprecation date.
- PnLSaver will publish a sunset date at least 90 days before a stable version stops responding, unless continued operation would create an urgent security or legal risk.
Read-only security model
No signing capability exists
The API never asks for a private key, wallet connection, signature, approval, or transaction. POST routes submit public addresses and read parameters for aggregation, cache refreshes, snapshots, or the bounded portfolio assistant; they do not submit blockchain transactions.
- There is no API authentication flow because the documented endpoints operate on public wallet data.
- There are no webhooks: clients poll or use the documented NDJSON progress streams.
- There is no MCP server. Agents should discover the HTTP surface through /openapi.json and /llms.txt.
Structured JSON errors
| Field | Meaning |
|---|---|
| error | Backward-compatible human-readable message used by the web client. |
| code | Stable machine-readable category such as invalid_request or rate_limited. |
| message | Human-readable explanation of this failure. |
| hint | Concrete recovery guidance, including where to verify the request shape. |
Unknown API paths and malformed JSON bodies also use this shape. Rate-limited responses include Retry-After when the endpoint can calculate one.
HTML and Markdown representations
Public pages honor Accept: text/markdown and return UTF-8 Markdown from the canonical URL. Negotiated responses set Vary: Accept, Accept-Encoding so shared caches do not mix HTML and Markdown. A request that excludes both available formats receives 406 Not Acceptable.
API routes return application/json except documented image responses and application/x-ndjson progress streams. Request application/json when an agent calls the API directly.
Rate limits and operational compatibility
Every /api response advertises the public-api quota. The default deployment allows 10,000 requests per client IP in a sliding 15-minute window, which is intentionally above normal interactive portfolio traffic. Expensive operations may advertise a smaller endpoint-specific policy instead.
- RateLimit-Policy describes the named quota and window; RateLimit reports remaining requests and seconds until capacity begins to return. The legacy-compatible RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset fields carry the same basic state.
- A 429 response includes Retry-After. Wait at least that many seconds and apply jitter before retrying; do not fan retries across wallet addresses.
- Upstream RPC and provider failures are reported as errors, warnings, or partial sections rather than silently counted as zero.
- Successful JSON objects may gain fields as portfolio coverage expands; clients should ignore fields they do not understand.
- Cold wallet reads can take longer than cached reads. Use streaming variants where the OpenAPI contract advertises application/x-ndjson.
- The public quota is process-local and may reset when the service restarts. Clients must treat headers on each response as current rather than predicting future capacity from an earlier response.
Try it
Start with a public wallet address.
No connection, signature, approval, or transaction required.
Open PnLSaver