diff --git a/course/externallib.php b/course/externallib.php
index ec8e627..c8256d5 100644
--- a/course/externallib.php
+++ b/course/externallib.php
@@ -29,5 +29,99 @@ defined('MOODLE_INTERNAL') || die;
 require_once("$CFG->libdir/externallib.php");
 
 class moodle_course_external extends external_api {
+    /**
+     * Returns description of method parameters
+     * @return external_function_parameters
+     */
+    public static function create_courses_parameters() {
+        global $CFG;
 
-}
\ No newline at end of file
+        return new external_function_parameters(
+            array(
+                'courses' => new external_multiple_structure(
+                    new external_single_structure(
+                        array(
+                            'category'      => new external_value(PARAM_INT),
+                            'fullname'      => new external_value(PARAM_RAW),
+                            'shortname'     => new external_value(PARAM_RAW),
+                            'idnumber'      => new external_value(PARAM_RAW),
+                            'summary'       => new external_value(PARAM_RAW),
+                            'summaryformat' => new external_value(PARAM_INT),
+                            'format'        => new external_value(PARAM_ALPHA),
+                            'startdate'     => new external_value(PARAM_INT)
+                        )
+                    )
+                )
+            )
+        );
+    }
+
+    /**
+     * Create one or more courses
+     *
+     * @param array $courses  An array of courses to create.
+     * @return array An array of arrays
+     */
+    public static function create_courses($courses) {
+        global $CFG, $DB;
+        require_once($CFG->dirroot."/course/lib.php");
+
+        // Ensure the current user is allowed to run this function
+        $context = get_context_instance(CONTEXT_SYSTEM);
+        self::validate_context($context);
+        require_capability('moodle/course:create', $context);
+
+        // Do basic automatic PARAM checks on incoming data, using params description
+        // If any problems are found then exceptions are thrown with helpful error messages
+        $params = self::validate_parameters(self::create_courses_parameters(), array('courses'=>$courses));
+
+        $availablethemes = get_plugin_list('theme');
+        $availablelangs  = get_string_manager()->get_list_of_translations();
+
+        $transaction = $DB->start_delegated_transaction();
+
+        $courseids = array();
+        foreach ($params['courses'] as $course) {
+            // Make sure that the shortname doesn't already exist
+            if ($DB->record_exists('course', array('shortname'=>$course['shortname']))) {
+                throw new invalid_parameter_exception('Shortname already exists: '.$course['shortname']);
+            }
+
+            // Make sure lang is valid
+            if (empty($availablelangs[$course['lang']])) {
+                throw new invalid_parameter_exception('Invalid language code: '.$course['lang']);
+            }
+
+            // Make sure lang is valid
+            if (!empty($course['theme']) && empty($availablethemes[$course['theme']])) { //theme is VALUE_OPTIONAL,
+                                                                                     // so no default value.
+                                                                                     // We need to test if the client sent it
+                                                                                     // => !empty($course['theme'])
+                throw new invalid_parameter_exception('Invalid theme: '.$course['theme']);
+            }
+
+            $course['id'] = create_course($course)->id;
+
+            $courseids[] = array('id'=>$course['id'], 'shortname'=>$course['shortname']);
+        }
+
+        $transaction->allow_commit();
+
+        return $courseids;
+    }
+
+   /**
+     * Returns description of method result value
+     * @return external_description
+     */
+    public static function create_courses_returns() {
+        return new external_multiple_structure(
+            new external_single_structure(
+                array(
+                    'id'       => new external_value(PARAM_INT, 'course id'),
+                    'shortname' => new external_value(PARAM_RAW, 'short name'),
+                )
+            )
+        );
+    }
+}
