REST API Overview
Call the Nexa platform directly from any language or framework using plain HTTP.
The Nexa REST API lets you integrate file processing, payments, and student records into any stack — Python, PHP, Ruby, Go, plain curl, or anything else that can make an HTTP request. No SDK required.
Base URL
All endpoints are versioned implicitly through breaking-change-free evolution. When a breaking change is necessary a versioned prefix (/v2/...) will be introduced with advance notice.
Authentication
Every request must carry your tenant API key in the x-api-key header.
Get your API key from the Nexa dashboard → API key.
Warning
Never expose your API key in client-side code or public repositories. Route all Nexa API calls through your server.
User-scoped requests
Endpoints that return per-user data (documents, student records, analysis jobs) also accept an optional x-user-id header. When provided, results are filtered to that user.
Request format
- All
POST/PATCHbodies must be JSON withContent-Type: application/json. GETparameters are passed as query string values.- File uploads use
multipart/form-data.
Response format
Successful responses return JSON. The shape varies by endpoint — see the individual reference pages.
Error format
All errors follow a consistent envelope:
| HTTP status | When |
|---|---|
400 | Malformed request body or missing required fields |
401 | Missing or invalid x-api-key |
403 | Valid key but insufficient permissions |
404 | Resource not found |
409 | Conflict (e.g. duplicate payment reference) |
422 | Validation failed |
429 | Rate limit exceeded |
500 | Internal server error |
Rate limits
All limits use a sliding window algorithm scoped per tenant (by API key), except the RPC endpoint which is scoped per user.
| Endpoint | Limit | Scope |
|---|---|---|
POST /api/file-processing/extract | 20 req / min | per tenant |
POST /api/payments/initialize | 10 req / min | per tenant |
POST /api/student-emails/bulk | 5 req / min | per tenant |
POST /api/rpc/[...orpc] | 120 req / min | per user |
| All other routes | 60 req / min | per tenant |
Response headers
Every response (including successful ones) includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests allowed in the window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp (milliseconds) when the window resets |
429 response
When the limit is exceeded you receive HTTP 429 with an additional Retry-After header:
Retry strategy
Use Retry-After as your wait floor before retrying:
Info
The @nexa-ed/sdk handles 429 automatically with one built-in retry using the
Retry-After header. If the retry also fails, a NexaError with code
RATE_LIMITED is thrown.
Webhook verification
When Nexa delivers webhook events to your server, each request is signed with HMAC-SHA256. Verify the signature before processing any event.
Headers sent by Nexa:
| Header | Value |
|---|---|
x-nexa-signature | Hex-encoded HMAC-SHA256 of body + timestamp |
x-nexa-timestamp | Unix timestamp (seconds) when the event was signed |
Verification (Python example):
Verification (Go example):
Quick reference
| Category | Docs |
|---|---|
| File processing | REST API → File Processing |
| Payments | REST API → Payments |
| Documents & records | REST API → Documents |
| Student email provisioning | REST API → Student Emails |