Developers

Website API

Build your own website, mobile app or integration on top of an organisation's VLearned content: programmes, courses, instructors, events, news, testimonials and pages. You can also send contact-form enquiries.

REST + JSON No API key for public content CORS enabled Version 1

Overview

Every endpoint is scoped to one organisation by its slug, the first part of its website address. For acme.vlearned.com the slug is acme.

Base URLhttps://vlearned.com/apis/v1
AuthenticationNone. These endpoints only return content the organisation has published publicly.
FormatJSON responses. Send Accept: application/json. Dates use ISO 8601.
CORSAllowed from any origin, so you can call the API directly from browser JavaScript.
AvailabilityReturns 404 if the organisation is inactive or has switched its website off.

Quick start

Fetch an organisation's latest courses:

curl -H "Accept: application/json" \
  "https://vlearned.com/apis/v1/organisations/your-organisation/courses?per_page=6"

The same request from a web page:

const res = await fetch('https://vlearned.com/apis/v1/organisations/your-organisation/courses?per_page=6', {
  headers: { Accept: 'application/json' },
});
const { data, meta } = await res.json();
data.forEach((course) => console.log(course.title, course.url));

Responses and errors

Single records are wrapped in data. Lists that support paging also include meta:

{
  "data": [ { "id": 12, "slug": "intro-to-data", "title": "Intro to Data", "...": "..." } ],
  "meta": { "current_page": 1, "last_page": 3, "per_page": 12, "total": 31, "organisation": "your-organisation" }
}
StatusMeaning
200Success.
201Enquiry received.
404Organisation, website or record not found, or not public.
422Validation failed. The body lists errors per field under errors.
429Too many requests. Wait and retry; see Retry-After.

Rate limits

Read endpoints allow 120 requests per minute per IP address. Enquiry submissions allow 5 per minute. The X-RateLimit-Limit and X-RateLimit-Remaining headers show your current allowance. Cache responses on your side where you can.

Organisation

GET /organisations/{slug}

Organisation profile: name, logo, colours, tagline, about text, contact details, headline stats and website address.

GET /organisations/{slug}/website

Website settings: theme, announcement bar, hero, homepage section order, call to action, menus and social links.

Learning catalogue

GET /organisations/{slug}/programmes

Published public programmes, featured first.

QueryDescription
qSearch by name or summary
per_page1 to 50, default 12
pagePage number
GET /organisations/{slug}/programmes/{programme}

One programme by slug or ID, including its description, outcomes, requirements, courses and admission settings.

GET /organisations/{slug}/courses

Published public courses, newest first.

QueryDescription
qSearch by title or summary
per_page1 to 50, default 12
pagePage number
GET /organisations/{slug}/courses/{course}

One course by slug or ID, including objectives, the curriculum (sections and lesson titles) and whether learners enrol or apply.

GET /organisations/{slug}/instructors

Instructors with a public profile: name, bio, photo, subjects, languages and rating.

Website content

GET /organisations/{slug}/events

Published events.

QueryDescription
whenupcoming (default), past or all
per_page1 to 50, default 12
pagePage number
GET /organisations/{slug}/events/{slug}

One event with its full description.

GET /organisations/{slug}/news

Published news articles, newest first.

QueryDescription
per_page1 to 50, default 12
pagePage number
GET /organisations/{slug}/news/{slug}

One article with its full content.

GET /organisations/{slug}/testimonials

Published testimonials in display order.

GET /organisations/{slug}/pages

Published custom pages (slug, title, address).

GET /organisations/{slug}/pages/{slug}

One custom page with content and SEO fields.

Enquiries

POST /organisations/{slug}/enquiries

Send a contact-form message to the organisation. It appears in the admin under Website → Enquiries. Returns 404 if the organisation has switched its contact form off.

FieldDescription
nameRequired, up to 120 characters
emailRequired, valid email
phoneOptional
subjectOptional, up to 160 characters
messageRequired, 10 to 5000 characters

Examples

Course object

{
  "id": 12,
  "slug": "intro-to-data",
  "title": "Intro to Data",
  "short_description": "Learn the basics of data analysis.",
  "thumbnail_url": "https://...",
  "category": "Data",
  "price": "49.00",
  "discount_price": null,
  "currency": "MYR",
  "is_free": false,
  "level": "beginner",
  "total_lessons": 18,
  "instructor": { "id": 7, "name": "Aisha Rahman" },
  "published_at": "2026-09-01T08:00:00+00:00",
  "url": "https://your-organisation.vlearned.com/catalogue/intro-to-data",
  "admission": {
    "mode": "apply",
    "applications_open": true,
    "deadline": "2026-12-15",
    "questions": ["What is your highest qualification?"],
    "action_url": "https://your-organisation.vlearned.com/apply/course/intro-to-data"
  }
}

Enrolment and applications

Every course and programme includes an admission object. When mode is enrol, learners join directly (paid courses go through checkout first). When it is apply, learners submit an application that the organisation reviews. Send learners to action_url: they sign in or create an account on the organisation's website and then enrol, pay or apply there. Enrolment and payment always happen on the organisation's website, never through this API.

Send an enquiry

curl -X POST "https://vlearned.com/apis/v1/organisations/your-organisation/enquiries" \
  -H "Accept: application/json" -H "Content-Type: application/json" \
  -d '{"name":"Sam Lee","email":"sam@example.com","subject":"January intake","message":"Is there still space in the January intake?"}'
{ "data": { "id": "9d2c...", "received_at": "2026-10-12T09:30:00+00:00" }, "message": "Thank you. Your message has been received." }

Show upcoming events on any website

<ul id="events"></ul>
<script>
  fetch('https://vlearned.com/apis/v1/organisations/your-organisation/events?per_page=3')
    .then((r) => r.json())
    .then(({ data }) => {
      document.getElementById('events').innerHTML = data
        .map((e) => `<li><a href="${e.url}">${e.title}</a> – ${new Date(e.starts_at).toLocaleDateString()}</li>`)
        .join('');
    });
</script>

Other APIs

Signed-in features such as enrolments, progress, assessments and administration use the authenticated platform API. Read about tokens, scopes and endpoints in the platform API reference.

Need higher limits, webhooks or help with an integration? Contact us at info@aismartuallearning.com.