Courses & training
Udemy
Coupons, course updates, announcements and revenue for instructors.
11 endpoints
Your AI agent enrolls new learners, tags graduates, grades the Review Center queue and nudges stalled learners, with your OK before anything reaches a learner. Sign in to your school's admin once in your own Cloud Browser. No API plan to buy and no code to keep running.
11 tools Read and write
LearnWorlds has a REST API (v2) and webhooks, but they come with the Learning Center plan and above, $249 a month billed annually or $299 monthly. It has no official MCP server (checked 6 Nov 2026). Cotlet runs 11 LearnWorlds tools hosted, 6 of them writes, over MCP for agents and REST for scripts.
| What you need | LearnWorlds API | Zapier | Cotlet |
|---|---|---|---|
| List users and course progress | Yes, with your code | Triggers, no lists | Yes, as data |
| Enroll and unenroll users | Yes, with your code | Yes, as actions | Yes, after your OK |
| Add or remove tags | Yes, with your code | Yes, as actions | Yes |
| Suspend or unsuspend a user | Yes, with your code | No action | Yes, after your OK |
| Grade Review Center assessments | Yes, with your code | Trigger only | Yes, after your OK |
| Send a direct message to a user | No endpoint | No | Yes, after your OK |
| What it takes to start | Learning Center plan and a developer | A Zap per job | Your admin login |
Checked 6 Nov 2026. Sources: LearnWorlds Help: LearnWorlds API documentation · LearnWorlds Help: How to request your API keys and access tokens · LearnWorlds Help: How to monitor, segment and export user progress · LearnWorlds pricing · Zapier: LearnWorlds integrations · LearnWorlds: Extended API and webhooks · GitHub: ohneben/Learnworlds-MCP
Once, in a browser we host for you.
Add one address to its settings.
It prepares the work, you OK each change.
We never keep your LearnWorlds password, and no enrollment, message, suspension or grade reaches a learner until you approve it. Who can see your session
Enable LearnWorlds for agents. Create a Cotlet account, sign in to your school's admin in its Cloud Browser as the admin the agent should act as, then press Enable for agents.
Add the Cotlet address. Enter https://cotlet.dev/mcp/v1 in your agent as a remote MCP server or custom connector.
Approve the link. Chat apps ask you to sign in to Cotlet once. Editors, n8n and scripts send an API key from the console.
https://cotlet.dev/mcp/v1 carries LearnWorlds next to your other apps. The tools act with the admin role of the user you sign in as, so pick an admin who can reach Users, Courses and the Review Center. Refresh the connector after enabling LearnWorlds so the tools load.
Settings > Connectors > Add custom connector
URL: https://cotlet.dev/mcp/v1/connect
Claude Code:
claude mcp add --transport http cotlet-learnworlds \
https://cotlet.dev/mcp/v1 \
--header "Authorization: Bearer $COTLET_API_KEY" Settings > Apps & Connectors > Create
MCP server URL: https://cotlet.dev/mcp/v1/connect
Authentication: OAuth // ~/.cursor/mcp.json
{
"mcpServers": {
"cotlet-learnworlds": {
"url": "https://cotlet.dev/mcp/v1",
"headers": { "Authorization": "Bearer ${env:COTLET_API_KEY}" }
}
}
} # ~/.codex/config.toml
[mcp_servers.cotlet-learnworlds]
url = "https://cotlet.dev/mcp/v1"
bearer_token_env_var = "COTLET_API_KEY" MCP Client Tool (inside an AI Agent)
Transport: HTTP Streamable
URL: https://cotlet.dev/mcp/v1
Auth: Bearer, <your key>
Tool: learnworlds_read Make: MCP Client > Call a tool
Zapier: MCP Client by Zapier > Run Tool
Server URL: https://cotlet.dev/mcp/v1
Token: <your key>
Tool: learnworlds_write Suspended users sit on their own list and show up only when you ask. Tags are created when a tag does not exist yet.
Returns users the way Users > All users shows them, newest sign-up first. Search by name or email and filter by tag. user_id goes into get_user, enroll_users, unenroll_users, update_tags, send_message and suspend_user. Suspended users are not in this list; they sit on their own Suspended users list and appear only when you pass suspended true.
MCP calllearnworlds_read → list_users
REST endpointGET https://cotlet.dev/api/v1/learnworlds/users
| Name | Type | Description |
|---|---|---|
| query string | string | Part of a name or email. |
| tag string | string | Tag name as shown in Users > Tags. |
| suspended boolean | boolean | true lists the Suspended users instead. Default: false. |
| limit integer | integer | Rows to return. |
{
"users": [
{
"user_id": "5f3a9c1e2b7d4a0011c8e601",
"name": "Lena Fischer",
"email": "lena.fischer@example.com",
"tags": [
"newsletter"
],
"signed_up": "2026-11-03"
},
{
"user_id": "5f3a9c1e2b7d4a0011c8e602",
"name": "Marco Bianchi",
"email": "marco.bianchi@example.com",
"tags": [
"cohort-autumn"
],
"signed_up": "2026-11-02"
}
]
} Opens the user card and returns the profile, the tags and each product the user is enrolled in, with progress and the expiration date where one is set. A course the user finished by hand shows completed_manually true, as the admin dashboard marks it "Completed (Manually)". Use it to check before enrolling or messaging.
MCP calllearnworlds_read → get_user
REST endpointGET https://cotlet.dev/api/v1/learnworlds/users/{user_id}
| Name | Type | Description |
|---|---|---|
| user_id string required | string | user_id from list_users. |
{
"user_id": "user_8c41d2"
} {
"user_id": "5f3a9c1e2b7d4a0011c8e601",
"name": "Lena Fischer",
"email": "lena.fischer@example.com",
"tags": [
"newsletter"
],
"products": [
{
"product": "Photography Basics",
"progress_percent": 60,
"completed_manually": false,
"expires": null
}
]
} Uses Suspend Account on the Users page. A suspended user cannot log in and cannot sign up again with the same email, and moves to the Suspended users list. Suspending does not pause or cancel the user's active payments, so cancel those where you take payments. A call with suspended false lifts it. By default you confirm each call; you can switch that off for this tool.
MCP calllearnworlds_write → set_user_suspended
REST endpointPUT https://cotlet.dev/api/v1/learnworlds/users/{user_id}/suspended
| Name | Type | Description |
|---|---|---|
| user_id string required | string | user_id from list_users. |
| suspended boolean required | boolean | true suspends, false lifts the suspension. |
{
"user_id": "user_8c41d2",
"suspended": true
} {
"user_id": "5f3a9c1e2b7d4a0011c8e603",
"name": "Tom Walker",
"suspended": true
} Courses only: bundles and subscription plans are enrolled from the user card. A user who is already in comes back as skipped.
Returns the courses of the school as the Courses page shows them. course_id goes into list_course_users and enroll_users. It reads courses only; bundles and subscription plans are enrolled from the user card and are not covered here.
MCP calllearnworlds_read → list_courses
REST endpointGET https://cotlet.dev/api/v1/learnworlds/courses
| Name | Type | Description |
|---|---|---|
| query string | string | Part of a course title. |
{
"courses": [
{
"course_id": "photography-basics",
"title": "Photography Basics",
"status": "published",
"enrolled": 128
},
{
"course_id": "editing-masterclass",
"title": "Editing Masterclass",
"status": "published",
"enrolled": 54
}
]
} Reads the Course Users tab of the course insights. Each row has the completion date, units completed, certificate date and score, as that tab shows them. Filter by status to get only learners who finished or only those still in progress. Rows are ordered as the tab orders them. Free courses are missing from the Users report export, so this tool reads the course page instead.
MCP calllearnworlds_read → list_course_users
REST endpointGET https://cotlet.dev/api/v1/learnworlds/course-users
| Name | Type | Description |
|---|---|---|
| course_id string required | string | course_id from list_courses. |
| status enum | enum | completed or in_progress. Default: both. |
| limit integer | integer | Rows to return. |
{
"course_id": "course_8c41d2"
} {
"course": "Photography Basics",
"users": [
{
"user_id": "5f3a9c1e2b7d4a0011c8e601",
"name": "Lena Fischer",
"units_completed": 9,
"completion_date": null,
"certificate_date": null,
"score": null
},
{
"user_id": "5f3a9c1e2b7d4a0011c8e602",
"name": "Marco Bianchi",
"units_completed": 14,
"completion_date": "2026-11-01",
"certificate_date": "2026-11-01",
"score": 88
}
]
} Enrolls the listed users through the Enroll to Product action of the Users page. Each enrollment can carry its own expiration date. The learner gets access to the product at once. A user who is already enrolled is returned in skipped. Subscription plans need the Stripe gateway and are enrolled one user at a time, so they are not part of this tool. By default you confirm each call; you can switch that off for this tool.
MCP calllearnworlds_write → enroll_users
REST endpointPOST https://cotlet.dev/api/v1/learnworlds/courses/{course_id}/users/enroll
| Name | Type | Description |
|---|---|---|
| course_id string required | string | course_id from list_courses. |
| user_ids array required | array | user_id values from list_users. |
| expires string | string | Expiration date, YYYY-MM-DD. Default: no expiration. |
{
"course_id": "photography-basics",
"user_ids": [
"5f3a9c1e2b7d4a0011c8e601",
"5f3a9c1e2b7d4a0011c8e602"
],
"expires": "2027-05-01"
} {
"product": "Photography Basics",
"enrolled": [
{
"user_id": "5f3a9c1e2b7d4a0011c8e601",
"name": "Lena Fischer"
},
{
"user_id": "5f3a9c1e2b7d4a0011c8e602",
"name": "Marco Bianchi"
}
],
"skipped": []
} Unenrolls the listed users from one course. The learners lose access to it. Read the enrollment with get_user first. A Zapier trigger named User Unenrolled From Product fires on the school, so connected automations can react. By default you confirm each call; you can switch that off for this tool.
MCP calllearnworlds_write → unenroll_users
REST endpointPOST https://cotlet.dev/api/v1/learnworlds/courses/{course_id}/users/unenroll
| Name | Type | Description |
|---|---|---|
| course_id string required | string | course_id from list_courses. |
| user_ids array required | array | user_id values from list_users. |
{
"course_id": "course_8c41d2",
"user_ids": "user ids"
} {
"product": "Photography Basics",
"unenrolled": [
{
"user_id": "5f3a9c1e2b7d4a0011c8e602",
"name": "Marco Bianchi"
}
]
} Open-ended answers wait in the Unreviewed tab for a manual grade. Feedback is text only, and a message goes to one user per call.
Returns the Unreviewed tab of the Review Center: the learner, the course, the assessment and when it was submitted. Open-ended questions (text, file upload, record video) wait here for a manual grade. review_id goes into grade_assessment.
MCP calllearnworlds_read → list_pending_reviews
REST endpointGET https://cotlet.dev/api/v1/learnworlds/pending-reviews
| Name | Type | Description |
|---|---|---|
| course_id string | string | Only reviews of this course. |
{
"reviews": [
{
"review_id": "rv_7d21a4",
"learner": "Lena Fischer",
"course": "Photography Basics",
"assessment": "Final project",
"submitted": "2026-11-04"
}
]
} Opens Review Assessment for the review, sets a numeric score and a written comment, and clicks Submit Review. That makes the grade and the feedback visible to the learner. Feedback as a file, audio or video is not part of this tool. By default you confirm each call; you can switch that off for this tool.
MCP calllearnworlds_write → grade_assessment
REST endpointPOST https://cotlet.dev/api/v1/learnworlds/reviews/{review_id}/assessment/grade
| Name | Type | Description |
|---|---|---|
| review_id string required | string | review_id from list_pending_reviews. |
| score number required | number | Numeric score for the assessment. |
| feedback string | string | Written feedback shown to the learner. |
{
"review_id": "review_8c41d2",
"score": 1
} {
"review_id": "rv_7d21a4",
"learner": "Lena Fischer",
"assessment": "Final project",
"score": 85,
"feedback": "Strong composition. Work on exposure in the second shot.",
"status": "reviewed"
} Uses the Send Message action in the three-dot menu of Users > All users. The user receives the message. It sends to one user per call, so the agent loops over a list. Write the subject and body plainly; the tool sends what you give it. By default you confirm each call; you can switch that off for this tool.
MCP calllearnworlds_write → send_message
REST endpointPOST https://cotlet.dev/api/v1/learnworlds/users/{user_id}/messages
| Name | Type | Description |
|---|---|---|
| user_id string required | string | user_id from list_users. |
| subject string required | string | Message subject. |
| body string required | string | Message text. |
{
"user_id": "user_8c41d2",
"subject": "subject",
"body": "body"
} {
"sent_to": {
"user_id": "5f3a9c1e2b7d4a0011c8e601",
"name": "Lena Fischer"
},
"subject": "Your project is waiting"
} Your signed-in LearnWorlds browser profile, AES-256-GCM encrypted, in Finland. No password.
The 11 LearnWorlds tools. Never the session cookie.
What your admin role sees: users, tags, courses, enrollments and the Review Center.
Payments, plans, school design, course content and deleting users.
You sign in again in the Cloud Browser. We never type the password.
Disable for agents, reset the browser, or remove that admin in your school.
Our site scores A+ on Qualys SSL Labs, securityheaders.com and Mozilla Observatory (live results). Cotlet has no SOC 2 report or third-party pentest yet.
| Plan | Price | API and webhooks |
|---|---|---|
| Starter | $49 a month, $44 billed annually | No |
| Pro Trainer | $99 a month, $79 billed annually | No |
| Learning Center | $299 a month, $249 billed annually | Yes |
| Corporate | Custom | Yes |
LearnWorlds released a new platform version in 2025 and kept its API at v2, while the admin screens changed with it. When a menu or a field changes, the fix happens on our side and your prompts keep working. status.cotlet.dev checks the site, console and API every 3 minutes.
| Action | Undo |
|---|---|
| Enroll users | Unenroll them; the learner had access in between |
| Unenroll users | Enroll them again |
| Update tags | One call with the opposite lists |
| Suspend a user | Call again with suspended false |
| Send a message | No, the user has it |
| Grade an assessment | No tool call; the learner sees it at once |
5 of 11 tools ask first: enroll_users, unenroll_users, send_message, set_user_suspended, grade_assessment. Each one gives a learner access, takes it away, mails them or shows them a grade. Tag changes reach nobody directly, and the 5 reads run at once. Switch the wait off per tool for a scheduled run.
Suspending a user does not pause or cancel their active payments. Cancel those where you take payments.
{
"name": "enroll_users",
"arguments": {
"course_id": "photography-basics",
"user_ids": [
"5f3a9c1e2b7d4a0011c8e601",
"5f3a9c1e2b7d4a0011c8e602"
],
"expires": "2027-05-01"
}
} curl -X POST https://cotlet.dev/api/v1/learnworlds/courses/photography-basics/users/enroll \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user_ids":["5f3a9c1e2b7d4a0011c8e601","5f3a9c1e2b7d4a0011c8e602"],"expires":"2027-05-01"}' {
"product": "Photography Basics",
"enrolled": [
{
"user_id": "5f3a9c1e2b7d4a0011c8e601",
"name": "Lena Fischer"
},
{
"user_id": "5f3a9c1e2b7d4a0011c8e602",
"name": "Marco Bianchi"
}
],
"skipped": []
} A script or a nightly job calls the same tools over REST at /api/v1/learnworlds, with one key and one price, and no LearnWorlds API keys of your own. A call LearnWorlds refuses, such as a feature your admin role lacks, costs nothing. The tools table gives the REST path of each tool.
About $20 a monthfor a school enrolling about 40 learners a month, 3,420 credits. Your LearnWorlds plan is billed by LearnWorlds as before.
| Job | Calls | Credits |
|---|---|---|
| Enroll the week's sign-ups | 6 × 4 | 240 |
| Friday completion report | 4 × 4 | 160 |
| Tag graduates, each workday | 4 × 22 | 880 |
| Grade the Review Center queue | 9 × 4 | 360 |
| Message stalled learners | 7 × 4 | 280 |
| Cloud Browser, 30 days | 1,500 | |
| Total | 3,420 |
LearnWorlds publishes no usage per school. Its own cost guide uses a creator enrolling 50 learners a month, so the month is our example of 40. Plans cap active learners at 1,000 on Starter and 2,000 above it. Dollars at the $29 pack rate.
| Credits | Price, one time | Calls at 10 credits | Per 1,000 credits |
|---|---|---|---|
| 5,000 | $29 | 500 | $5.80 |
| 15,000 | $79 | 1,500 | $5.27 |
| 32,000 | $149 | 3,200 | $4.66 |
| 60,000 | $249 | 6,000 | $4.15 |
Only successful calls use credits; failed calls and timeouts cost nothing. At a balance of 0 calls pause, never a surprise charge. Authenticate with the Authorization: Bearer header.
| Option | What it does | Where it stops |
|---|---|---|
| LearnWorlds API v2 | Official REST and webhooks: users, courses, enrollments, tags, suspensions, assessment reviews. | Learning Center plan and above, and your code. No endpoint to message a user. |
| ohneben/Learnworlds-MCP | Community MCP server on the API: all 94 endpoints as tools, stdio or Streamable HTTP, MIT, 2 stars. | You host it and keep the API token, so the API plan applies. Last commit 15 Sep 2026. |
| Pipedream LearnWorlds MCP | Hosted MCP server at mcp.pipedream.net/v2. | You sign in to Pipedream to see its tools; we could not list them without an account. |
| Zapier | Official app: instant triggers such as Assessment Completed and Course Completed, actions to enroll, unenroll, tag and create users. | Fixed steps. No list reads, suspend, grading or messages. Make has a help center article too. |
If your school is on the Learning Center plan and you have a developer, the API is official and covers nearly every job on this page. A community MCP server turns it into tools. When an admin wants an agent to run the enrollments, tags and grading today, without an API plan, keys or code, that is the part Cotlet covers.
Take Group sp. z o.o. builds and runs Cotlet. It is a software company registered in Poland, EU (VAT PL6342984273), operating since 2019 and founded by Bart Krawczyk (Co-founder, CTO) and Jake Slugocki (Co-founder, SEO, sales and marketing). Questions about the LearnWorlds tools go to contact@cotlet.dev.
Sign up at cotlet.dev, log in to LearnWorlds once in its Cloud Browser and add Cotlet to ChatGPT or Claude, following the steps in your console. No API key is needed. ChatGPT and Claude then work in your LearnWorlds account through Cotlet, in their phone apps too.
With Cotlet, ChatGPT, Claude and other AI agents handle jobs like these in LearnWorlds: enroll a list of learners in a course; weekly course completion report; tag learners who finished a course. You ask in plain words, and anything that reaches other people waits for your OK first.
Sign up free at https://cotlet.dev, open LearnWorlds under Integrations in the console and sign in to your school admin in its Cloud Browser. The trial starts with your first app, and no card is asked.
The Learning Center plan or higher. LearnWorlds' help center says the progress export through the API is available on Learning Center and higher plans, and its pricing page points to Learning Center for tools like API. Cotlet works in your own admin session, so it follows what your admin dashboard offers on your plan.
Yes, the ones in Courses > Review Center. Open-ended questions (text, file upload, record video) wait there for a manual grade, and Submit Review shows the score and written feedback to the learner. Each grade asks for your OK by default.
Yes, on the Learning Center plan and above. They send events such as registrations and enrollments to a URL you set under Settings > Developers > Webhooks. Cotlet does not receive them. Run your agent on a schedule instead, for example a daily list_course_users pass.
No. Cotlet works in your school admin with your own login, so there are no API keys to request. If you have the API, both can run side by side.
Only in how it is called. Both carry the same 11 tools, inputs and answers, with one API key and one price. Agents use MCP; scripts and HTTP steps use REST.
No. Cotlet is independent and not affiliated with LearnWorlds (CY) Ltd.
Free 7-day trial with 2,000 credits, no card needed.
May we use Google Analytics to see which pages help people? It sets cookies only if you accept. No ads, and we never sell data. Cookie policy