[AVAILABLE]. Every path in the sidebar under REST API is generated
from
openapi/openapi.yaml, which is structurally validated in CI (npm run lint:openapi, plus openapi-bundle-refs.test.ts’s $ref-integrity checks) on
every push, and cross-checked against packages/api/src/app.ts’s real mounted
routes by openapi-route-parity.test.ts: every real route needs a matching
spec path, and every spec path needs a real, currently-mounted route behind
it, in both directions, or the test fails by name. GET /documentation and
GET /reference are the one explicit, allowlisted exception: rendered doc
surfaces, not API resources, see Views of the same
spec below.Base URL
The sandbox runs the same code as production, with its own database, keys and demo approver; its one action acts on
nothing, and everything sent to it is visible to every visitor. See Playground. The
raw spec is also served at
GET /openapi.yaml and, identically, JSON-serialized, at
GET /openapi.json (some tooling and most AI coding agents expect a .json path by
convention; both describe the same spec), see Deploy
patterns.
Are you an AI coding agent? Fetch
GET /api-manifest.json first. It’s a
single machine-readable index: the OpenAPI spec locations above, the auth
scheme, and both real SDKs (@parmana/sdk on npm, parmana on PyPI) with
their actual current package name and version, read directly from each
package’s own manifest, not hand-typed. It never claims a language has an SDK
unless one is actually published, see Other
languages.Every endpoint has its own page
The REST API tab lists every endpoint on its own page, grouped by area: Execution, Transactions, Verification, Receipts, Trust Records, Replay, Policies, Policy Governance, Approvers, External Connectors, Sandbox, Refusal Records, Execution Intents, Audit, System and Handbook. Each page is generated from the bundled OpenAPI file, so it shows the exact parameters, request body, every response with a real example, and a Try it panel that sends a real request to the public sandbox with the demo key filled in (switch the server to call your own). With the demo key, onlysandbox:receipt and the read routes work; other capabilities return 403, and governance routes return 403 NON_HUMAN_CALLER_DENIED, so use their captured examples. A test fails if an endpoint is added to the spec without a page. Start with Execute a Business Transaction, the endpoint every integration uses.
If you are an AI agent, follow Integrate Parmana: specification for AI agents instead of reading the pages one by one.
Views of the same spec
Every route, request/response shape, and status code ultimately comes from one file,openapi/openapi.yaml,
version-controlled alongside the code that implements it. That one spec drives three
surfaces, so none of them can drift from what the server actually does:
This site
Guides, SDKs, and the per-route reference in the sidebar under REST API,
each with real captured examples and a working curl snippet.
GET /documentation
Live Swagger UI on the real deployment, with Try it out wired to a real
bearer key, for hands-on testing, not just reading.
GET /reference
Live, read-only, single-page ReDoc view of the full spec, no Try it out
button, built for auditors and integration partners who just need to read
it.
Postman
postman/parmana.postman_collection.json
has one request for every endpoint, in one folder per area, with the example bodies from the
spec. It is generated from the same OpenAPI file (npm run generate:postman), and a test fails
if it falls behind.
- In Postman, choose Import and select the file.
- Create an environment with a secret variable
apiKeyholding your API key, or the sandbox demo key2VfYWCzt_cBAPK-8uufX6ordfY2JuQhFPsohuEumKMEto try it. The collection sends it asAuthorization: Bearer {{apiKey}}; requests the API marks as public send no key. Never put a real key in the collection itself. baseUrldefaults to the public sandbox,https://parmana-sandbox.vercel.app. Override it in the environment for production (https://parmana-api-real.vercel.app) or your own deployment, for examplehttp://localhost:3000.
Authentication
The bearer key model, and how it differs from Policy evaluation and gateway
attestation.
Error handling
The shared error envelope, which errors carry a code, and the one known gap.
Idempotency and nonces
Why there’s no Idempotency-Key header, what businessTransactionId does
instead, and how authorizations and approvals are accepted once.
Error catalog
Every error this API returns, one table, cross-linked from the spec.
Errors
Non 2xx responses are{ "error": string }, often with a stable code. Branch on the status, then on code, never
on the text. Which errors carry a code, and the one known gap, are on Error handling;
every specific error this API returns is on the Error catalog.
Both maintained SDKs raise a specific exception per status code. The Python SDK:
ValidationError/NotFoundError/ConflictError/ServerError/etc., see Python
SDK. The TypeScript SDK: ValidationError/AuthenticationError/
AuthorizationError/NotFoundError/ConflictError/ExecutionRejectedError/etc., see
TypeScript SDK.
Auth
Every route requires a caller bearer key, except the liveness/readiness
probes and documentation/verification routes listed on
Authentication. See that page for how to send
a key and what it does and does not prove.
Rate limiting
POST /execute is rate-limited per authenticated caller; GET /health and GET /ready carry a
separate, more permissive limit keyed by IP. See Authentication
for the mechanism and Error catalog for the exact 429 shape.
Versioning
GET /version (with a key) reports {"name":"Parmana","version":"<build>","api":"v1"}; GET /api-manifest.json
reports the same two values without one, as apiVersion and buildVersion. The api field
is the REST API’s version, currently v1; the version field is a separate deployment
build identifier, not derived from it. openapi/openapi.yaml’s own info.version tracks the
spec document, currently 1.0.0. There’s no fixed release cadence: routes and fields have
been added within v1 as this API has grown (see Changelog), and existing
fields and status codes haven’t been removed or had their meaning changed. A breaking change
to the REST API surface itself would be a new version (v2), not a silent change to v1.
Both SDKs follow semantic versioning (MAJOR.MINOR.PATCH): a major version indicates a
breaking change to the SDK’s public surface (ParmanaClient, its domain models, its error
types), a minor version adds functionality without breaking existing code, and a patch is a
backward-compatible fix. Check the currently published version with npm view @parmana/sdk version or pip index versions parmana, see TypeScript SDK and Python
SDK.