Skip to content

API Reference

Marty McEnroe edited this page Feb 19, 2026 · 4 revisions

API Reference

Technical reference for Aletheia's backend API.


Overview

Aletheia's backend exposes two Lambda functions via CloudFlare-proxied Function URLs:

  • Agent Lambda — Text analysis (etymology, context)
  • Auth Lambda — Authentication, billing, admin endpoints

Base URL

https://api.aletheia.study

All requests pass through CloudFlare Workers for rate limiting and DDoS protection.


Authentication

Most endpoints require JWT authentication via the Authorization header:

Authorization: Bearer <jwt_token>

JWTs are obtained via LinkedIn OAuth sign-in (see Authentication Flow).

JWT Claims

{
  "user_id": "linkedin_sub_claim",
  "tier": "free|subscriber|admin",
  "billing_anchor_day": 1,
  "exp": 1739900000,
  "iat": 1739813600,
  "jti": "uuid"
}

Analysis Endpoints

POST / (Analyze Text)

Analyze text for etymology and context. Requires JWT.

Request

POST /
Authorization: Bearer <jwt>
Content-Type: application/json
{
  "text": "string (required)",
  "context": "string (optional)",
  "url": "string (optional)"
}
Field Type Required Description
text string Yes The text to analyze (max 500 chars)
context string No Surrounding context for disambiguation
url string No Source URL for context

Response

{
  "signal": "green|yellow|orange|red",
  "gem": "string",
  "explanation": "string",
  "etymology": {
    "origin": "string",
    "period": "string",
    "evolution": "string"
  }
}

Authentication Endpoints

POST /auth/token

Exchange LinkedIn OAuth authorization code for a JWT. Public.

{
  "code": "linkedin_auth_code",
  "redirect_uri": "extension_redirect_uri"
}

Response:

{
  "jwt": "eyJ...",
  "user_id": "12345",
  "tier": "free",
  "expires_in": 86400
}

POST /auth/refresh

Refresh an expiring JWT. Public (valid JWT in body).

GET /auth/validate

Validate a JWT and return its claims. Public (Bearer token in header).

GET /auth/callback

LinkedIn OAuth callback handler. Public.


Billing Endpoints

POST /create-checkout-session

Create a Stripe Checkout session for subscription upgrade. Requires JWT.

{
  "success_url": "https://...",
  "cancel_url": "https://..."
}

Response:

{
  "checkout_url": "https://checkout.stripe.com/..."
}

GET /subscription-status

Get current subscription status. Requires JWT.

Response:

{
  "tier": "free|subscriber",
  "stripe_subscription_id": "sub_...",
  "grace_period": null
}

POST /stripe-webhook

Stripe webhook handler. Stripe signature verification (no JWT).

Handles: checkout.session.completed, invoice.paid, invoice.payment_failed, customer.subscription.deleted.

POST /redeem-coupon

Redeem a coupon code for a tier upgrade. Requires JWT.

{
  "code": "COUPON_CODE"
}

Admin Endpoints

GET /metrics

Admin business metrics dashboard. Requires JWT (admin tier).

Response:

{
  "total_users": 42,
  "users_by_tier": {"free": 38, "subscriber": 4},
  "active_subscriptions": 4,
  "mrr_cents": 3996,
  "active_coupons": 2
}

Data Management

DELETE /my-data

GDPR data erasure — delete all user data. Requires Bearer token.


Error Responses

400 Bad Request

{"error": "bad_request", "message": "Text field is required"}

401 Unauthorized

{"error": "unauthorized", "message": "Invalid or expired token"}

429 Too Many Requests

{
  "error": "rate_limit_exceeded",
  "window": "daily",
  "resets_at": "2026-02-17T00:00:00Z",
  "resets_in_seconds": 86400,
  "upgrade_url": "https://aletheia.study/upgrade"
}

500 Internal Server Error

{"error": "internal_error", "message": "An unexpected error occurred"}

Rate Limits

CloudFlare Edge (All Users)

Limit Value
Requests per 10 seconds per IP 3

Per-User (by Tier)

Tier Hourly Daily Monthly
Free 3 20 100
Subscriber 30 500 5,000
Admin 1,000 10,000 100,000

CORS

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization

Last updated: 2026-02-19

Clone this wiki locally