API Reference¶
Base URL: https://api.nanorix.io
EU Base URL: https://api.nanorix.eu
All request and response bodies use JSON. Authentication uses Bearer tokens in the Authorization header.
Authentication¶
Authenticated endpoints require:
The API key is issued at signup and cannot be retrieved later. Nanorix stores only a SHA-256 hash.
Rate Limits by Tier¶
| Tier | Requests/min | Concurrent Sessions | Max TTL |
|---|---|---|---|
| Free | 60 | 3 | 5 min |
| Starter | 120 | 20 | 10 min |
| Business | 300 | 100 | 30 min |
| Enterprise | Custom | Custom | Unlimited |
Endpoints¶
POST /v1/signup¶
Create a new customer account. Public, rate limited to 10 requests/min per IP.
Request:
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | yes | Valid email address |
jurisdiction |
string | no | US (default), EU, UK, CA, AU, IN, OTHER |
Response (201):
{
"customer_id": "cust_8a3f...",
"api_key": "nrx_live_...",
"tier": "free",
"message": "Save your API key — it cannot be retrieved later."
}
Errors: 400 invalid email, 409 email already registered, 429 rate limited.
POST /v1/sessions¶
Create an ephemeral session. Requires authentication.
Request:
| Field | Type | Required | Description |
|---|---|---|---|
data_classification |
string | no | general (default), PHI, PII, financial, credentials |
Response (201):
{
"session_id": "sess_a8f3e71c...",
"status": "active",
"ttl_seconds": 300,
"created_at": "2026-03-01T14:00:00Z"
}
Errors: 401 unauthorized, 402 quota exceeded (free tier: 100 CDPs/month), 429 rate limited.
GET /v1/sessions/:id¶
Get session status. Requires authentication. Must own the session.
Response (200):
{
"session_id": "sess_a8f3e71c...",
"status": "active",
"ttl_seconds": 300,
"created_at": "2026-03-01T14:00:00Z",
"data_classification": "PHI"
}
Session statuses: active, executing, destroyed, expired, expired_unclean.
POST /v1/sessions/:id/exec¶
Execute a command inside the session. Requires authentication.
Request:
| Field | Type | Required | Description |
|---|---|---|---|
command |
string | yes | Command to execute inside the sandbox |
input_data |
string | no | Data written to {tmpfs}/input/data before execution |
timeout |
integer | no | Seconds before SIGTERM. Defaults to session TTL |
Response (200):
Use input_data, not command-line arguments
Pass sensitive data via the input_data field, not in the command string. Command-line arguments are visible in /proc/PID/cmdline. The input_data field writes to a file inside the sealed sandbox.
DELETE /v1/sessions/:id¶
Destroy the session and generate a CDP. Requires authentication.
Response (200):
{
"session_id": "sess_a8f3e71c...",
"status": "destroyed",
"cdp": {
"cdp_version": "1.0",
"...": "see CDP Specification"
},
"regulatory_context": { "...": "..." },
"session_context": {
"jurisdiction": "US",
"data_classification": "PHI"
}
}
This is the primary response. The full CDP JSON format is documented in the CDP Specification.
GET /v1/proofs/:session_id¶
Retrieve a stored CDP for a destroyed session. Requires authentication. Must own the session.
Response (200): The stored CDP JSON, identical to what was returned in the DELETE response.
Errors: 401 unauthorized, 404 session not found or not yet destroyed.
GET /v1/customers/me¶
Get your account details, usage, and limits. Requires authentication.
Response (200):
{
"customer_id": "cust_8a3f...",
"email": "you@company.com",
"tier": "free",
"jurisdiction": "US",
"cdps_this_cycle": 12,
"cdp_limit": 100,
"sessions_used": 2,
"sessions_limit": 3,
"rate_limit_rpm": 60,
"billing_cycle_start": "2026-03-01T00:00:00Z",
"api_key_prefix": "nrx_live_a1b2"
}
POST /v1/verify¶
Stateless CDP verification. Public, no authentication required. Rate limited to 60 requests/min per IP.
Request: A CDP JSON document as the request body.
Response (200):
{
"valid": true,
"checks": {
"chain_integrity": true,
"final_hash": true,
"signature": true,
"step_count": 8
}
}
Nothing is stored. The CDP is verified and discarded.
GET /v1/keys/:id¶
Retrieve an Ed25519 public key. Public, no authentication required. Used for Level 2 provenance verification.
Response (200):
{
"key_id": "nrx-verify-20260301T143000Z-a8f3e71c",
"algorithm": "Ed25519",
"public_key": "base64:MCowBQYDK2Vw...",
"created_at": "2026-03-01T14:30:00Z"
}
GET /v1/health¶
Health check. Public.
Response (200):
{
"status": "healthy",
"engines": { "eee": true, "dire": true, "rzl": true, "fgx": true, "ave": true },
"database": true,
"uptime_seconds": 86400,
"timestamp": "2026-03-09T12:00:00Z"
}
POST /v1/billing/checkout¶
Upgrade to a paid tier. Requires authentication. Redirects to Stripe Checkout.
Request:
Response (200):
Error Format¶
All errors return a consistent JSON format:
{
"error": "QuotaExceeded",
"message": "Free tier limit of 100 CDPs/month exceeded. Upgrade to continue.",
"status": 402
}
Common Error Codes¶
| Status | Error | Description |
|---|---|---|
| 400 | BadRequest |
Invalid request body or parameters |
| 401 | Unauthorized |
Missing or invalid API key |
| 402 | QuotaExceeded |
Free tier CDP limit reached |
| 404 | NotFound |
Session or resource not found |
| 409 | Conflict |
Resource already exists (e.g., duplicate email) |
| 429 | RateLimited |
Too many requests — retry after the indicated period |
| 500 | InternalError |
Server error — contact support |