--- name: moodle-external-api-development description: "This skill guides you through creating custom external web service APIs for Moodle LMS, following Moodle's external API framework and coding standards." risk: critical source: community date_added: "2026-02-27" --- # Moodle External API Development This skill guides you through creating custom external web service APIs for Moodle LMS, following Moodle's external API framework and coding standards. ## Detailed Guide Read [the detailed guide](references/detailed-guide.md) before executing this skill. It retains the complete procedure and reference material. Treat its safety, prerequisites, and validation requirements as mandatory. For focused work, load the relevant sections; for end-to-end work, read the guide completely. ## When to Use This Skill - Creating custom web services for Moodle plugins - Implementing REST/AJAX endpoints for course management - Building APIs for quiz operations, user tracking, or reporting - Exposing Moodle functionality to external applications - Developing mobile app backends using Moodle ## Examples from Real Implementation ### Simple Read API (Get Quiz Attempts) ```php libdir/externallib.php"); use external_api; use external_function_parameters; use external_single_structure; use external_value; class get_quiz_attempts extends external_api { public static function execute_parameters() { return new external_function_parameters([ 'userid' => new external_value(PARAM_INT, 'User ID'), 'courseid' => new external_value(PARAM_INT, 'Course ID') ]); } public static function execute($userid, $courseid) { global $DB; self::validate_parameters(self::execute_parameters(), [ 'userid' => $userid, 'courseid' => $courseid ]); $sql = "SELECT COUNT(*) AS quiz_attempts FROM {quiz_attempts} qa JOIN {quiz} q ON qa.quiz = q.id WHERE qa.userid = :userid AND q.course = :courseid"; $attempts = $DB->get_field_sql($sql, [ 'userid' => $userid, 'courseid' => $courseid ]); return ['quiz_attempts' => (int)$attempts]; } public static function execute_returns() { return new external_single_structure([ 'quiz_attempts' => new external_value(PARAM_INT, 'Total number of quiz attempts') ]); } } ``` ### Complex Write API (Create Quiz from Categories) See attached `create_quiz_from_categories.php` for a comprehensive example including: - Multiple database insertions - Course module creation - Quiz instance configuration - Random question selection with tags - Group-based access restrictions - Extensive error logging - Transaction management ## Limitations - Use this skill only when the task clearly matches the scope described above. - Do not treat the output as a substitute for environment-specific validation, testing, or expert review. - Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.