API Reference
The LearningAcademy.io API lets you programmatically manage your academy — create courses, invite students, track enrollments, and receive real-time webhook events.
https://your-academy.learningacademy.io/api
application/json
Bearer la_live_...
Authentication
All API requests require a valid API key sent in the Authorization header.
You can create API keys from your admin dashboard under Settings → Integrations.
la_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keys use the la_live_ prefix. Your raw key is shown only once at creation — store it securely.
curl https://your-academy.learningacademy.io/api/courses \
-H "Authorization: Bearer la_live_your_api_key_here" \
-H "Content-Type: application/json"
Never expose your API key in client-side code, public repos, or frontend JavaScript. Treat it like a password.
Scopes
API keys can be scoped to limit access. Available scopes:
all Full access to all endpointsread:students Read student datawrite:students Create/update studentsread:payments Read payment historyread:enrollments Read enrollment datawrite:enrollments Create enrollmentswebhooks:manage Manage webhooksRate Limits
API requests are rate-limited to ensure fair usage across all academies.
| Plan | Rate Limit | Burst |
|---|---|---|
| Pro | 1,000 requests/minute | 50 concurrent |
| Custom/Enterprise | Custom limits | Contact sales |
Error Handling
The API uses standard HTTP status codes. Errors return a JSON body with a message field.
| Status | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request — invalid parameters |
| 401 | Unauthorized — missing or invalid API key |
| 403 | Forbidden — insufficient permissions or plan |
| 404 | Not Found |
| 429 | Rate Limit Exceeded |
| 500 | Internal Server Error |
{
"message": "API key is required",
"error": "unauthorized"
}
/api/courses
List all courses in your academy. Returns courses scoped to your tenant.
Response
[
{
"id": 1,
"title": "Onboarding 101",
"description": "Complete onboarding course",
"imageUrl": "https://...",
"accessLevel": "paid",
"price": "49.99",
"paymentType": "one_time",
"published": true,
"tenantId": 1,
"createdAt": "2026-01-15T10:30:00.000Z",
"lessonCount": 12
}
]
cURL Example
curl https://your-academy.learningacademy.io/api/courses \
-H "Authorization: Bearer la_live_your_api_key_here"
/api/courses/:id
Get a single course by ID, including its modules and lessons.
Path Parameters
id integer — Course ID requiredcURL Example
curl https://your-academy.learningacademy.io/api/courses/1 \
-H "Authorization: Bearer la_live_your_api_key_here"
/api/courses
Create a new course in your academy. Requires admin privileges and a Pro plan.
Request Body
title string requireddescription stringimageUrl string — Cover image URLaccessLevel string — "free", "paid", "recruitpro"price string — Price in dollars (e.g. "49.99")paymentType string — "one_time" or "subscription"cURL Example
curl -X POST https://your-academy.learningacademy.io/api/courses \
-H "Authorization: Bearer la_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"title": "Advanced Sales Training",
"description": "Master advanced sales techniques",
"accessLevel": "paid",
"price": "99.00",
"paymentType": "one_time"
}'
/api/admin/users
List all users (students and admins) in your academy.
Response
[
{
"id": "user_abc123",
"email": "student@example.com",
"firstName": "Jane",
"lastName": "Doe",
"role": "jobseeker",
"tenantId": 1,
"createdAt": "2026-01-20T08:00:00.000Z"
}
]
cURL Example
curl https://your-academy.learningacademy.io/api/admin/users \
-H "Authorization: Bearer la_live_your_api_key_here"
/api/courses/:id/grant-access
Grant a user free access to a course by email. If the user exists, they are enrolled immediately. If not, an invite is generated.
Request Body
email string requiredtype string — "grant" (free) or "purchase" (sends purchase invite)cURL Example
curl -X POST https://your-academy.learningacademy.io/api/courses/1/grant-access \
-H "Authorization: Bearer la_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"email": "newstudent@example.com",
"type": "grant"
}'
/api/courses/:id/invite
Send a course invitation email to a prospective student. Generates a unique invite token.
Request Body
email string requiredcURL Example
curl -X POST https://your-academy.learningacademy.io/api/courses/1/invite \
-H "Authorization: Bearer la_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"email": "student@example.com"}'
/api/courses/:id/enroll
Enroll the authenticated user in a course. Used for free courses or manual enrollment.
cURL Example
curl -X POST https://your-academy.learningacademy.io/api/courses/1/enroll \
-H "Authorization: Bearer la_live_your_api_key_here"
/api/courses/:id/students
List all students enrolled in a specific course, including their progress.
cURL Example
curl https://your-academy.learningacademy.io/api/courses/1/students \
-H "Authorization: Bearer la_live_your_api_key_here"
/api/downloads
List all downloadable resources (PDFs, templates, files) in your academy.
cURL Example
curl https://your-academy.learningacademy.io/api/downloads \
-H "Authorization: Bearer la_live_your_api_key_here"
/api/downloads
Create a new downloadable resource.
Request Body
title string requireddescription stringfileUrl string requiredcategory stringaccessLevel string — "free", "paid", "recruitpro"cURL Example
curl -X POST https://your-academy.learningacademy.io/api/downloads \
-H "Authorization: Bearer la_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"title": "Sales Playbook",
"description": "Complete guide to closing deals",
"fileUrl": "https://example.com/playbook.pdf",
"category": "Templates",
"accessLevel": "paid"
}'
Webhook Events
LearningAcademy.io can send real-time webhook notifications to your endpoints when events happen in your academy. Configure webhooks from Settings → Integrations → Webhooks.
| Event | Description | Trigger |
|---|---|---|
| student.created | New student registered | User signs up under your academy |
| purchase.created | New purchase completed | Stripe checkout succeeds |
| payment.succeeded | Payment received | Stripe payment confirmed |
| payment.failed | Payment failed | Stripe payment declined |
| subscription.created | New subscription started | Recurring plan activated |
| subscription.canceled | Subscription canceled | Student cancels plan |
| access.granted | Access granted to course | Enrollment or manual grant |
| access.revoked | Access revoked from course | Admin removes access |
Webhook Payloads
Every webhook delivery sends a JSON POST with event-specific data. Here are sample payloads for the most common events:
student.created
{
"event": "student.created",
"timestamp": "2026-02-26T10:30:00.000Z",
"data": {
"userId": "user_abc123",
"email": "student@example.com",
"firstName": "Jane",
"lastName": "Doe",
"role": "jobseeker",
"tenantId": 1
}
}
purchase.created
{
"event": "purchase.created",
"timestamp": "2026-02-26T10:30:00.000Z",
"data": {
"courseId": 1,
"courseTitle": "Onboarding 101",
"userId": "user_abc123",
"email": "student@example.com",
"amount": 4999,
"currency": "usd",
"stripeSessionId": "cs_live_abc123"
}
}
access.granted
{
"event": "access.granted",
"timestamp": "2026-02-26T10:30:00.000Z",
"data": {
"courseId": 1,
"courseTitle": "Onboarding 101",
"userId": "user_abc123",
"email": "student@example.com",
"grantedBy": "admin"
}
}
Signature Verification
Every webhook delivery is signed with HMAC-SHA256 so you can verify it came from LearningAcademy.io. The signing secret is shown once when you create the webhook endpoint.
Webhook Headers
X-LA-Signature HMAC-SHA256 hex digestX-LA-Timestamp Unix timestamp (seconds)X-LA-Event Event name (e.g. student.created)X-LA-Delivery Unique delivery ID (UUID)How to Verify
The signature is computed as: HMAC-SHA256(secret, "${timestamp}.${rawBody}")
Node.js Example
const crypto = require('crypto');
function verifyWebhook(req, secret) {
const signature = req.headers['x-la-signature'];
const timestamp = req.headers['x-la-timestamp'];
const rawBody = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Python Example
import hmac, hashlib, json
def verify_webhook(headers, body, secret):
signature = headers.get('X-LA-Signature')
timestamp = headers.get('X-LA-Timestamp')
raw_body = json.dumps(body, separators=(',', ':'))
expected = hmac.new(
secret.encode(),
f"{timestamp}.{raw_body}".encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
To use with Zapier, create a Webhooks by Zapier trigger (Catch Hook), paste the URL into your webhook settings, and subscribe to the events you need. For signature verification, add a Zapier Code by Zapier step using the Node.js example above.
Retry Policy
Failed deliveries are retried with exponential backoff:
After 10 failed attempts, the delivery is marked as permanently failed (dead-letter).
/api/tenant/api-keys
List all API keys for your academy. Raw key values are never returned — only the prefix is shown.
cURL Example
curl https://your-academy.learningacademy.io/api/tenant/api-keys \
-H "Authorization: Bearer la_live_your_api_key_here"
/api/tenant/api-keys
Create a new API key. The raw key is returned only once in the response — store it immediately.
Request Body
name string — Label for the key requiredscopes string[] — e.g. ["all"] or ["read:students", "read:enrollments"] requiredexpiresAt string — ISO date (optional)cURL Example
curl -X POST https://your-academy.learningacademy.io/api/tenant/api-keys \
-H "Authorization: Bearer la_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Zapier Integration",
"scopes": ["read:students", "read:enrollments"]
}'
Response (key shown once)
{
"key": {
"id": 1,
"name": "Zapier Integration",
"keyPrefix": "la_live_a1b2",
"scopes": ["read:students", "read:enrollments"],
"createdAt": "2026-02-26T10:00:00.000Z"
},
"rawKey": "la_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4"
}
/api/tenant/api-keys/:id/revoke
Permanently revoke an API key. Revoked keys can no longer be used for authentication.
cURL Example
curl -X POST https://your-academy.learningacademy.io/api/tenant/api-keys/1/revoke \
-H "Authorization: Bearer la_live_your_api_key_here"