Base URLs

EnvironmentBase URLPurpose
Localhttp://localhost:8080Development — OTP is always 123456, no SMS sent
Sandboxhttps://sandbox.api.aarokya.inIntegration testing — Juspay sandbox, no real payments
Productionhttps://api.aarokya.inLive environment — real OTPs, real payments
All endpoints accept and return application/json unless otherwise noted.

Versioning

The API is currently unversioned — all paths are at root (e.g. /auth/otp/trigger). A /v1/ prefix will be introduced before the first public release. Changes will be communicated with:
  1. A changelog entry in this documentation
  2. Deprecation header (Deprecation: true) on endpoints being replaced
  3. A minimum 3-month parallel operation period before old endpoints are removed

Versioning Strategy

Once versioned, we will use URI path versioning:
https://api.aarokya.in/v1/auth/otp/trigger
https://api.aarokya.in/v2/auth/otp/trigger   ← breaking change
Non-breaking changes (new optional fields, new endpoints) will be added within the existing version without incrementing. Breaking changes (removed fields, changed types, altered semantics) will bump the version.

Common Headers

Request Headers

HeaderRequiredDescription
Content-TypeYes (for POST/PATCH)Always application/json
AuthorizationYes (protected endpoints)Bearer <access_token>
X-Request-IDRecommendedClient-generated UUID for request tracing
X-App-VersionRecommendedApp version string (e.g. 1.2.3)
X-PlatformRecommendedios | android | web

Response Headers

HeaderDescription
Content-TypeAlways application/json; charset=utf-8
X-Request-IDEchoed from request, or server-generated if not provided
X-RateLimit-LimitMax requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the rate limit window resets
Always send X-Request-ID — a UUID you generate per request. If something goes wrong, this ID appears in server logs and makes debugging dramatically faster. Contact support with the request ID to trace exactly what happened.

Request Format

curl https://api.aarokya.in/user/profile \
  -H 'Authorization: Bearer <access_token>' \
  -H 'X-Request-ID: 550e8400-e29b-41d4-a716-446655440000'

Authentication

Protected endpoints require a JWT access token in the Authorization header:
Authorization: Bearer <access_token>
Obtain an access token via POST /auth/otp/verify. See the Authentication guide for full details on token lifecycle and refresh.

Public Endpoints (no auth required)

MethodPathNotes
POST/auth/otp/triggerStarts login flow
POST/auth/otp/verifyCompletes login, returns tokens
POST/auth/token/refreshRefreshes token pair
GET/healthHealth check for load balancers
GET/api_docs/openapi.jsonOpenAPI spec
GET/api_docs/uiSwagger UI

Response Envelope

All successful responses return JSON directly (no outer wrapper). Error responses use a consistent envelope — see Error Reference.
{
  "user_id": "a3f8c2d1-...",
  "phone": "9876543210",
  "first_name": "Priya",
  "profile_complete": true
}

Pagination

Endpoints that return lists (e.g. insurance plans, transaction history) use cursor-based pagination where applicable. Query parameters:
ParameterTypeDefaultDescription
limitinteger20Maximum items per page (max 100)
cursorstringOpaque cursor from previous response
Paginated responses include a meta field:
{
  "plans": [...],
  "meta": {
    "total": 45,
    "limit": 20,
    "has_more": true,
    "next_cursor": "eyJpZCI6IjEwMCJ9"
  }
}
Pagination is not yet implemented on the current stub endpoints. Transaction history is capped at 10 entries. Full pagination will be added when live Juspay and NH integrations are complete.

Rate Limits

Endpoint GroupLimitWindow
POST /auth/otp/trigger5 requests / phone1 minute
POST /auth/otp/verify5 attempts per OTP sessionPer session
POST /auth/token/refresh10 requests / user1 minute
All other endpoints300 requests / user1 minute
Exceeding rate limits returns 429 Too Many Requests with:
{
  "error": "RATE_LIMIT_EXCEEDED",
  "message": "Too many requests. Please slow down.",
  "status_code": 429,
  "retry_after": 47
}
The retry_after field (seconds) indicates when the limit resets.

Request ID Tracking

Every request can include an X-Request-ID header with a UUID you generate. The server:
  1. Logs the request ID alongside every log line for that request
  2. Echoes it in the response header
If you experience an error, share the X-Request-ID with Aarokya support — it maps directly to the full request trace in the server logs.
// Example: generate and attach X-Request-ID in TypeScript
const requestId = crypto.randomUUID();

const response = await fetch('https://api.aarokya.in/user/profile', {
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'X-Request-ID': requestId,
  }
});

// Log it for debugging
console.log('Request ID:', requestId);

OpenAPI Spec

The full machine-readable spec is available at:
GET /api_docs/openapi.json
An interactive Swagger UI is served at:
GET /api_docs/ui
Use the Try It Out tab above to explore all endpoints interactively.

Health Check

GET /health
Returns 200 OK with no authentication required. Used by load balancers, uptime monitors, and Kubernetes readiness probes.
{
  "status": "ok",
  "version": "0.1.0",
  "timestamp": "2025-06-14T10:30:00Z"
}