MENU navbar-image

Introduction

The Teachfloor API is organized around REST. Our API has predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

Base URL

https://api.teachfloor.com

Authenticating requests

This API is authenticated by sending an Authorization header with the value "Bearer {YOUR_API_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

You can retrieve your API Key in Settings > Integrations and clicking Generate API Key.

Rate Limiting

Example response:

HTTP/1.1 200 OK
X-RateLimit-Limit:	50
X-RateLimit-Remaining:	48

Teachfloor API has a rate limit of 50 requests per minute per API Key.

Each HTTP response includes headers indicating the rate limit status: X-RateLimit-Limit specifies the rate limit per minute, and X-RateLimit-Remaining indicates the remaining rate limit available.

Activities

Retrieve an Activity

Requires Authentication

Retrieves the details of an existing activity in your organization based on the provided unique activity ID. The response includes comprehensive information about the activity, such as its score, timestamps, associated element details, and related metadata.

If the activity is performed by an individual, the member key contains the details of the member who completed the activity.
If the activity is performed by a group, the members key provides a list of all members who participated in the activity.

The meta object contains additional details and metadata about the activity's completion status. It provides context on the outcome and participant of the activity.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/activities/p5v87ERWKR3dkjyD" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/activities/p5v87ERWKR3dkjyD',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/activities/p5v87ERWKR3dkjyD"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
"error": null,
"payload": {
     "id": "KwJ8VgrmlAp4PBnM",
     "object": "activity",
     "timestamp" : "2022-11-27T13:52:02.000000Z",
     "status": "PASSED",
     "passed": true,
     "score": 100,
     "completed_by": "6K8vojJn1xe14abL",
     "member": {
         "id": "6K8vojJn1xe14abL",
         "object": "member",
         "first_name": "Adalberto",
         "last_name": "Bruen",
         "full_name": "Adalberto Bruen",
         "avatar": null,
         "email": "iva52@example.org",
         "is_email_verified": true,
         "last_seen": "2024-11-27T13:51:52.000000Z"
     },
     "context": {
         "id": "QB8nmEJjqdbLA2K5",
         "object": "element",
         "created_at": "2024-11-26T11:37:16.000000Z",
         "name": "Multiple Choice Quiz",
         "cover": null,
         "type": "QUIZ",
         "position": 3,
         "course": "B4peAvmZ1L9OY3Xr",
         "module": "no0aApWNyRMD68rv",
         "metadata": {}
     }
}
 

Request   

GET v0/activities/{id}

URL Parameters

id  string  

The ID of the requested activity.

List all Activities

Requires Authentication

Returns a list of activities within your organization. The activities are sorted by their creation date, with the most recently created activities appearing first. Each activity in the list includes information such as the score, dates, element data and more.

If the activity is performed by an individual, the member key contains the details of the member who completed the activity.
If the activity is performed by a group, the members key provides a list of all members who participated in the activity.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/activities?course=B4peAvmZ1L9OY3Xr&module=no0aApWNyRMD68rv&element=QB8nmEJjqdbLA2K5&member=6K8vojJn1xe14abL&page=2" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/activities',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'course'=> 'B4peAvmZ1L9OY3Xr',
            'module'=> 'no0aApWNyRMD68rv',
            'element'=> 'QB8nmEJjqdbLA2K5',
            'member'=> '6K8vojJn1xe14abL',
            'page'=> '2',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/activities"
);

const params = {
    "course": "B4peAvmZ1L9OY3Xr",
    "module": "no0aApWNyRMD68rv",
    "element": "QB8nmEJjqdbLA2K5",
    "member": "6K8vojJn1xe14abL",
    "page": "2",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
"error": null,
"payload": {
   "data": [
       {
           "id": "KwJ8VgrmlAp4PBnM",
           "object": "activity",
           "timestamp" : "2022-11-27T13:52:02.000000Z",
           "status": "PASSED",
           "passed": true,
           "score": 100,
           "completed_by": "6K8vojJn1xe14abL",
           "member": {
               "id": "6K8vojJn1xe14abL",
               "object": "member",
               "first_name": "Adalberto",
               "last_name": "Bruen",
               "full_name": "Adalberto Bruen",
               "avatar": null,
               "email": "iva52@example.org",
               "is_email_verified": true,
               "last_seen": "2024-11-27T13:51:52.000000Z"
           },
           "context": {
               "id": "QB8nmEJjqdbLA2K5",
               "object": "element",
               "created_at": "2024-11-26T11:37:16.000000Z",
               "name": "Multiple Choice Quiz",
               "cover": null,
               "type": "QUIZ",
               "position": 3,
               "course": "B4peAvmZ1L9OY3Xr",
               "module": "no0aApWNyRMD68rv",
               "metadata": {}
           }
       },
       {...},
       {...},
   ],
   "pagination": {
       "total": 3,
       "count": 3,
       "per_page": 10,
       "current_page": 1,
       "total_pages": 1
   }
}
 

Request   

GET v0/activities

Query Parameters

course  string optional  

The unique ID to filter activities by course

module  string optional  

The unique ID to filter activities by module

element  string optional  

The unique ID to filter activities by element

member  string optional  

The unique ID to filter activities by member

page  integer optional  

A cursor for pagination across multiple pages of results.

Courses

Requires Authentication

Search for existing courses in your organization. You can search by course name. The search is case-insensitive and supports partial matches.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/courses/search" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"q\": \"Marketing\"
}"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/courses/search',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'q' => 'Marketing',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/search"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "q": "Marketing"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "p5v87ERWKR3dkjyD",
        "object": "course",
        "name": "Ultimate Marketing Course",
        "status": "PUBLISHED",
        "created_at": "2022-02-03T16:06:42.000000Z",
        "cover": null,
        "availability": "CONTINUOUS",
        "visibility": "PRIVATE",
        "start_date": null,
        "end_date": null,
        "currency": "eur",
        "price": null,
        "url": null,
        "public_url": null,
        "join_url": null,
        "metadata": {},
        "custom_fields": {
          "field_1": {
            "key": "field_1",
            "object": "custom-field",
            "created_at": "2024-07-30T16:05:47.000000Z",
            "name": "Multiple Field Question",
            "description": null,
            "type": "MULTIPLE_OPTIONS",
            "options": [
                "Option A",
                "Option B",
                "Option C"
            ],
            "required": false
          }
        }
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 5,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 1
    }
  }
}
 

Retrieve a Course

Requires Authentication

Retrieves the details of an existing course in your organization based on the provided unique course ID. Returns a comprehensive information about the course, including its name, availability, status, dates, and more.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "p5v87ERWKR3dkjyD",
        "object": "course",
        "name": "Ultimate Marketing Course",
        "status": "PUBLISHED",
        "created_at": "2022-02-03T16:06:42.000000Z",
        "cover": null,
        "availability": "CONTINUOUS",
        "visibility": "PRIVATE",
        "start_date": null,
        "end_date": null,
        "currency": "eur",
        "price": null,
        "content": null,
        "url": null,
        "public_url": null,
        "join_url": null,
        "metadata": {},
        "custom_fields": {
            "field_1": {
                "key": "field_1",
                "object": "custom-field",
                "created_at": "2024-07-30T16:05:47.000000Z",
                "name": "Multiple Field Question",
                "description": null,
                "type": "MULTIPLE_OPTIONS",
                "options": [
                    "Option A",
                    "Option B",
                    "Option C"
                ],
                "required": false
            }
        }
    }
}
 

Request   

GET v0/courses/{id}

URL Parameters

id  string  

The ID of the requested course.

List all Courses

Requires Authentication

Returns a list of courses within your organization. The courses are sorted by their creation date, with the most recently created courses appearing first. Each course in the list includes information such as the course name, availability, status, dates, and more.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/courses?page=2" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/courses',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'page'=> '2',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses"
);

const params = {
    "page": "2",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "p5v87ERWKR3dkjyD",
        "object": "course",
        "name": "Ultimate Marketing Course",
        "status": "PUBLISHED",
        "created_at": "2022-02-03T16:06:42.000000Z",
        "cover": null,
        "availability": "CONTINUOUS",
        "visibility": "PRIVATE",
        "start_date": null,
        "end_date": null,
        "currency": "eur",
        "price": null,
        "url": null,
        "public_url": null,
        "join_url": null,
        "metadata": {},
        "custom_fields": {
          "field_1": {
            "key": "field_1",
            "object": "custom-field",
            "created_at": "2024-07-30T16:05:47.000000Z",
            "name": "Multiple Field Question",
            "description": null,
            "type": "MULTIPLE_OPTIONS",
            "options": [
                "Option A",
                "Option B",
                "Option C"
            ],
            "required": false
          }
        }
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 15,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 2
    }
  }
}
 

Request   

GET v0/courses

Query Parameters

page  integer optional  

A cursor for pagination across multiple pages of results.

Join a Course

Requires Authentication

Joins a member in one of your courses.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/join" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"member\": \"e7W6kP8wvjd3GRBz\",
    \"role\": \"lecturer\"
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/join',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'member' => 'e7W6kP8wvjd3GRBz',
            'role' => 'lecturer',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/join"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "member": "e7W6kP8wvjd3GRBz",
    "role": "lecturer"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": null
}
 

Request   

POST v0/courses/{id}/join

URL Parameters

id  string  

The ID of the course to enroll.

Body Parameters

member  string  

The unique ID of the member who is being added to the course.

role  string optional  

The role to assign to the member inside the course. If not set the member will be enrolled to the course as a customer. To assign an instructor or assiatant to the course use lecturer or assistant. Must be one of customer, lecturer, or assistant.

Revoke Course Access

Requires Authentication

Revokes a member access to a course.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/revoke" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"member\": \"e7W6kP8wvjd3GRBz\"
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/revoke',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'member' => 'e7W6kP8wvjd3GRBz',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/revoke"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "member": "e7W6kP8wvjd3GRBz"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": null
}
 

Request   

POST v0/courses/{id}/revoke

URL Parameters

id  string  

The ID of the course from which the member should be revoked.

Body Parameters

member  string  

The ID of the member to revoke access to the course.

Create a Course

Requires Authentication

Creates a course in your organization. Returns the created course details upon successful creation.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/courses" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Ultimate Marketing Course\",
    \"content\": \"# Introduction\\\\nWelcome to the **Ultimate Marketing Course**.\",
    \"availability\": \"CONTINUOUS\",
    \"start_date\": \"2023-07-12\",
    \"end_date\": \"2023-07-26\",
    \"visibility\": \"PUBLIC\",
    \"metadata\": {
        \"category\": \"marketing\"
    }
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/courses',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Ultimate Marketing Course',
            'content' => '# Introduction\\nWelcome to the **Ultimate Marketing Course**.',
            'availability' => 'CONTINUOUS',
            'start_date' => '2023-07-12',
            'end_date' => '2023-07-26',
            'visibility' => 'PUBLIC',
            'metadata' => [
                'category' => 'marketing',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Ultimate Marketing Course",
    "content": "# Introduction\\nWelcome to the **Ultimate Marketing Course**.",
    "availability": "CONTINUOUS",
    "start_date": "2023-07-12",
    "end_date": "2023-07-26",
    "visibility": "PUBLIC",
    "metadata": {
        "category": "marketing"
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "p5v87ERWKR3dkjyD",
        "object": "course",
        "name": "Ultimate Marketing Course",
        "status": "PUBLISHED",
        "created_at": "2022-02-03T16:06:42.000000Z",
        "cover": null,
        "availability": "CONTINUOUS",
        "visibility": "PRIVATE",
        "start_date": null,
        "end_date": null,
        "currency": "eur",
        "price": null,
        "content": "# Introduction\nWelcome to the **Ultimate Marketing Course**.",
        "url": null,
        "public_url": null,
        "join_url": null,
        "metadata": {},
        "custom_fields": {
            "field_1": {
                "key": "field_1",
                "object": "custom-field",
                "created_at": "2024-07-30T16:05:47.000000Z",
                "name": "Multiple Field Question",
                "description": null,
                "type": "MULTIPLE_OPTIONS",
                "options": [
                    "Option A",
                    "Option B",
                    "Option C"
                ],
                "required": false
            }
        }
    }
}
 

Request   

POST v0/courses

Body Parameters

name  string optional  

The course name. Must not be greater than 255 characters.

content  string optional  

The course content in markdown format. Supports headings, bold, italic, strikethrough, highlights, inline code, code blocks, blockquotes, lists, tables, images, links, and math (LaTeX).

availability  string optional  

The course availability. Must be one of: CONTINUOUS, SCHEDULED. Must be one of CONTINUOUS or SCHEDULED.

start_date  string optional  

If the course availability is set to SCHEDULED, this defines the course schedule start. Specify the date in YYYY-MM-DD format. This field is required when availability is SCHEDULED. Must be a valid date.

end_date  string optional  

If the course availability is set to SCHEDULED, this defines the course schedule end. Specify the date in YYYY-MM-DD format. This field is required when availability is SCHEDULED or date. Must be a date after or equal to start_date.

visibility  string optional  

The course visibility inside your organization. A course with PUBLIC visibility is shown to all the members of your organization. A course with PRIVATE visibility is shown only to the members of the course but is hidden by the other members of your organization. Must be one of PUBLIC or PRIVATE.

metadata  string optional  

Metadata is an attribute that lets you store more information, structured as key-value pairs, for your own use and reference.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Keys and values are stored as strings and can contain any characters with one exception: you can't use square brackets ([ and ]) in keys.

List all Course Members

Requires Authentication

Returns a list of members within the course.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/members" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"include_test_user\": true
}"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/members',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'include_test_user' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/members"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "include_test_user": true
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "6jO9XN7mZEVpvxqo",
        "object": "course_member",
        "joined_at": "2024-01-22T12:56:04.000000Z",
        "member": {
          "id": "e7W6kP8wvjd3GRBz",
          "object": "member",
          "first_name": "John",
          "last_name": "Doe",
          "full_name": "John Doe",
          "avatar": null,
          "email": null,
          "is_email_verified": false,
          "last_seen": "2024-01-22T12:56:04.000000Z"
        },
        "course": {
          "id": "p5v87ERWKR3dkjyD",
          "object": "course",
          "name": "Ultimate Marketing Course",
          "status": "PUBLISHED",
          "created_at": "2022-02-03T16:06:42.000000Z",
          "cover": null,
          "availability": "CONTINUOUS",
          "visibility": "PRIVATE",
          "start_date": null,
          "end_date": null,
          "currency": "eur",
          "price": null,
          "url": null,
          "public_url": null,
          "join_url": null,
          "metadata": {},
          "custom_fields": {
            "field_1": {
              "key": "field_1",
              "object": "custom-field",
              "created_at": "2024-07-30T16:05:47.000000Z",
              "name": "Multiple Field Question",
              "description": null,
              "type": "MULTIPLE_OPTIONS",
              "options": [
                  "Option A",
                  "Option B",
                  "Option C"
              ],
              "required": false
            }
          }
        },
        "custom_fields": {
          "field_1": [
            "Option A",
            "Option B"
          ]
        }
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 15,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 2
    }
  }
}
 

Request   

GET v0/courses/{id}/members

URL Parameters

id  string  

The ID of the course from which the members should be retrieved.

Body Parameters

include_test_user  boolean optional  

Include test users to the results if set to true.

List all Course Modules

Requires Authentication

Returns a list of modules within the course.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/courses/LZ6dN0DGgBD3QjxB/modules" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/courses/LZ6dN0DGgBD3QjxB/modules',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/LZ6dN0DGgBD3QjxB/modules"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "LZ6dN0DGgBD3QjxB",
        "object": "module",
        "created_at": "2024-01-22T12:55:11.000000Z",
        "name": "Lesson #1",
        "type": "LESSON",
        "availability": "CONTINUOUS",
        "position": 0,
        "course": "B4peAvmZ1L9OY3Xr",
        "metadata": {}
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 15,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 2
    }
  }
}
 

Request   

GET v0/courses/{id}/modules

URL Parameters

id  string  

The ID of the course from which the modules should be retrieved.

List all Course Elements

Requires Authentication

Returns a list of elements within the course.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/courses/WYxKj5OlrekVAGr7/elements" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/courses/WYxKj5OlrekVAGr7/elements',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/WYxKj5OlrekVAGr7/elements"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "WYxKj5OlrekVAGr7",
        "object": "element",
        "created_at": "2024-01-22T12:55:11.000000Z",
        "name": "Introduction",
        "cover": null,
        "type": "CONTENT",
        "position": 0,
        "module": "LZ6dN0DGgBD3QjxB",
        "metadata": {},
        "properties": {}
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 15,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 2
    }
  }
}
 

Request   

GET v0/courses/{id}/elements

URL Parameters

id  string  

The ID of the course from which the elements should be retrieved.

Update a Course

Requires Authentication

Updates the details of an existing course in your organization based on the provided unique course ID. Any parameters not provided will be left unchanged. Returns the updated course details upon successful update.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Ultimate Marketing Course\",
    \"content\": \"# Introduction\\\\nWelcome to the **Ultimate Marketing Course**.\",
    \"availability\": \"CONTINUOUS\",
    \"start_date\": \"2023-07-12\",
    \"end_date\": \"2023-07-26\",
    \"visibility\": \"PUBLIC\",
    \"metadata\": {
        \"category\": \"marketing\"
    }
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Ultimate Marketing Course',
            'content' => '# Introduction\\nWelcome to the **Ultimate Marketing Course**.',
            'availability' => 'CONTINUOUS',
            'start_date' => '2023-07-12',
            'end_date' => '2023-07-26',
            'visibility' => 'PUBLIC',
            'metadata' => [
                'category' => 'marketing',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Ultimate Marketing Course",
    "content": "# Introduction\\nWelcome to the **Ultimate Marketing Course**.",
    "availability": "CONTINUOUS",
    "start_date": "2023-07-12",
    "end_date": "2023-07-26",
    "visibility": "PUBLIC",
    "metadata": {
        "category": "marketing"
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "p5v87ERWKR3dkjyD",
        "object": "course",
        "name": "Ultimate Marketing Course",
        "status": "PUBLISHED",
        "created_at": "2022-02-03T16:06:42.000000Z",
        "cover": null,
        "availability": "CONTINUOUS",
        "visibility": "PRIVATE",
        "start_date": null,
        "end_date": null,
        "currency": "eur",
        "price": null,
        "content": "# Introduction\nWelcome to the **Ultimate Marketing Course**.",
        "url": null,
        "public_url": null,
        "join_url": null,
        "metadata": {},
        "custom_fields": {
            "field_1": {
                "key": "field_1",
                "object": "custom-field",
                "created_at": "2024-07-30T16:05:47.000000Z",
                "name": "Multiple Field Question",
                "description": null,
                "type": "MULTIPLE_OPTIONS",
                "options": [
                    "Option A",
                    "Option B",
                    "Option C"
                ],
                "required": false
            }
        }
    }
}
 

Request   

POST v0/courses/{id}

URL Parameters

id  string  

The ID of the requested course to update.

Body Parameters

name  string optional  

The course name. Must not be greater than 255 characters.

content  string optional  

The course content in markdown format. Supports headings, bold, italic, strikethrough, highlights, inline code, code blocks, blockquotes, lists, tables, images, links, and math (LaTeX).

availability  string optional  

The course availability. Must be one of: CONTINUOUS, SCHEDULED. Must be one of CONTINUOUS or SCHEDULED.

start_date  string optional  

If the course availability is set to SCHEDULED, this defines the course schedule start. Specify the date in YYYY-MM-DD format. This field is required when availability is SCHEDULED. Must be a valid date.

end_date  string optional  

If the course availability is set to SCHEDULED, this defines the course schedule end. Specify the date in YYYY-MM-DD format. This field is required when availability is SCHEDULED or date. Must be a date after or equal to start_date.

visibility  string optional  

The course visibility inside your organization. A course with PUBLIC visibility is shown to all the members of your organization. A course with PRIVATE visibility is shown only to the members of the course but is hidden by the other members of your organization. Must be one of PUBLIC or PRIVATE.

metadata  string optional  

Metadata is an attribute that lets you store more information, structured as key-value pairs, for your own use and reference.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Keys and values are stored as strings and can contain any characters with one exception: you can't use square brackets ([ and ]) in keys.

Delete a Course

Requires Authentication

Deletes a course in your organization. Returns an object with a deleted parameter upon successful deletion.

Example request:
curl --request DELETE \
    "https://api.teachfloor.com/v0/courses/1" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->delete(
    'https://api.teachfloor.com/v0/courses/1',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "id": "p5v87ERWKR3dkjyD",
    "object": "course",
    "deleted": true,
  }
}
 

Request   

DELETE v0/courses/{id}

URL Parameters

id  integer  

The ID of the course.

Retrieve a Course Member

Requires Authentication

Retrieves the details of a specific member in a course, including their progress data.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/members/e7W6kP8wvjd3GRBz" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/members/e7W6kP8wvjd3GRBz',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/courses/p5v87ERWKR3dkjyD/members/e7W6kP8wvjd3GRBz"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "6jO9XN7mZEVpvxqo",
        "object": "course_member",
        "joined_at": "2024-01-22T12:56:04.000000Z",
        "member": {
            "id": "e7W6kP8wvjd3GRBz",
            "object": "member",
            "first_name": "John",
            "last_name": "Doe",
            "full_name": "John Doe",
            "avatar": null,
            "email": "john@example.com",
            "is_email_verified": true,
            "last_seen": "2024-01-22T12:56:04.000000Z"
        },
        "course": {
            "id": "p5v87ERWKR3dkjyD",
            "object": "course",
            "name": "Ultimate Marketing Course"
        },
        "custom_fields": {},
        "progress": {
            "is_completed": false,
            "completion_percentage": 65,
            "completed_elements_count": 8,
            "total_elements_count": 12,
            "completed_modules_count": 3,
            "total_modules_count": 5,
            "started_at": "2024-01-22T12:56:04.000000Z",
            "completed_at": null
        }
    }
}
 

Request   

GET v0/courses/{id}/members/{member_id}

URL Parameters

id  string  

The ID of the course.

member_id  string  

The ID of the member.

Elements

List all activites

Requires Authentication

Returns a list of activites related to the element.

If the activity is performed by an individual, the member key contains the details of the member who completed the activity.
If the activity is performed by a group, the members key provides a list of all members who participated in the activity.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/elements/e7W6kP8wvjd3GRBz/activities?member=6K8vojJn1xe14abL" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/elements/e7W6kP8wvjd3GRBz/activities',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'member'=> '6K8vojJn1xe14abL',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/elements/e7W6kP8wvjd3GRBz/activities"
);

const params = {
    "member": "6K8vojJn1xe14abL",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
"error": null,
"payload": {
   "data": [
       {
           "id": "KwJ8VgrmlAp4PBnM",
           "object": "activity",
           "timestamp" : "2022-11-27T13:52:02.000000Z",
           "status": "PASSED",
           "passed": true,
           "score": 100,
           "completed_by": "6K8vojJn1xe14abL",
           "member": {
               "id": "6K8vojJn1xe14abL",
               "object": "member",
               "first_name": "Adalberto",
               "last_name": "Bruen",
               "full_name": "Adalberto Bruen",
               "avatar": null,
               "email": "iva52@example.org",
               "is_email_verified": true,
               "last_seen": "2024-11-27T13:51:52.000000Z"
           },
           "context": {
                "id": "QB8nmEJjqdbLA2K5",
                "object": "element",
                "created_at": "2024-11-26T11:37:16.000000Z",
                "name": "Multiple Choice Quiz",
                "cover": null,
                "type": "QUIZ",
                "content": null,
                "position": 3,
                "course": "B4peAvmZ1L9OY3Xr",
                "module": "no0aApWNyRMD68rv",
                "metadata": {},
                "properties": {
                    "passing_score": 70,
                    "completion_trigger": "on_pass"
                }
           },
       },
       {...},
       {...},
   ],
   "pagination": {
       "total": 3,
       "count": 3,
       "per_page": 10,
       "current_page": 1,
       "total_pages": 1
   }
}
 

Request   

GET v0/elements/{id}/activities

URL Parameters

id  string  

The ID of the element to retrieve an activities.

Query Parameters

member  string optional  

The unique ID of the member to filter activities for.

Create element

Requires Authentication

Creates an element in the specified module. Returns the created element details upon successful creation.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/elements" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"First knowledge\",
    \"content\": \"# Element Introduction\\\\nWelcome to the **first element**.\",
    \"module\": \"no0aApWNyRMD68rv\",
    \"position\": 0,
    \"type\": \"QUIZ\",
    \"metadata\": {
        \"category\": \"marketing\"
    },
    \"properties\": {
        \"video_url\": \"https:\\/\\/www.youtube.com\\/watch?v=dQw4w9WgXcQ\"
    }
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/elements',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'First knowledge',
            'content' => '# Element Introduction\\nWelcome to the **first element**.',
            'module' => 'no0aApWNyRMD68rv',
            'position' => 0,
            'type' => 'QUIZ',
            'metadata' => [
                'category' => 'marketing',
            ],
            'properties' => [
                'video_url' => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/elements"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "First knowledge",
    "content": "# Element Introduction\\nWelcome to the **first element**.",
    "module": "no0aApWNyRMD68rv",
    "position": 0,
    "type": "QUIZ",
    "metadata": {
        "category": "marketing"
    },
    "properties": {
        "video_url": "https:\/\/www.youtube.com\/watch?v=dQw4w9WgXcQ"
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "data": {
            "id": "QB8nmEJjqdbLA2K5",
            "object": "element",
            "created_at": "2024-11-26T11:37:16.000000Z",
            "name": "Multiple Choice Quiz",
            "cover": null,
            "type": "QUIZ",
            "content": null,
            "position": 3,
            "course": "B4peAvmZ1L9OY3Xr",
            "module": "no0aApWNyRMD68rv",
            "metadata": {},
            "properties": {
                "passing_score": 70,
                "completion_trigger": "on_pass"
            }
        }
    }
}
 

Request   

POST v0/elements

Body Parameters

name  string optional  

The element name. Must not be greater than 255 characters.

content  string optional  

The element content in markdown format. Supports headings, bold, italic, strikethrough, highlights, inline code, code blocks, blockquotes, lists, tables, images, links, and math (LaTeX).

module  string  

The module id of the element.

position  integer optional  

The 0-indexed position of the element within its module. If omitted, the element is appended at the end. Values beyond the last sibling index are clamped to the last position. Siblings are re-ordered automatically. Must be at least 0.

type  string optional  

The element type. Must be one of: CONTENT, VIDEO, ZOOM_MEETING, MEETING_LINK, QUIZ, SUBMISSION, GROUP_SUBMISSION, EMBED, SURVEY, SCORM, CERTIFICATE, TAG, DATACAMP, SELF_REVIEW, PEER_REVIEW, FEEDBACK_REFLECTION, INSTRUCTOR_REVIEW, INSTRUCTOR_DISCUSSION, AI_REVIEW, CHECKLIST, DISCUSSION, FILE, GROUP_FORMATION, FORM, SCORE, GROUP_PEER_REVIEW, GROUP_FEEDBACK_REFLECTION, MICROSOFT_TEAMS_MEETING.

metadata  string optional  

Metadata is an attribute that lets you store more information, structured as key-value pairs, for your own use and reference.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Keys and values are stored as strings and can contain any characters with one exception: you can't use square brackets ([ and ]) in keys.

properties  string optional  

Type-specific properties for the element. The accepted keys depend on the element type. Unknown keys will be rejected with a validation error.

Supported element types and their properties:

VIDEO
  • video_url (string) — The video URL. Supports Vimeo, YouTube, and direct video URLs.
  • video_type (string) — The video source type. Must be set to URL when updating the video_url. Must be one of: URL, SOURCE.

QUIZ
  • passing_score (integer) — The minimum passing score (0-100).
  • completion_trigger (string) — When the quiz should be marked as complete. Must be one of: on_pass, on_submit.
  • questions (array) — The quiz questions. Full replacement — the entire questions array is replaced on update. Include existing question/answer IDs to preserve links to student responses. Omit IDs to auto-generate new ones.

Questions
The questions property accepts an array of question objects. The entire questions array is replaced on every update (full replacement, not merge).

Important — Question and Answer IDs:
Each question and answer has an id field. These IDs link to student responses, activity records, and grades. When updating questions:
  • Include the id to preserve an existing question/answer and maintain links to student data.
  • Omit the id to create a new question/answer with an auto-generated ID.
  • Questions/answers not included in the array will be removed.
  • If you change or omit an existing ID, the link to student responses for that question/answer will be broken.

Question object:
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • text (string, required) — The question text.
  • shuffle (boolean, optional) — Whether to shuffle answer order. Default: false.
  • require_all_correct (boolean, optional) — Require all correct answers selected (multi-choice). Default: false.
  • answers (array, required) — Array of answer objects.

Answer object:
  • id (string, optional) — Existing answer ID to preserve. Omit for new answers.
  • text (string, required) — The answer text.
  • is_correct (boolean, required) — Whether this is a correct answer.

EMBED
  • embed (string) — The embed code.

FILE
  • file_url (string) — The file URL.

SUBMISSION
  • questions (array) — The submission questions. Full replacement on update. Each question defines which response types (text, file) are accepted.

Questions
The questions property accepts an array of question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question defines which response types (text, file) are accepted.

Question object:
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • text (string, required) — The question text.
  • accept_text (boolean, optional) — Whether text responses are accepted. Default: true.
  • text_required (boolean, optional) — Whether text response is required. Default: false.
  • accept_file (boolean, optional) — Whether file uploads are accepted. Default: false.
  • file_required (boolean, optional) — Whether file upload is required. Default: false.
  • file_multiple (boolean, optional) — Whether multiple files can be uploaded. Default: false.

GROUP_SUBMISSION
  • questions (array) — The submission questions. Full replacement on update. Each question defines which response types (text, file) are accepted.

Questions
The questions property accepts an array of question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question defines which response types (text, file) are accepted.

Question object:
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • text (string, required) — The question text.
  • accept_text (boolean, optional) — Whether text responses are accepted. Default: true.
  • text_required (boolean, optional) — Whether text response is required. Default: false.
  • accept_file (boolean, optional) — Whether file uploads are accepted. Default: false.
  • file_required (boolean, optional) — Whether file upload is required. Default: false.
  • file_multiple (boolean, optional) — Whether multiple files can be uploaded. Default: false.

SURVEY
  • questions (array) — The survey questions. Full replacement on update. Each question has a text and a list of options participants can choose from.

Questions
The questions property accepts an array of survey (poll-style) questions. The entire questions array is replaced on every update (full replacement, not merge). Each question has a text and a list of answer options participants can choose from. There are no correct answers and no scoring.

Question object:
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • text (string, required) — The question text.
  • options (array, required) — Answer options (at least 2).

Option object:
  • id (string, optional) — Existing option ID to preserve.
  • text (string, required) — The option text.

FORM
  • questions (array) — The form questions. Full replacement — the entire questions array is replaced on update. Each question has a type that determines its structure.

Questions
The questions property accepts an array of question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, NUMBER_SCALE, MULTIPLE_CHOICE, STACK_RANK, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT type additional fields:
  • min_words (integer, optional) — Minimum word count. Default: 1.

NUMBER_SCALE type additional fields:
  • range_min (integer, optional) — Scale minimum value. Default: 1.
  • range_max (integer, optional) — Scale maximum value. Default: 10.

MULTIPLE_CHOICE / STACK_RANK type additional fields:
  • options (array, required) — Array of option objects.

Option object:
  • id (string, optional) — Existing option ID to preserve.
  • text (string, required) — The option text.

MEETING_LINK
  • meeting_url (string) — The meeting URL.
  • start_date (string) — The meeting start date (ISO 8601 format).
  • end_date (string) — The meeting end date (ISO 8601 format).

ZOOM_MEETING
  • start_date (string) — The meeting start date (ISO 8601 format).
  • end_date (string) — The meeting end date (ISO 8601 format).
  • meeting_reports (boolean) — Whether attendance tracking is enabled.

MICROSOFT_TEAMS_MEETING
  • start_date (string) — The meeting start date (ISO 8601 format).
  • end_date (string) — The meeting end date (ISO 8601 format).
  • meeting_reports (boolean) — Whether attendance tracking is enabled.

SCORM
  • scorm_url (string) — The URL of the uploaded SCORM package file. Read-only.
  • scorm_user_identifier (string) — The identifier used to track learners. Must be one of: user_id, user_email.

CHECKLIST
  • questions (array) — The checklist items. Full replacement on update. Each item is a simple { id?, text } object.

Questions
The questions property accepts an array of checklist items. The entire items array is replaced on every update (full replacement, not merge). Each item is a simple object with a text field.

Item object:
  • id (string, optional) — Existing item ID to preserve. Omit for new items.
  • text (string, required) — The checklist item text.

PEER_REVIEW
  • source (object) — The submission element being reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

SELF_REVIEW
  • source (object) — The submission element being self-reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a SUBMISSION element in the same course.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

INSTRUCTOR_REVIEW
  • source (object) — The submission element being reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a SUBMISSION or GROUP_SUBMISSION element in the same course.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION or GROUP_SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

INSTRUCTOR_DISCUSSION
  • source (object) — The submission element being discussed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a SUBMISSION or GROUP_SUBMISSION element in the same course.

Source
The source property references the submission element being discussed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION or GROUP_SUBMISSION and must belong to the same course.


AI_REVIEW
  • source (object) — The submission element being reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a SUBMISSION element in the same course.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

FEEDBACK_REFLECTION
  • source (object) — The peer review element this reflection is linked to. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a PEER_REVIEW element in the same course.
  • questions (array) — The reflection questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the peer review element this reflection is linked to. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type PEER_REVIEW and must belong to the same course.

Questions
The questions property accepts an array of reflection question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

GROUP_PEER_REVIEW
  • source (object) — The group submission element being reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type GROUP_SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

GROUP_FEEDBACK_REFLECTION
  • source (object) — The group peer review element this reflection is linked to. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a GROUP_PEER_REVIEW element in the same course.
  • questions (array) — The reflection questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the peer review element this reflection is linked to. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type GROUP_PEER_REVIEW and must belong to the same course.

Questions
The questions property accepts an array of reflection question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

CERTIFICATE
  • certificate_title (string) — The certificate title.
  • certificate_description (string) — The certificate description.
  • certificate_course_name (string) — The course name displayed on the certificate.
  • certificate_issued_by (string) — The issuer name displayed on the certificate.

.

Update element

Requires Authentication

Updates the details of an existing element in your organization based on the provided unique element ID. Any parameters not provided will be left unchanged. Returns the updated element details upon successful update.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/elements/p5v87ERWKR3dkjyD" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Introduction to Marketing\",
    \"content\": \"# Element Introduction\\\\nWelcome to the **first element**.\",
    \"position\": 2,
    \"metadata\": {
        \"category\": \"marketing\"
    },
    \"properties\": {
        \"passing_score\": 80
    }
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/elements/p5v87ERWKR3dkjyD',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Introduction to Marketing',
            'content' => '# Element Introduction\\nWelcome to the **first element**.',
            'position' => 2,
            'metadata' => [
                'category' => 'marketing',
            ],
            'properties' => [
                'passing_score' => 80,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/elements/p5v87ERWKR3dkjyD"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Introduction to Marketing",
    "content": "# Element Introduction\\nWelcome to the **first element**.",
    "position": 2,
    "metadata": {
        "category": "marketing"
    },
    "properties": {
        "passing_score": 80
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "data": {
            "id": "QB8nmEJjqdbLA2K5",
            "object": "element",
            "created_at": "2024-11-26T11:37:16.000000Z",
            "name": "Multiple Choice Quiz",
            "cover": null,
            "type": "QUIZ",
            "content": null,
            "position": 3,
            "course": "B4peAvmZ1L9OY3Xr",
            "module": "no0aApWNyRMD68rv",
            "metadata": {},
            "properties": {
                "passing_score": 80,
                "completion_trigger": "on_pass"
            }
        }
    }
}
 

Request   

POST v0/elements/{id}

URL Parameters

id  string  

The ID of the requested element to update.

Body Parameters

name  string optional  

The element name. Must not be greater than 255 characters.

content  string optional  

The element content in markdown format. Supports headings, bold, italic, strikethrough, highlights, inline code, code blocks, blockquotes, lists, tables, images, links, and math (LaTeX).

position  integer optional  

The 0-indexed position of the element within its module. Siblings are re-ordered automatically. Values beyond the last sibling index are clamped to the last position. Must be at least 0.

metadata  string optional  

Metadata is an attribute that lets you store more information, structured as key-value pairs, for your own use and reference.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Keys and values are stored as strings and can contain any characters with one exception: you can't use square brackets ([ and ]) in keys.

properties  string optional  

Type-specific properties for the element. The accepted keys depend on the element type. Unknown keys will be rejected with a validation error.

Supported element types and their properties:

VIDEO
  • video_url (string) — The video URL. Supports Vimeo, YouTube, and direct video URLs.
  • video_type (string) — The video source type. Must be set to URL when updating the video_url. Must be one of: URL, SOURCE.

QUIZ
  • passing_score (integer) — The minimum passing score (0-100).
  • completion_trigger (string) — When the quiz should be marked as complete. Must be one of: on_pass, on_submit.
  • questions (array) — The quiz questions. Full replacement — the entire questions array is replaced on update. Include existing question/answer IDs to preserve links to student responses. Omit IDs to auto-generate new ones.

Questions
The questions property accepts an array of question objects. The entire questions array is replaced on every update (full replacement, not merge).

Important — Question and Answer IDs:
Each question and answer has an id field. These IDs link to student responses, activity records, and grades. When updating questions:
  • Include the id to preserve an existing question/answer and maintain links to student data.
  • Omit the id to create a new question/answer with an auto-generated ID.
  • Questions/answers not included in the array will be removed.
  • If you change or omit an existing ID, the link to student responses for that question/answer will be broken.

Question object:
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • text (string, required) — The question text.
  • shuffle (boolean, optional) — Whether to shuffle answer order. Default: false.
  • require_all_correct (boolean, optional) — Require all correct answers selected (multi-choice). Default: false.
  • answers (array, required) — Array of answer objects.

Answer object:
  • id (string, optional) — Existing answer ID to preserve. Omit for new answers.
  • text (string, required) — The answer text.
  • is_correct (boolean, required) — Whether this is a correct answer.

EMBED
  • embed (string) — The embed code.

FILE
  • file_url (string) — The file URL.

SUBMISSION
  • questions (array) — The submission questions. Full replacement on update. Each question defines which response types (text, file) are accepted.

Questions
The questions property accepts an array of question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question defines which response types (text, file) are accepted.

Question object:
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • text (string, required) — The question text.
  • accept_text (boolean, optional) — Whether text responses are accepted. Default: true.
  • text_required (boolean, optional) — Whether text response is required. Default: false.
  • accept_file (boolean, optional) — Whether file uploads are accepted. Default: false.
  • file_required (boolean, optional) — Whether file upload is required. Default: false.
  • file_multiple (boolean, optional) — Whether multiple files can be uploaded. Default: false.

GROUP_SUBMISSION
  • questions (array) — The submission questions. Full replacement on update. Each question defines which response types (text, file) are accepted.

Questions
The questions property accepts an array of question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question defines which response types (text, file) are accepted.

Question object:
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • text (string, required) — The question text.
  • accept_text (boolean, optional) — Whether text responses are accepted. Default: true.
  • text_required (boolean, optional) — Whether text response is required. Default: false.
  • accept_file (boolean, optional) — Whether file uploads are accepted. Default: false.
  • file_required (boolean, optional) — Whether file upload is required. Default: false.
  • file_multiple (boolean, optional) — Whether multiple files can be uploaded. Default: false.

SURVEY
  • questions (array) — The survey questions. Full replacement on update. Each question has a text and a list of options participants can choose from.

Questions
The questions property accepts an array of survey (poll-style) questions. The entire questions array is replaced on every update (full replacement, not merge). Each question has a text and a list of answer options participants can choose from. There are no correct answers and no scoring.

Question object:
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • text (string, required) — The question text.
  • options (array, required) — Answer options (at least 2).

Option object:
  • id (string, optional) — Existing option ID to preserve.
  • text (string, required) — The option text.

FORM
  • questions (array) — The form questions. Full replacement — the entire questions array is replaced on update. Each question has a type that determines its structure.

Questions
The questions property accepts an array of question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, NUMBER_SCALE, MULTIPLE_CHOICE, STACK_RANK, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve. Omit for new questions.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT type additional fields:
  • min_words (integer, optional) — Minimum word count. Default: 1.

NUMBER_SCALE type additional fields:
  • range_min (integer, optional) — Scale minimum value. Default: 1.
  • range_max (integer, optional) — Scale maximum value. Default: 10.

MULTIPLE_CHOICE / STACK_RANK type additional fields:
  • options (array, required) — Array of option objects.

Option object:
  • id (string, optional) — Existing option ID to preserve.
  • text (string, required) — The option text.

MEETING_LINK
  • meeting_url (string) — The meeting URL.
  • start_date (string) — The meeting start date (ISO 8601 format).
  • end_date (string) — The meeting end date (ISO 8601 format).

ZOOM_MEETING
  • start_date (string) — The meeting start date (ISO 8601 format).
  • end_date (string) — The meeting end date (ISO 8601 format).
  • meeting_reports (boolean) — Whether attendance tracking is enabled.

MICROSOFT_TEAMS_MEETING
  • start_date (string) — The meeting start date (ISO 8601 format).
  • end_date (string) — The meeting end date (ISO 8601 format).
  • meeting_reports (boolean) — Whether attendance tracking is enabled.

SCORM
  • scorm_url (string) — The URL of the uploaded SCORM package file. Read-only.
  • scorm_user_identifier (string) — The identifier used to track learners. Must be one of: user_id, user_email.

CHECKLIST
  • questions (array) — The checklist items. Full replacement on update. Each item is a simple { id?, text } object.

Questions
The questions property accepts an array of checklist items. The entire items array is replaced on every update (full replacement, not merge). Each item is a simple object with a text field.

Item object:
  • id (string, optional) — Existing item ID to preserve. Omit for new items.
  • text (string, required) — The checklist item text.

PEER_REVIEW
  • source (object) — The submission element being reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

SELF_REVIEW
  • source (object) — The submission element being self-reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a SUBMISSION element in the same course.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

INSTRUCTOR_REVIEW
  • source (object) — The submission element being reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a SUBMISSION or GROUP_SUBMISSION element in the same course.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION or GROUP_SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

INSTRUCTOR_DISCUSSION
  • source (object) — The submission element being discussed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a SUBMISSION or GROUP_SUBMISSION element in the same course.

Source
The source property references the submission element being discussed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION or GROUP_SUBMISSION and must belong to the same course.


AI_REVIEW
  • source (object) — The submission element being reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a SUBMISSION element in the same course.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

FEEDBACK_REFLECTION
  • source (object) — The peer review element this reflection is linked to. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a PEER_REVIEW element in the same course.
  • questions (array) — The reflection questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the peer review element this reflection is linked to. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type PEER_REVIEW and must belong to the same course.

Questions
The questions property accepts an array of reflection question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

GROUP_PEER_REVIEW
  • source (object) — The group submission element being reviewed. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear.
  • questions (array) — The review rubric questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the submission element being reviewed. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type GROUP_SUBMISSION and must belong to the same course.

Questions
The questions property accepts an array of review rubric question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

GROUP_FEEDBACK_REFLECTION
  • source (object) — The group peer review element this reflection is linked to. On read returns { type, id, name }. On write pass { id: "element_id" } or null to clear. Must be a GROUP_PEER_REVIEW element in the same course.
  • questions (array) — The reflection questions. Full replacement on update. Types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX.

Source
The source property references the peer review element this reflection is linked to. On read it returns an object with type, id, and name. On write, pass { "id": "element_id" }, or null to clear. The referenced element must be of type GROUP_PEER_REVIEW and must belong to the same course.

Questions
The questions property accepts an array of reflection question objects. The entire questions array is replaced on every update (full replacement, not merge). Each question has a type that determines its structure.

Question types: TEXT, TEXT_SCALE, NUMBER_SCALE, YES_NO, INFO_BOX

Common fields (all types):
  • id (string, optional) — Existing question ID to preserve.
  • type (string, required) — The question type.
  • text (string, required) — The question text.
  • optional (boolean, optional) — Whether the question is optional. Default: false.

TEXT: min_words (integer)
NUMBER_SCALE: range_min (integer), range_max (integer)
TEXT_SCALE: options (array of { text }) — ordered from lowest to highest score.
YES_NO: yes_text (string), no_text (string)
INFO_BOX: no additional fields

CERTIFICATE
  • certificate_title (string) — The certificate title.
  • certificate_description (string) — The certificate description.
  • certificate_course_name (string) — The course name displayed on the certificate.
  • certificate_issued_by (string) — The issuer name displayed on the certificate.

.

Requires Authentication

Search for existing elements in your organization. You can search by element name. The search is case-insensitive and supports partial matches.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/elements/search" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"q\": \"Quiz\",
    \"type\": \"GROUP_FEEDBACK_REFLECTION\"
}"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/elements/search',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'q' => 'Quiz',
            'type' => 'GROUP_FEEDBACK_REFLECTION',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/elements/search"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "q": "Quiz",
    "type": "GROUP_FEEDBACK_REFLECTION"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "QB8nmEJjqdbLA2K5",
        "object": "element",
        "created_at": "2024-11-26T11:37:16.000000Z",
        "name": "Multiple Choice Quiz",
        "cover": null,
        "type": "QUIZ",
        "content": null,
        "position": 3,
        "course": "B4peAvmZ1L9OY3Xr",
        "module": "no0aApWNyRMD68rv",
        "metadata": {},
        "properties": {}
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 3,
      "count": 3,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 1
    }
  }
}
 

Retrieve an Element

Requires Authentication

Retrieves the details of an existing element in your organization based on the provided unique element ID. Returns comprehensive information about the element, including its name, type, content, position, and type-specific properties.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/elements/QB8nmEJjqdbLA2K5" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/elements/QB8nmEJjqdbLA2K5',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/elements/QB8nmEJjqdbLA2K5"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "data": {
            "id": "QB8nmEJjqdbLA2K5",
            "object": "element",
            "created_at": "2024-11-26T11:37:16.000000Z",
            "name": "Multiple Choice Quiz",
            "cover": null,
            "type": "QUIZ",
            "content": null,
            "position": 3,
            "course": "B4peAvmZ1L9OY3Xr",
            "module": "no0aApWNyRMD68rv",
            "metadata": {},
            "properties": {
                "passing_score": 70,
                "completion_trigger": "on_pass"
            }
        }
    }
}
 

Request   

GET v0/elements/{id}

URL Parameters

id  string  

The ID of the requested element.

List all Elements

Requires Authentication

Returns a list of elements within your organization. The elements are sorted by their creation date, with the most recently created elements appearing first.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/elements?page=2" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/elements',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'page'=> '2',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/elements"
);

const params = {
    "page": "2",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "QB8nmEJjqdbLA2K5",
        "object": "element",
        "created_at": "2024-11-26T11:37:16.000000Z",
        "name": "Multiple Choice Quiz",
        "cover": null,
        "type": "QUIZ",
        "content": null,
        "position": 3,
        "course": "B4peAvmZ1L9OY3Xr",
        "module": "no0aApWNyRMD68rv",
        "metadata": {},
        "properties": {}
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 15,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 2
    }
  }
}
 

Request   

GET v0/elements

Query Parameters

page  integer optional  

A cursor for pagination across multiple pages of results.

Delete an Element

Requires Authentication

Deletes an existing element in your organization. Returns an object with a deleted parameter upon successful deletion.

Example request:
curl --request DELETE \
    "https://api.teachfloor.com/v0/elements/QB8nmEJjqdbLA2K5" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->delete(
    'https://api.teachfloor.com/v0/elements/QB8nmEJjqdbLA2K5',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/elements/QB8nmEJjqdbLA2K5"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "QB8nmEJjqdbLA2K5",
        "object": "element",
        "deleted": true
    }
}
 

Request   

DELETE v0/elements/{id}

URL Parameters

id  string  

The ID of the element to delete.

Members

Requires Authentication

Search for existing members in your organization. You can search by first name, last name or email. The search is case-insensitive and supports partial matches.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/members/search" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"q\": \"John\",
    \"include_test_user\": true
}"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/members/search',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'q' => 'John',
            'include_test_user' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/members/search"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "q": "John",
    "include_test_user": true
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "member",
        "first_name": "John",
        "last_name": "Doe",
        "full_name": "John Doe",
        "avatar": null,
        "email": null,
        "is_email_verified": false,
        "last_seen": "2024-01-22T12:56:04.000000Z"
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 5,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 1
    }
  }
}
 

Retrieve a Member

Requires Authentication

Retrieves the details of an existing member in your organization based on the provided unique member ID. Returns a comprehensive information about the member, including their first name, last name, email, and profile image.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/members/e7W6kP8wvjd3GRBz" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/members/e7W6kP8wvjd3GRBz',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/members/e7W6kP8wvjd3GRBz"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "member",
        "first_name": "John",
        "last_name": "Doe",
        "full_name": "John Doe",
        "avatar": null,
        "email": null,
        "is_email_verified": false,
        "last_seen": "2024-01-22T12:56:04.000000Z"
    }
}
 

Request   

GET v0/members/{id}

URL Parameters

id  string  

The ID of the requested member.

List all Members

Requires Authentication

Retrieves a paginated list of members in your organization. This API endpoint allows you to retrieve detailed information about each member, including their name, email, and other relevant details.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/members?page=2" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/members',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'page'=> '2',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/members"
);

const params = {
    "page": "2",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "member",
        "first_name": "John",
        "last_name": "Doe",
        "full_name": "John Doe",
        "avatar": null,
        "email": null,
        "is_email_verified": false,
        "last_seen": "2024-01-22T12:56:04.000000Z"
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 152,
      "count": 10,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 16
    }
  }
}
 

Request   

GET v0/members

Query Parameters

page  integer optional  

A cursor for pagination across multiple pages of results.

Create a Member

Requires Authentication

Create a member in your organization.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/members" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"john.doe@example.com\",
    \"password\": \"doNotU5e_thiSPassw0rd\",
    \"first_name\": \"John\",
    \"last_name\": \"Doe\",
    \"role\": \"lecturer\",
    \"avatar\": \"https:\\/\\/example.com\\/avatar.png\"
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/members',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => 'john.doe@example.com',
            'password' => 'doNotU5e_thiSPassw0rd',
            'first_name' => 'John',
            'last_name' => 'Doe',
            'role' => 'lecturer',
            'avatar' => 'https://example.com/avatar.png',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/members"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "john.doe@example.com",
    "password": "doNotU5e_thiSPassw0rd",
    "first_name": "John",
    "last_name": "Doe",
    "role": "lecturer",
    "avatar": "https:\/\/example.com\/avatar.png"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "member",
        "first_name": "John",
        "last_name": "Doe",
        "full_name": "John Doe",
        "avatar": null,
        "email": "john.doe@example.com",
        "is_email_verified": false,
        "last_seen": "2024-01-22T12:56:04.000000Z"
    }
}
 

Request   

POST v0/members

Body Parameters

email  string  

The member's email. Must be a valid email address.

password  string  

The member's password. Must be at least 8 characters. Must have at least one uppercase and one lowercase letter. Must have at least one number. Must have at least one symbol.

first_name  string  

The member's first name.

last_name  string  

The member's last name.

role  string  

The member's role. It must be "owner", "admin", "lecturer", "assistant" or "customer".

avatar  string optional  

The member's profile picture. Must be a valid URL. Must not be greater than 255 characters.

List all Member Courses

Requires Authentication

Returns a list of courses the member belongs to.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/members/e7W6kP8wvjd3GRBz/courses" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/members/e7W6kP8wvjd3GRBz/courses',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/members/e7W6kP8wvjd3GRBz/courses"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "6jO9XN7mZEVpvxqo",
        "object": "course_member",
        "joined_at": "2024-01-22T12:56:04.000000Z",
        "member": {
          "id": "e7W6kP8wvjd3GRBz",
          "object": "member",
          "first_name": "John",
          "last_name": "Doe",
          "full_name": "John Doe",
          "avatar": null,
          "email": null,
          "is_email_verified": false,
          "last_seen": "2024-01-22T12:56:04.000000Z"
        },
        "course": {
          "id": "p5v87ERWKR3dkjyD",
          "object": "course",
          "name": "Ultimate Marketing Course",
          "created_at": "2022-02-03T16:06:42.000000Z",
          "cover": null,
          "availability": "CONTINUOUS",
          "visibility": "PRIVATE",
          "start_date": null,
          "end_date": null,
          "currency": "eur",
          "price": null,
          "url": null,
          "public_url": null,
          "join_url": null,
          "metadata": {}
        },
        "custom_fields": {
          "field_1": {
            "key": "field_1",
            "object": "custom-field",
            "created_at": "2024-07-30T16:05:47.000000Z",
            "name": "Multiple Field Question",
            "description": null,
            "type": "MULTIPLE_OPTIONS",
            "options": [
                "Option A",
                "Option B",
                "Option C"
            ],
            "required": false
          }
        }
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 15,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 2
    }
  }
}
 

Request   

GET v0/members/{id}/courses

URL Parameters

id  string  

The ID of the member which the courses should be retrieveds.

Update a Member

Requires Authentication

Updates the details of an existing member in your organization based on the provided unique member ID. Any parameters not provided will be left unchanged. Returns the updated member details upon successful update.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/members/p5v87ERWKR3dkjyD" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"john.doe@example.com\",
    \"password\": \"doNotU5e_thiSPassw0rd\",
    \"first_name\": \"John\",
    \"last_name\": \"Doe\",
    \"avatar\": \"https:\\/\\/example.com\\/avatar.png\"
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/members/p5v87ERWKR3dkjyD',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => 'john.doe@example.com',
            'password' => 'doNotU5e_thiSPassw0rd',
            'first_name' => 'John',
            'last_name' => 'Doe',
            'avatar' => 'https://example.com/avatar.png',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/members/p5v87ERWKR3dkjyD"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "john.doe@example.com",
    "password": "doNotU5e_thiSPassw0rd",
    "first_name": "John",
    "last_name": "Doe",
    "avatar": "https:\/\/example.com\/avatar.png"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "member",
        "first_name": "John",
        "last_name": "Doe",
        "full_name": "John Doe",
        "avatar": null,
        "email": "john.doe@example.com",
        "is_email_verified": false,
        "last_seen": "2024-01-22T12:56:04.000000Z"
    }
}
 

Request   

POST v0/members/{id}

URL Parameters

id  string  

The ID of the requested member to update.

Body Parameters

email  string optional  

The member email address.

password  string optional  

The member's password. Must be at least 8 characters. Must have at least one uppercase and one lowercase letter. Must have at least one number. Must have at least one symbol.

first_name  string optional  

The member first name.

last_name  string optional  

The member last name.

avatar  string optional  

The member profile picture URL.

Modules

Create a module

Requires Authentication

Create a module in the specified course. Returns the created module details upon successful creation.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/modules" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"First knowledge\",
    \"content\": \"# Module Introduction\\\\nWelcome to the **first module**.\",
    \"course\": \"qw0aApAGyRKL69rw\",
    \"availability\": \"CONTINUOUS\",
    \"start_date\": \"2025-02-17T00:00:00Z\",
    \"end_date\": \"2025-03-17T00:00:00Z\",
    \"position\": 0,
    \"metadata\": {
        \"category\": \"marketing\"
    }
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/modules',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'First knowledge',
            'content' => '# Module Introduction\\nWelcome to the **first module**.',
            'course' => 'qw0aApAGyRKL69rw',
            'availability' => 'CONTINUOUS',
            'start_date' => '2025-02-17T00:00:00Z',
            'end_date' => '2025-03-17T00:00:00Z',
            'position' => 0,
            'metadata' => [
                'category' => 'marketing',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/modules"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "First knowledge",
    "content": "# Module Introduction\\nWelcome to the **first module**.",
    "course": "qw0aApAGyRKL69rw",
    "availability": "CONTINUOUS",
    "start_date": "2025-02-17T00:00:00Z",
    "end_date": "2025-03-17T00:00:00Z",
    "position": 0,
    "metadata": {
        "category": "marketing"
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "module",
        "created_at": "2024-01-22T12:56:04.000000Z",
        "name": "Example module",
        "type": "LESSON",
        "availability": "SCHEDULED",
        "start_date": "2025-02-20T00:00:00.000000Z",
        "end_date": "2025-02-21T00:00:00.000000Z",
        "content": null,
        "position": 1,
        "course": "p5v87ERWKR3dkjyD",
        "metadata": {}
    }
}
 

Request   

POST v0/modules

Body Parameters

name  string optional  

The module name. Must not be greater than 255 characters.

content  string optional  

The module content in markdown format. Supports headings, bold, italic, strikethrough, highlights, inline code, code blocks, blockquotes, lists, tables, images, links, and math (LaTeX).

course  string  

The course id of the module.

availability  string optional  

Defines the availability of the module. Can be one of the following values: "CONTINUOUS" for an ongoing module or "SCHEDULED" for a module with specific start and end dates. Must be one of CONTINUOUS or SCHEDULED.

start_date  string optional  

The start date of the module. The date should be in ISO 8601 format (e.g., "2025-02-17T00:00:00Z"). This field is required if the availability is "SCHEDULED". This field is required when availability is SCHEDULED. Must be a valid date.

end_date  string optional  

The end date of the module. The date should be in ISO 8601 format (e.g., "2025-03-18T00:00:00Z"). This field is required if the availability is "SCHEDULED" and must be after the start date. This field is required when availability is SCHEDULED or date. Must be a date after or equal to start_date.

position  integer optional  

The 0-indexed position of the module within its course. If omitted, the module is appended at the end. Values beyond the last sibling index are clamped to the last position. Siblings are re-ordered automatically. Must be at least 0.

metadata  string optional  

Metadata is an attribute that lets you store more information, structured as key-value pairs, for your own use and reference.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Keys and values are stored as strings and can contain any characters with one exception: you can't use square brackets ([ and ]) in keys.

Update a module

Requires Authentication

Updates the details of an existing module based on the provided unique module ID. Any parameters not provided will be left unchanged. Returns the updated module details upon successful update.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/modules/p5v87ERWKR3dkjyD" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"First knowledge\",
    \"content\": \"# Module Introduction\\\\nWelcome to the **first module**.\",
    \"availability\": \"CONTINUOUS\",
    \"start_date\": \"2025-02-17T00:00:00Z\",
    \"end_date\": \"2025-03-17T00:00:00Z\",
    \"position\": 2,
    \"metadata\": {
        \"category\": \"marketing\"
    }
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/modules/p5v87ERWKR3dkjyD',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'First knowledge',
            'content' => '# Module Introduction\\nWelcome to the **first module**.',
            'availability' => 'CONTINUOUS',
            'start_date' => '2025-02-17T00:00:00Z',
            'end_date' => '2025-03-17T00:00:00Z',
            'position' => 2,
            'metadata' => [
                'category' => 'marketing',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/modules/p5v87ERWKR3dkjyD"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "First knowledge",
    "content": "# Module Introduction\\nWelcome to the **first module**.",
    "availability": "CONTINUOUS",
    "start_date": "2025-02-17T00:00:00Z",
    "end_date": "2025-03-17T00:00:00Z",
    "position": 2,
    "metadata": {
        "category": "marketing"
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "module",
        "created_at": "2024-01-22T12:56:04.000000Z",
        "name": "Example module",
        "type": "LESSON",
        "availability": "SCHEDULED",
        "start_date": "2025-02-20T00:00:00.000000Z",
        "end_date": "2025-02-21T00:00:00.000000Z",
        "content": null,
        "position": 1,
        "course": "p5v87ERWKR3dkjyD",
        "metadata": {}
    }
}
 

Request   

POST v0/modules/{id}

URL Parameters

id  string  

The ID of the requested module to update.

Body Parameters

name  string optional  

The module name. Must not be greater than 255 characters.

content  string optional  

The module content in markdown format. Supports headings, bold, italic, strikethrough, highlights, inline code, code blocks, blockquotes, lists, tables, images, links, and math (LaTeX).

availability  string optional  

Defines the availability of the module. Can be one of the following values: "CONTINUOUS" for an ongoing module or "SCHEDULED" for a module with specific start and end dates. Must be one of CONTINUOUS or SCHEDULED.

start_date  string optional  

The start date of the module. The date should be in ISO 8601 format (e.g., "2025-02-17T00:00:00Z"). This field is required if the availability is "SCHEDULED". This field is required when availability is SCHEDULED. Must be a valid date.

end_date  string optional  

The end date of the module. The date should be in ISO 8601 format (e.g., "2025-03-18T00:00:00Z"). This field is required if the availability is "SCHEDULED" and must be after the start date. This field is required when availability is SCHEDULED or date. Must be a date after or equal to start_date.

position  integer optional  

The 0-indexed position of the module within its course. Siblings are re-ordered automatically. Values beyond the last sibling index are clamped to the last position. Must be at least 0.

metadata  string optional  

Metadata is an attribute that lets you store more information, structured as key-value pairs, for your own use and reference.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Keys and values are stored as strings and can contain any characters with one exception: you can't use square brackets ([ and ]) in keys.

Requires Authentication

Search for existing modules in your organization. You can search by module name. The search is case-insensitive and supports partial matches.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/modules/search" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"q\": \"Introduction\"
}"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/modules/search',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'q' => 'Introduction',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/modules/search"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "q": "Introduction"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "module",
        "created_at": "2024-01-22T12:56:04.000000Z",
        "name": "Introduction to Marketing",
        "type": "LESSON",
        "availability": "CONTINUOUS",
        "start_date": null,
        "end_date": null,
        "content": null,
        "position": 0,
        "course": "p5v87ERWKR3dkjyD",
        "metadata": {}
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 3,
      "count": 3,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 1
    }
  }
}
 

Retrieve a Module

Requires Authentication

Retrieves the details of an existing module in your organization based on the provided unique module ID. Returns comprehensive information about the module, including its name, type, availability, position, and dates.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/modules/e7W6kP8wvjd3GRBz" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/modules/e7W6kP8wvjd3GRBz',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/modules/e7W6kP8wvjd3GRBz"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "data": {
            "id": "e7W6kP8wvjd3GRBz",
            "object": "module",
            "created_at": "2024-01-22T12:56:04.000000Z",
            "name": "Example module",
            "type": "LESSON",
            "availability": "SCHEDULED",
            "start_date": "2025-02-20T00:00:00.000000Z",
            "end_date": "2025-02-21T00:00:00.000000Z",
            "content": null,
            "position": 1,
            "course": "p5v87ERWKR3dkjyD",
            "metadata": {}
        }
    }
}
 

Request   

GET v0/modules/{id}

URL Parameters

id  string  

The ID of the requested module.

List Module Elements

Requires Authentication

Returns a list of elements within the specified module.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/modules/e7W6kP8wvjd3GRBz/elements?page=2" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/modules/e7W6kP8wvjd3GRBz/elements',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'page'=> '2',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/modules/e7W6kP8wvjd3GRBz/elements"
);

const params = {
    "page": "2",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "QB8nmEJjqdbLA2K5",
        "object": "element",
        "created_at": "2024-11-26T11:37:16.000000Z",
        "name": "Multiple Choice Quiz",
        "cover": null,
        "type": "QUIZ",
        "content": null,
        "position": 3,
        "course": "B4peAvmZ1L9OY3Xr",
        "module": "e7W6kP8wvjd3GRBz",
        "metadata": {},
        "properties": {}
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 5,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 1
    }
  }
}
 

Request   

GET v0/modules/{id}/elements

URL Parameters

id  string  

The ID of the module.

Query Parameters

page  integer optional  

A cursor for pagination across multiple pages of results.

List all Modules

Requires Authentication

Returns a list of modules within your organization. The modules are sorted by their creation date, with the most recently created modules appearing first.

Example request:
curl --request GET \
    --get "https://api.teachfloor.com/v0/modules?page=2" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://api.teachfloor.com/v0/modules',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'page'=> '2',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/modules"
);

const params = {
    "page": "2",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  "error": null,
  "payload": {
    "data": [
      {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "module",
        "created_at": "2024-01-22T12:56:04.000000Z",
        "name": "Example module",
        "type": "LESSON",
        "availability": "SCHEDULED",
        "start_date": "2025-02-20T00:00:00.000000Z",
        "end_date": "2025-02-21T00:00:00.000000Z",
        "content": null,
        "position": 1,
        "course": "p5v87ERWKR3dkjyD",
        "metadata": {}
      },
      {...},
      {...}
    ],
    "pagination": {
      "total": 15,
      "count": 5,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 2
    }
  }
}
 

Request   

GET v0/modules

Query Parameters

page  integer optional  

A cursor for pagination across multiple pages of results.

Delete a Module

Requires Authentication

Deletes an existing module in your organization. Returns an object with a deleted parameter upon successful deletion.

Example request:
curl --request DELETE \
    "https://api.teachfloor.com/v0/modules/e7W6kP8wvjd3GRBz" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
$client = new \GuzzleHttp\Client();
$response = $client->delete(
    'https://api.teachfloor.com/v0/modules/e7W6kP8wvjd3GRBz',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/modules/e7W6kP8wvjd3GRBz"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "e7W6kP8wvjd3GRBz",
        "object": "module",
        "deleted": true
    }
}
 

Request   

DELETE v0/modules/{id}

URL Parameters

id  string  

The ID of the module to delete.

Organization

Revoke Organization Access

Requires Authentication

Revoke a member access from organization.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/revoke" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"member\": \"e7W6kP8wvjd3GRBz\"
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/revoke',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'member' => 'e7W6kP8wvjd3GRBz',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/revoke"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "member": "e7W6kP8wvjd3GRBz"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": null
}
 

Request   

POST v0/revoke

Body Parameters

member  string  

The ID of the member to revoke access to the organization.

Invite Member

Requires Authentication

Invite a member to join the organization or course.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/invites" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"john.doe@example.com\",
    \"full_name\": \"John Doe\",
    \"role\": \"customer\",
    \"discount_percentage\": 63,
    \"course\": \"e7W6kP8wvjd3GRBz\",
    \"skip_email\": false
}"
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/invites',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => 'john.doe@example.com',
            'full_name' => 'John Doe',
            'role' => 'customer',
            'discount_percentage' => 63,
            'course' => 'e7W6kP8wvjd3GRBz',
            'skip_email' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/invites"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "john.doe@example.com",
    "full_name": "John Doe",
    "role": "customer",
    "discount_percentage": 63,
    "course": "e7W6kP8wvjd3GRBz",
    "skip_email": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "id": "R8dXqkpL1BaJl92y",
        "object": "invite",
        "token": "PgvInCUzTnNuTYpYWb2c",
        "url": null,
        "full_name": "John Doe",
        "role": "customer",
        "discount_percentage": 0,
        "course": null,
        "skip_email": false
    }
}
 

Request   

POST v0/invites

Body Parameters

email  string  

The member's emails to whom will sent an invitation. Must be a valid email address.

full_name  string optional  

The member's full name.

role  string optional  

The member's role. Default to "customer". Must be one of customer, lecturer, admin, or owner.

discount_percentage  integer optional  

Must be between 0 and 100.

course  string optional  

If set, the ID of the course the member will be invited to.

skip_email  boolean optional  

If set to true, an email notification will be skipped.

Uploads

Upload a file

Requires Authentication

Uploads a file to your organization's storage. Returns the public URL of the uploaded file. The returned URL can be used to set element properties such as video_url, scorm_url, file, or avatar.

Example request:
curl --request POST \
    "https://api.teachfloor.com/v0/uploads" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "file=@/tmp/phpmHK9CF" 
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://api.teachfloor.com/v0/uploads',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'file',
                'contents' => fopen('/tmp/phpmHK9CF', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
const url = new URL(
    "https://api.teachfloor.com/v0/uploads"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('file', document.querySelector('input[name="file"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Example response (200):


{
    "error": null,
    "payload": {
        "url": "https://cdn.teachfloor.com/public/123/my-document-1712345678.pdf",
        "name": "my-document.pdf",
        "mime_type": "application/pdf",
        "size": 204800
    }
}
 

Request   

POST v0/uploads

Body Parameters

file  file  

The file to upload. Supports images (jpg, jpeg, png, webp, svg, gif), documents (pdf, doc, docx, xls, xlsx, ppt, pptx, csv, txt), audio (mp3, wav, ogg), video (mp4, webm, mov), archives (zip), and SCORM packages. Max 100MB. Must be a file. Must not be greater than 102400 kilobytes.

Webhooks

Teachfloor uses webhooks to notify your application when an event happens in your account. Webhooks are particularly useful for asynchronous events like when a new member joins a course, a member has completed an element, or when a course is updated.

You can start receiving event notifications by adding your own webhook endpoint in Developers > Webhooks and clicking on Add Endpoint.

Webhook Retries

Teachfloor webhooks have built-in retry methods for 3xx, 4xx, or 5xx response status codes. If Teachfloor doesn’t quickly receive a 2xx response status code for an event, we will retry calling the webhook after 10 seconds. If that second attempt fails, we will attempt to call the webhook a final time after 100 seconds.

Webhook Signature


Signature verification example:

/**
 * Generate the signature using the signing
 * secret and the webhook content
 */
$generatedSignature = hash_hmac('sha256', $request->getContent(), $webhookSigningSecret);

/**
 * Compare the generated signature with the received
 * Teachfloor-Signature header to determine if the
 * webhook event is legit
 */
if ($generatedSignature !== $headerSignature) {
  /**
   * Verification failed
   */
  return false;
}

/**
 * Legit event, use the webhook content...
 */

Teachfloor will sign the webhook events it sends to your endpoints by including a signature in each event’s Teachfloor-Signature header. This allows you to verify that the events were sent by Teachfloor, not by a third party.

To verify the webhook event signatures, you need to retrieve your endpoint’s secret from your Webhook Endpoints settings. Select an endpoint that you want to obtain the secret for, then click the Reveal Signing Secret button.

Signatures are generated using a hash-based message authentication code (HMAC) with SHA-256. Use the endpoint’s signing secret as the key, convert the event payload to json format and use it as the message in your HMAC-SHA256 function. Compare the generated signature with the received Teachfloor-Signature header to determine if the webhook event is legit.