# Newlege Public API — v1 Programmatic access to a Newlege academy: students, courses, enrollments, transactions. Built for backends, automation tools (Zapier / Make / n8n), and AI agents (Claude, ChatGPT, Gemini). - **Base URL:** `https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1` - **Auth:** Bearer token in the `Authorization` header - **Format:** JSON request/response, UTF-8 - **Stability:** v1.0 stable Every request is scoped to a single academy through its API key. The API can never return data belonging to another academy — isolation is enforced at the database layer. --- ## Authentication All requests must include: ``` Authorization: Bearer nl_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ``` Generate keys in the dashboard: **Settings → Integrations → Public API**. The plaintext token is shown **once** on creation — store it in a secret manager. ```bash curl https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1/me \ -H "Authorization: Bearer nl_live_..." ``` ## Scopes Each key carries a list of scopes. Endpoints reject requests whose key lacks the required scope with HTTP 403. | Scope | Grants | | --------------------- | ----------------------------------- | | `students:read` | List and read students | | `students:write` | Create and update students | | `courses:read` | List and read courses | | `enrollments:read` | List enrollments | | `enrollments:write` | Enroll a student in a course | | `transactions:read` | List billing transactions | ## Rate limits Default: **60 requests / minute / key**. Every response includes `X-RateLimit-Limit` and `X-RateLimit-Remaining`. Exceeding returns HTTP 429 with error code `rate_limited`. ## Errors Stable envelope: ```json { "error": { "code": "forbidden_scope", "message": "Missing required scope: students:read" }, "request_id": "b3a1..." } ``` | Code | HTTP | Meaning | | ------------------- | ---- | ----------------------------------------------- | | `unauthorized` | 401 | Missing, invalid, expired, or revoked key | | `forbidden_scope` | 403 | Key lacks the scope required by the endpoint | | `not_found` | 404 | Resource does not exist in this academy | | `validation_error` | 400 | Request body or query parameters are invalid | | `rate_limited` | 429 | Exceeded the per-minute limit for this key | | `internal` | 500 | Unexpected server error — retry with backoff | ## Pagination List endpoints accept `limit` (max 100, default 50) and `cursor`. Response includes `pagination.next_cursor` when more results exist. ```bash curl "https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1/students?limit=25&cursor=2025-06-01T10:00:00Z" \ -H "Authorization: Bearer nl_live_..." ``` --- ## Endpoints ### GET /me Returns the academy associated with the current key, plus the key's scopes. ```bash curl https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1/me -H "Authorization: Bearer nl_live_..." ``` ```json { "data": { "academy_id": "f2e486a9-...", "academy_name": "Itai Barak Academy", "academy_slug": "itai-barak", "plan": "premium", "scopes": ["students:read", "courses:read"] }, "request_id": "..." } ``` ### GET /students Requires `students:read`. Returns members of the academy with the student role. ```bash curl https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1/students -H "Authorization: Bearer nl_live_..." ``` ```json { "data": [ { "id": "8c1d...", "email": "student@example.com", "full_name": "John Doe", "phone": "+972501234567", "status": "active", "created_at": "2025-06-01T10:00:00Z" } ], "pagination": { "has_more": false, "next_cursor": null }, "request_id": "..." } ``` ### GET /students/{id} Requires `students:read`. ```bash curl https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1/students/8c1d... -H "Authorization: Bearer nl_live_..." ``` ### GET /courses Requires `courses:read`. ```bash curl https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1/courses -H "Authorization: Bearer nl_live_..." ``` ### GET /courses/{id} Requires `courses:read`. ### GET /enrollments Requires `enrollments:read`. Optional filters: `course_id`, `student_id`. ```bash curl "https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1/enrollments?course_id=COURSE_ID" \ -H "Authorization: Bearer nl_live_..." ``` ### POST /enrollments Requires `enrollments:write`. Grants a student access to a course. Both must already exist in this academy. ```bash curl -X POST https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1/enrollments \ -H "Authorization: Bearer nl_live_..." \ -H "Content-Type: application/json" \ -d '{ "student_id": "STUDENT_UUID", "course_id": "COURSE_UUID" }' ``` ### GET /transactions Requires `transactions:read`. ```bash curl https://cuabhknytckerifjaple.supabase.co/functions/v1/public-api/v1/transactions -H "Authorization: Bearer nl_live_..." ``` --- ## Use with Claude / ChatGPT / Gemini Both Claude Projects and OpenAI custom GPTs support adding HTTP tools / actions. Import the OpenAPI spec from `https://newlege.co.il/openapi.json` and add an `Authorization: Bearer nl_live_...` header. Then ask the model things like *"list my newest 10 students"* or *"enroll user X in course Y"*. A native MCP server is coming in Phase 2 — it will expose every endpoint as a typed MCP tool for Claude Desktop and Cursor. ## Use with Zapier / Make / n8n Use the generic **HTTP / Webhook** action. Set the URL to one of the endpoints above, add `Authorization: Bearer nl_live_...`, and for POSTs send JSON. Example: *"When a row is added in Google Sheets → POST /enrollments"*. ## Changelog - **v1.0** — Initial release. Endpoints: `/me`, `/students`, `/courses`, `/enrollments`, `/transactions`. Support: support@newlege.co.il