Semestra

Schedule and calendar

GET
/programs/{program_id}/calendar

Use for "when is my class tomorrow?", "what's on next Wednesday?" or a week overview. Interpret relative days in the Program's time zone and pass dates; end is exclusive and at most 400 days after start. A busy term is a large result: narrow it with course_ids, kinds or a shorter range. Cancelled classes are included with status 'cancelled'. For today alone prefer calendar.today.get. Each class carries its term week in meta.week_number.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Query Parameters

start*Start

First day, in the Program's time zone

Formatdate
end*End

Day after the last day (exclusive); at most 400 days later

Formatdate
sources?array<>|

Sources to include, e.g. ['schedule.meetings', 'tasks.due']; all by default

term_id?|

Only this term

course_ids?array<>|

Only these courses

kinds?array<>|

Only these kinds: class, event, task; all by default

Response Body

Successful Response

application/json
  1. response
timezone*Timezone

The Program's time zone, for reading the local times

start*Start
Formatdate
end*End
Formatdate
items*array<>

Sorted by start

weeks*array<>

Term weeks touching the range

breaks*array<>

Breaks touching the range

Example Request
curl -X GET 'https://example.com/programs/string/calendar?start=2019-08-24&end=2019-08-24'
Example Response
{  "timezone": "string",  "start": "2019-08-24",  "end": "2019-08-24",  "items": [    {      "id": "string",      "source": "string",      "kind": "class",      "title": "string",      "start_at": "2019-08-24T14:15:22Z",      "end_at": "2019-08-24T14:15:22Z",      "all_day": false,      "course_id": "string",      "type_code": "string",      "location": "string",      "color_ref": "string",      "status": "cancelled",      "ref": {        "entity": "string",        "id": "string"      },      "meta": {        "conflicts_with": [          "string"        ],        "term_id": "string",        "meeting_id": "string",        "section_id": "string",        "original_date": "2019-08-24",        "original_start_at": "2019-08-24T14:15:22Z",        "week_number": 0,        "section_code": "string",        "instructor": "string",        "note": "string",        "url": "string",        "assessment_id": "string",        "updated_at": "2019-08-24T14:15:22Z"      }    }  ],  "weeks": [    {      "term_id": "string",      "start_date": "2019-08-24",      "end_date": "2019-08-24",      "number": 0,      "break_name": "string"    }  ],  "breaks": [    {      "term_id": "string",      "name": "string",      "start_date": "2019-08-24",      "end_date": "2019-08-24"    }  ]}
GET
/programs/{program_id}/today

Prefer this for questions about today ("what do I have today?", "what's due this week?"). It also says which term week it is. For other days or longer ranges use calendar.occurrence.list. Times are local to the Program, with their UTC offset.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Response Body

Successful Response

application/json
  1. response
day*Day

Today in the Program's time zone

Formatdate
timezone*Timezone
week*|

The current term's week, if in a term

items*array<>

Today's classes and events

upcoming*array<>

Tasks due in the next 7 days

tasks*array<>

Tasks due today and overdue ones

Example Request
curl -X GET 'https://example.com/programs/string/today'
Example Response
{  "day": "2019-08-24",  "timezone": "string",  "week": {    "term_id": "string",    "term_name": "string",    "number": 0,    "break_name": "string"  },  "items": [    {      "id": "string",      "source": "string",      "kind": "class",      "title": "string",      "start_at": "2019-08-24T14:15:22Z",      "end_at": "2019-08-24T14:15:22Z",      "all_day": false,      "course_id": "string",      "type_code": "string",      "location": "string",      "color_ref": "string",      "status": "cancelled",      "ref": {        "entity": "string",        "id": "string"      },      "meta": {        "conflicts_with": [          "string"        ],        "term_id": "string",        "meeting_id": "string",        "section_id": "string",        "original_date": "2019-08-24",        "original_start_at": "2019-08-24T14:15:22Z",        "week_number": 0,        "section_code": "string",        "instructor": "string",        "note": "string",        "url": "string",        "assessment_id": "string",        "updated_at": "2019-08-24T14:15:22Z"      }    }  ],  "upcoming": [    {      "id": "string",      "source": "string",      "kind": "class",      "title": "string",      "start_at": "2019-08-24T14:15:22Z",      "end_at": "2019-08-24T14:15:22Z",      "all_day": false,      "course_id": "string",      "type_code": "string",      "location": "string",      "color_ref": "string",      "status": "cancelled",      "ref": {        "entity": "string",        "id": "string"      },      "meta": {        "conflicts_with": [          "string"        ],        "term_id": "string",        "meeting_id": "string",        "section_id": "string",        "original_date": "2019-08-24",        "original_start_at": "2019-08-24T14:15:22Z",        "week_number": 0,        "section_code": "string",        "instructor": "string",        "note": "string",        "url": "string",        "assessment_id": "string",        "updated_at": "2019-08-24T14:15:22Z"      }    }  ],  "tasks": [    {      "id": "string",      "source": "string",      "kind": "class",      "title": "string",      "start_at": "2019-08-24T14:15:22Z",      "end_at": "2019-08-24T14:15:22Z",      "all_day": false,      "course_id": "string",      "type_code": "string",      "location": "string",      "color_ref": "string",      "status": "cancelled",      "ref": {        "entity": "string",        "id": "string"      },      "meta": {        "conflicts_with": [          "string"        ],        "term_id": "string",        "meeting_id": "string",        "section_id": "string",        "original_date": "2019-08-24",        "original_start_at": "2019-08-24T14:15:22Z",        "week_number": 0,        "section_code": "string",        "instructor": "string",        "note": "string",        "url": "string",        "assessment_id": "string",        "updated_at": "2019-08-24T14:15:22Z"      }    }  ]}
GET
/terms/{term_id}/schedule-conflicts

Use after adding or moving meetings to warn about clashes. Only enabled meetings that share at least one date count.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

term_id*Term Id

Term id

Response Body

Successful Response

application/json
  1. response
items*array<>
Example Request
curl -X GET 'https://example.com/terms/string/schedule-conflicts'
Example Response
{  "items": [    {      "meeting_id": "string",      "other_meeting_id": "string",      "weekday": 0,      "dates": [        "2019-08-24"      ]    }  ]}
GET
/programs/{program_id}/events

Optionally only one course's or one term's. For a date range use calendar.occurrence.list.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Query Parameters

course_id?|

Only this course's events

term_id?|

Only this term's events

Response Body

Successful Response

application/json
  1. response
items*array<>

By start time

Example Request
curl -X GET 'https://example.com/programs/string/events'
Example Response
{  "items": [    {      "id": "string",      "program_id": "string",      "term_id": "string",      "course_id": "string",      "type_code": "string",      "title": "string",      "start_at": "2019-08-24T14:15:22Z",      "end_at": "2019-08-24T14:15:22Z",      "all_day": true,      "location": "string",      "note": "string",      "source_kind": "string",      "source_ref": "string",      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  ]}
POST
/programs/{program_id}/events

Times without an offset are read in the Program's time zone. For something that repeats weekly use schedule.meeting.create.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Request Body

application/json
  1. body
title*Title

E.g. 'Midterm'

Length1 <= length <= 100
start_at*Start At

Start; without an offset it is read in the Program's time zone

Formatdate-time
end_at*End At

End (not before the start)

Formatdate-time
all_day?All Day

Whole days; times are ignored

Defaultfalse
course_id?|

Course it belongs to

term_id?|

Term it belongs to

type_code?|

Event type code, e.g. 'TUT'

location?|

Location

note?|

Note

source_kind?|

Importer that created it

source_ref?|

Id in the import source

Response Body

Successful Response

application/json
  1. response
id*Id
program_id*Program Id
term_id*string|null
course_id*string|null
type_code*string|null
title*Title
start_at*Start At
Formatdate-time
end_at*End At
Formatdate-time
all_day*All Day
location*string|null
note*string|null
source_kind*string|null
source_ref*string|null
created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X POST 'https://example.com/programs/string/events' \  -H 'Content-Type: application/json' \  -d '{  "title": "string",  "start_at": "2019-08-24T14:15:22Z",  "end_at": "2019-08-24T14:15:22Z"}'
Example Response
{  "id": "string",  "program_id": "string",  "term_id": "string",  "course_id": "string",  "type_code": "string",  "title": "string",  "start_at": "2019-08-24T14:15:22Z",  "end_at": "2019-08-24T14:15:22Z",  "all_day": true,  "location": "string",  "note": "string",  "source_kind": "string",  "source_ref": "string",  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}
POST
/programs/{program_id}/events:batch

Times without an offset are read in the Program's time zone. For something that repeats weekly use schedule.section.create_many. An item with the same source_kind and source_ref as an existing event of the Program updates it.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Request Body

application/json
  1. body
events*array<>

Events; same source_kind+source_ref updates

Items1 <= items <= 100

Response Body

Successful Response

application/json
  1. response
items*array<>
created_ids*array<string>
updated_ids*array<string>
Example Request
curl -X POST 'https://example.com/programs/string/events:batch' \  -H 'Content-Type: application/json' \  -d '{  "events": [    {      "title": "string",      "start_at": "2019-08-24T14:15:22Z",      "end_at": "2019-08-24T14:15:22Z"    }  ]}'
Example Response
{  "items": [    {      "id": "string",      "program_id": "string",      "term_id": "string",      "course_id": "string",      "type_code": "string",      "title": "string",      "start_at": "2019-08-24T14:15:22Z",      "end_at": "2019-08-24T14:15:22Z",      "all_day": true,      "location": "string",      "note": "string",      "source_kind": "string",      "source_ref": "string",      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  ],  "created_ids": [    "string"  ],  "updated_ids": [    "string"  ]}

One one-off event.

GET
/events/{event_id}

Use schedule.event.list or calendar.occurrence.list to find events.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

event_id*Event Id

Event id

Response Body

Successful Response

application/json
  1. response
id*Id
program_id*Program Id
term_id*string|null
course_id*string|null
type_code*string|null
title*Title
start_at*Start At
Formatdate-time
end_at*End At
Formatdate-time
all_day*All Day
location*string|null
note*string|null
source_kind*string|null
source_ref*string|null
created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X GET 'https://example.com/events/string'
Example Response
{  "id": "string",  "program_id": "string",  "term_id": "string",  "course_id": "string",  "type_code": "string",  "title": "string",  "start_at": "2019-08-24T14:15:22Z",  "end_at": "2019-08-24T14:15:22Z",  "all_day": true,  "location": "string",  "note": "string",  "source_kind": "string",  "source_ref": "string",  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}

Change a one-off event.

PATCH
/events/{event_id}

Only the fields that are sent change. Moving only start_at keeps the event's duration. Find the id with schedule.event.list; a weekly class is changed with schedule.meeting.update or, for one week, schedule.exception.upsert.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

event_id*Event Id

Event id

Request Body

application/json
  1. body
title?|

Title

start_at?|

Start

end_at?|

End

all_day?|

Whole days

course_id?|

Course, or null

term_id?|

Term, or null

type_code?|

Event type code, or null

location?|

Location, or null

note?|

Note, or null

Response Body

Successful Response

application/json
  1. response
id*Id
program_id*Program Id
term_id*string|null
course_id*string|null
type_code*string|null
title*Title
start_at*Start At
Formatdate-time
end_at*End At
Formatdate-time
all_day*All Day
location*string|null
note*string|null
source_kind*string|null
source_ref*string|null
created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X PATCH 'https://example.com/events/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "id": "string",  "program_id": "string",  "term_id": "string",  "course_id": "string",  "type_code": "string",  "title": "string",  "start_at": "2019-08-24T14:15:22Z",  "end_at": "2019-08-24T14:15:22Z",  "all_day": true,  "location": "string",  "note": "string",  "source_kind": "string",  "source_ref": "string",  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}

Delete a one-off event.

DELETE
/events/{event_id}

Irreversible. Find the id with schedule.event.list. A weekly class is not an event: cancel one week with schedule.exception.upsert, or remove the class time with schedule.meeting.delete.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

event_id*Event Id

Event id

Response Body

Successful Response

application/json
  1. response
deleted?Deleted
Defaulttrue
Example Request
curl -X DELETE 'https://example.com/events/string'
Example Response
{  "deleted": true}
GET
/programs/{program_id}/event-types

Use to find valid type codes before creating meetings or events.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Response Body

Successful Response

application/json
  1. response
items*array<>

In display order

Example Request
curl -X GET 'https://example.com/programs/string/event-types'
Example Response
{  "items": [    {      "id": "string",      "program_id": "string",      "code": "string",      "name": "string",      "color": "string",      "icon": "string",      "builtin": true,      "position": 0    }  ]}
POST
/programs/{program_id}/event-types

Use when a schedule needs a type the Program does not have yet.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Request Body

application/json
  1. body
code*Code

Abbreviation, letters and digits, e.g. 'LAB'

Match^[A-Za-z0-9]{1,8}$
name*Name

Display name, e.g. 'Laboratory'

Length1 <= length <= 100
color?|

'subject-<1..12>' or '#rrggbb'

icon?|

lucide icon name, e.g. 'flask-conical'

Response Body

Successful Response

application/json
  1. response
id*Id
program_id*Program Id
code*Code

Upper-case abbreviation, e.g. 'LEC'

name*Name

Display name; built-in types are translated by the app

color*string|null
icon*string|null
builtin*Builtin
position*Position
Example Request
curl -X POST 'https://example.com/programs/string/event-types' \  -H 'Content-Type: application/json' \  -d '{  "code": "string",  "name": "string"}'
Example Response
{  "id": "string",  "program_id": "string",  "code": "string",  "name": "string",  "color": "string",  "icon": "string",  "builtin": true,  "position": 0}
PATCH
/event-types/{event_type_id}

Built-in types (LEC, PRA, TUT) keep their name; their color and icon can change.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

event_type_id*Event Type Id

Event type id

Request Body

application/json
  1. body
name?|

Display name (not for built-in types)

color?|

Color, or null for none

icon?|

Icon name, or null for none

Response Body

Successful Response

application/json
  1. response
id*Id
program_id*Program Id
code*Code

Upper-case abbreviation, e.g. 'LEC'

name*Name

Display name; built-in types are translated by the app

color*string|null
icon*string|null
builtin*Builtin
position*Position
Example Request
curl -X PATCH 'https://example.com/event-types/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "id": "string",  "program_id": "string",  "code": "string",  "name": "string",  "color": "string",  "icon": "string",  "builtin": true,  "position": 0}
DELETE
/event-types/{event_type_id}

Fails with schedule.event_type_in_use while anything uses the type.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

event_type_id*Event Type Id

Event type id

Response Body

Successful Response

application/json
  1. response
deleted?Deleted
Defaulttrue
Example Request
curl -X DELETE 'https://example.com/event-types/string'
Example Response
{  "deleted": true}
PUT
/programs/{program_id}/event-types:order

Types not listed keep their relative order after the listed ones.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Request Body

application/json
  1. body
event_type_ids*array<>

Types in display order

Itemsitems <= 100

Response Body

Successful Response

application/json
  1. response
items*array<>

In display order

Example Request
curl -X PUT 'https://example.com/programs/string/event-types:order' \  -H 'Content-Type: application/json' \  -d '{  "event_type_ids": [    "string"  ]}'
Example Response
{  "items": [    {      "id": "string",      "program_id": "string",      "code": "string",      "name": "string",      "color": "string",      "icon": "string",      "builtin": true,      "position": 0    }  ]}
DELETE
/meetings/{meeting_id}/exceptions/{original_date}

The class happens again as regularly scheduled. Use when a class cancelled or moved with schedule.exception.upsert takes place after all.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

meeting_id*Meeting Id

Meeting id

original_date*Original Date

Regular date of the changed class

Formatdate

Response Body

Successful Response

application/json
  1. response
id*Id
section_id*Section Id
weekday*Weekday

1 = Monday .. 7 = Sunday

start_time*Start Time

Wall-clock time in the Program's time zone

Formattime
end_time*End Time
Formattime
location*string|null
title*|

Optional name of this time, e.g. 'Lab'

enabled*Enabled

Shown in the calendar

source_kind*string|null
source_ref*string|null
exceptions*array<>

Cancelled or moved dates

created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X DELETE 'https://example.com/meetings/string/exceptions/2019-08-24'
Example Response
{  "id": "string",  "section_id": "string",  "weekday": 0,  "start_time": "14:15:22Z",  "end_time": "14:15:22Z",  "location": "string",  "title": "string",  "enabled": true,  "source_kind": "string",  "source_ref": "string",  "exceptions": [    {      "id": "string",      "meeting_id": "string",      "original_date": "2019-08-24",      "kind": "cancelled",      "new_date": "2019-08-24",      "new_start_time": "14:15:22Z",      "new_end_time": "14:15:22Z",      "new_location": "string",      "note": "string",      "imported": true    }  ],  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}
PUT
/meetings/{meeting_id}/exceptions/{original_date}

Use for "class is cancelled on Friday" or "Tuesday's lecture moves to room X". original_date must be a date the meeting normally happens on. Prefer this over deleting the meeting.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

meeting_id*Meeting Id

Meeting id

original_date*Original Date

The regular date of the class to change

Formatdate

Request Body

application/json
  1. body
kind*Kind

Cancel it, or move it

Value in"cancelled""moved"
new_date?|

Moved: new date (default: same day)

new_start_time?|

Moved: new start time

new_end_time?|

Moved: new end time

new_location?|

Moved: new location; null keeps the meeting's, "" means none

note?|

Note shown with the class

Response Body

Successful Response

application/json
  1. response
id*Id
section_id*Section Id
weekday*Weekday

1 = Monday .. 7 = Sunday

start_time*Start Time

Wall-clock time in the Program's time zone

Formattime
end_time*End Time
Formattime
location*string|null
title*|

Optional name of this time, e.g. 'Lab'

enabled*Enabled

Shown in the calendar

source_kind*string|null
source_ref*string|null
exceptions*array<>

Cancelled or moved dates

created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X PUT 'https://example.com/meetings/string/exceptions/2019-08-24' \  -H 'Content-Type: application/json' \  -d '{  "kind": "cancelled"}'
Example Response
{  "id": "string",  "section_id": "string",  "weekday": 0,  "start_time": "14:15:22Z",  "end_time": "14:15:22Z",  "location": "string",  "title": "string",  "enabled": true,  "source_kind": "string",  "source_ref": "string",  "exceptions": [    {      "id": "string",      "meeting_id": "string",      "original_date": "2019-08-24",      "kind": "cancelled",      "new_date": "2019-08-24",      "new_start_time": "14:15:22Z",      "new_end_time": "14:15:22Z",      "new_location": "string",      "note": "string",      "imported": true    }  ],  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}
GET
/programs/{program_id}/calendar-feed

One link per Program; None while it is off.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Response Body

Successful Response

application/json
  1. response
feed*|

The Program's link; None while it is off

Example Request
curl -X GET 'https://example.com/programs/string/calendar-feed'
Example Response
{  "feed": {    "id": "string",    "program_id": "string",    "prefix": "string",    "url": "string",    "sources": [      "schedule"    ],    "created_at": "2019-08-24T14:15:22Z",    "last_fetched_at": "2019-08-24T14:15:22Z",    "revoked_at": "2019-08-24T14:15:22Z"  }}
POST
/programs/{program_id}/calendar-feed

Anyone with the link can read the calendar. Returns the existing link if on.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

program_id*Program Id

Program id

Request Body

application/json
  1. body
sources?array<>

What the feed contains

Items1 <= items

Response Body

Successful Response

application/json
  1. response
id*Id
program_id*Program Id
prefix*Prefix

First characters of the token

url*|

Subscription URL; anyone with it can read the calendar. None for a link that cannot be shown again (made by an older version): reset gives a new one

sources*array<>
created_at*Created At
Formatdate-time
last_fetched_at*|null
revoked_at*|null
Example Request
curl -X POST 'https://example.com/programs/string/calendar-feed' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "id": "string",  "program_id": "string",  "prefix": "string",  "url": "string",  "sources": [    "schedule"  ],  "created_at": "2019-08-24T14:15:22Z",  "last_fetched_at": "2019-08-24T14:15:22Z",  "revoked_at": "2019-08-24T14:15:22Z"}
POST
/calendar-feeds/{feed_id}/reset

Calendars subscribed to the old address stop updating.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

feed_id*Feed Id

Feed id

Response Body

Successful Response

application/json
  1. response
id*Id
program_id*Program Id
prefix*Prefix

First characters of the token

url*|

Subscription URL; anyone with it can read the calendar. None for a link that cannot be shown again (made by an older version): reset gives a new one

sources*array<>
created_at*Created At
Formatdate-time
last_fetched_at*|null
revoked_at*|null
Example Request
curl -X POST 'https://example.com/calendar-feeds/string/reset'
Example Response
{  "id": "string",  "program_id": "string",  "prefix": "string",  "url": "string",  "sources": [    "schedule"  ],  "created_at": "2019-08-24T14:15:22Z",  "last_fetched_at": "2019-08-24T14:15:22Z",  "revoked_at": "2019-08-24T14:15:22Z"}
PATCH
/calendar-feeds/{feed_id}

Subscribed calendars pick up the change on their next refresh.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

feed_id*Feed Id

Feed id

Request Body

application/json
  1. body
sources*array<>

What the feed contains

Items1 <= items

Response Body

Successful Response

application/json
  1. response
id*Id
program_id*Program Id
prefix*Prefix

First characters of the token

url*|

Subscription URL; anyone with it can read the calendar. None for a link that cannot be shown again (made by an older version): reset gives a new one

sources*array<>
created_at*Created At
Formatdate-time
last_fetched_at*|null
revoked_at*|null
Example Request
curl -X PATCH 'https://example.com/calendar-feeds/string' \  -H 'Content-Type: application/json' \  -d '{  "sources": [    "schedule"  ]}'
Example Response
{  "id": "string",  "program_id": "string",  "prefix": "string",  "url": "string",  "sources": [    "schedule"  ],  "created_at": "2019-08-24T14:15:22Z",  "last_fetched_at": "2019-08-24T14:15:22Z",  "revoked_at": "2019-08-24T14:15:22Z"}
DELETE
/calendar-feeds/{feed_id}

Calendars subscribed to it stop updating.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

feed_id*Feed Id

Feed id

Response Body

Successful Response

application/json
  1. response
id*Id
program_id*Program Id
prefix*Prefix

First characters of the token

url*|

Subscription URL; anyone with it can read the calendar. None for a link that cannot be shown again (made by an older version): reset gives a new one

sources*array<>
created_at*Created At
Formatdate-time
last_fetched_at*|null
revoked_at*|null
Example Request
curl -X DELETE 'https://example.com/calendar-feeds/string'
Example Response
{  "id": "string",  "program_id": "string",  "prefix": "string",  "url": "string",  "sources": [    "schedule"  ],  "created_at": "2019-08-24T14:15:22Z",  "last_fetched_at": "2019-08-24T14:15:22Z",  "revoked_at": "2019-08-24T14:15:22Z"}
POST
/sections/{section_id}/meetings

The time runs in the section's weeks. Check schedule.conflict.list afterwards and mention any overlap.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

section_id*Section Id

Section the time belongs to

Request Body

application/json
  1. body
weekday*Weekday

1 = Monday .. 7 = Sunday

Range1 <= value <= 7
start_time*Start Time

Start, wall-clock time in the Program's time zone

Formattime
end_time*End Time

End, after the start

Formattime
location?|

Room or building

title?|

Optional name of this time

enabled?Enabled

False hides it from the calendar

Defaulttrue

Response Body

Successful Response

application/json
  1. response
id*Id
section_id*Section Id
weekday*Weekday

1 = Monday .. 7 = Sunday

start_time*Start Time

Wall-clock time in the Program's time zone

Formattime
end_time*End Time
Formattime
location*string|null
title*|

Optional name of this time, e.g. 'Lab'

enabled*Enabled

Shown in the calendar

source_kind*string|null
source_ref*string|null
exceptions*array<>

Cancelled or moved dates

created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X POST 'https://example.com/sections/string/meetings' \  -H 'Content-Type: application/json' \  -d '{  "weekday": 1,  "start_time": "14:15:22Z",  "end_time": "14:15:22Z"}'
Example Response
{  "id": "string",  "section_id": "string",  "weekday": 0,  "start_time": "14:15:22Z",  "end_time": "14:15:22Z",  "location": "string",  "title": "string",  "enabled": true,  "source_kind": "string",  "source_ref": "string",  "exceptions": [    {      "id": "string",      "meeting_id": "string",      "original_date": "2019-08-24",      "kind": "cancelled",      "new_date": "2019-08-24",      "new_start_time": "14:15:22Z",      "new_end_time": "14:15:22Z",      "new_location": "string",      "note": "string",      "imported": true    }  ],  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}
PATCH
/meetings/{meeting_id}

Changes every week. The weeks are the section's: schedule.section.update. To change or cancel a single date use schedule.exception.upsert instead.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

meeting_id*Meeting Id

Meeting id

Request Body

application/json
  1. body
weekday?|

1 = Monday .. 7 = Sunday

start_time?|

Start time

end_time?|

End time

location?|

Location, or null

title?|

Title, or null

enabled?|

Shown in the calendar

Response Body

Successful Response

application/json
  1. response
id*Id
section_id*Section Id
weekday*Weekday

1 = Monday .. 7 = Sunday

start_time*Start Time

Wall-clock time in the Program's time zone

Formattime
end_time*End Time
Formattime
location*string|null
title*|

Optional name of this time, e.g. 'Lab'

enabled*Enabled

Shown in the calendar

source_kind*string|null
source_ref*string|null
exceptions*array<>

Cancelled or moved dates

created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X PATCH 'https://example.com/meetings/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "id": "string",  "section_id": "string",  "weekday": 0,  "start_time": "14:15:22Z",  "end_time": "14:15:22Z",  "location": "string",  "title": "string",  "enabled": true,  "source_kind": "string",  "source_ref": "string",  "exceptions": [    {      "id": "string",      "meeting_id": "string",      "original_date": "2019-08-24",      "kind": "cancelled",      "new_date": "2019-08-24",      "new_start_time": "14:15:22Z",      "new_end_time": "14:15:22Z",      "new_location": "string",      "note": "string",      "imported": true    }  ],  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}
DELETE
/meetings/{meeting_id}

A section's last time goes with the section. To cancel one class use schedule.exception.upsert with kind 'cancelled'; to hide a section the user does not attend use schedule.meeting.set_enabled.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

meeting_id*Meeting Id

Meeting id

Response Body

Successful Response

application/json
  1. response
deleted?Deleted
Defaulttrue
Example Request
curl -X DELETE 'https://example.com/meetings/string'
Example Response
{  "deleted": true}
PUT
/courses/{course_id}/meetings:enabled

To hide a whole section, pass all of its meetings. To keep only one section, pass its meetings with enabled=true and the other sections' meetings as other_meeting_ids. Disabled meetings stay in the course but are left out of the calendar. Returns only the meetings whose state changed (empty when they already were as asked).

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

course_id*Course Id

Course id

Request Body

application/json
  1. body
meeting_ids*array<>

Meetings to change

Items1 <= items <= 200
enabled*Enabled

True to show them, false to hide them

other_meeting_ids?array<>

Meetings set to the opposite state in the same change, e.g. the other sections when keeping only one

Itemsitems <= 200

Response Body

Successful Response

application/json
  1. response
items*array<>
Example Request
curl -X PUT 'https://example.com/courses/string/meetings:enabled' \  -H 'Content-Type: application/json' \  -d '{  "meeting_ids": [    "string"  ],  "enabled": true}'
Example Response
{  "items": [    {      "id": "string",      "section_id": "string",      "weekday": 0,      "start_time": "14:15:22Z",      "end_time": "14:15:22Z",      "location": "string",      "title": "string",      "enabled": true,      "source_kind": "string",      "source_ref": "string",      "exceptions": [        {          "id": "string",          "meeting_id": "string",          "original_date": "2019-08-24",          "kind": "cancelled",          "new_date": "2019-08-24",          "new_start_time": "14:15:22Z",          "new_end_time": "14:15:22Z",          "new_location": "string",          "note": "string",          "imported": true        }      ],      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  ]}
POST
/courses/{course_id}/sections:batch

Each section runs in one of the course's terms; times are wall-clock times in the Program's time zone, and all times of a section share its weeks. A section code the course already has in that term adds the times to that section. Check schedule.conflict.list afterwards and mention any overlap. For a single extra session (exam, make-up class) use schedule.event.create_many instead.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

course_id*Course Id

Course id

Request Body

application/json
  1. body
sections*array<>

Sections

Items1 <= items <= 50

Response Body

Successful Response

application/json
  1. response
items*array<>

The sections written, with all their times

created_ids*array<string>

Meetings added

updated_ids*array<string>

Meetings that existed and were updated

Example Request
curl -X POST 'https://example.com/courses/string/sections:batch' \  -H 'Content-Type: application/json' \  -d '{  "sections": [    {      "term_id": "string",      "type_code": "string",      "meetings": [        {          "weekday": 1,          "start_time": "14:15:22Z",          "end_time": "14:15:22Z"        }      ]    }  ]}'
Example Response
{  "items": [    {      "id": "string",      "course_id": "string",      "term_id": "string",      "type_code": "string",      "section_code": "string",      "instructor": "string",      "recurrence": "weekly",      "anchor_week": 0,      "start_week": 0,      "end_week": 0,      "skip_breaks": true,      "meetings": [        {          "id": "string",          "section_id": "string",          "weekday": 0,          "start_time": "14:15:22Z",          "end_time": "14:15:22Z",          "location": "string",          "title": "string",          "enabled": true,          "source_kind": "string",          "source_ref": "string",          "exceptions": [            {              "id": "string",              "meeting_id": "string",              "original_date": "2019-08-24",              "kind": "cancelled",              "new_date": "2019-08-24",              "new_start_time": "14:15:22Z",              "new_end_time": "14:15:22Z",              "new_location": "string",              "note": "string",              "imported": true            }          ],          "created_at": "2019-08-24T14:15:22Z",          "updated_at": "2019-08-24T14:15:22Z"        }      ],      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  ],  "created_ids": [    "string"  ],  "updated_ids": [    "string"  ]}
PATCH
/sections/{section_id}

The weeks apply to every weekly time of the section. To change one time's day, hours or room use schedule.meeting.update; to change or cancel a single date use schedule.exception.upsert.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

section_id*Section Id

Section id

Request Body

application/json
  1. body
term_id?|

Another term of the course

type_code?|

Event type code

section_code?|

Section code

instructor?|

Instructor, or null

recurrence?|

weekly or biweekly

anchor_week?|

Biweekly anchor week; null = the first week

start_week?|

First term week

end_week?|

Last term week, or null

skip_breaks?|

Skip breaks

Response Body

Successful Response

application/json
  1. response

A class section with its weekly times; all of them run in the section's weeks.

id*Id
course_id*Course Id
term_id*Term Id
type_code*Type Code
section_code*Section Code

e.g. 'LEC0101'; empty when the source has none

instructor*string|null
recurrence*Recurrence
Value in"weekly""biweekly"
anchor_week*Anchor Week

Biweekly: the term week it starts alternating from

start_week*Start Week
end_week*|

Last term week; null = until the end of term

skip_breaks*Skip Breaks
meetings*array<>

Weekly times, by weekday and start time

created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X PATCH 'https://example.com/sections/string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "id": "string",  "course_id": "string",  "term_id": "string",  "type_code": "string",  "section_code": "string",  "instructor": "string",  "recurrence": "weekly",  "anchor_week": 0,  "start_week": 0,  "end_week": 0,  "skip_breaks": true,  "meetings": [    {      "id": "string",      "section_id": "string",      "weekday": 0,      "start_time": "14:15:22Z",      "end_time": "14:15:22Z",      "location": "string",      "title": "string",      "enabled": true,      "source_kind": "string",      "source_ref": "string",      "exceptions": [        {          "id": "string",          "meeting_id": "string",          "original_date": "2019-08-24",          "kind": "cancelled",          "new_date": "2019-08-24",          "new_start_time": "14:15:22Z",          "new_end_time": "14:15:22Z",          "new_location": "string",          "note": "string",          "imported": true        }      ],      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  ],  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}
DELETE
/sections/{section_id}

To hide a section the user does not attend use schedule.meeting.set_enabled instead; to cancel one class use schedule.exception.upsert.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

section_id*Section Id

Section id

Response Body

Successful Response

application/json
  1. response
deleted?Deleted
Defaulttrue
Example Request
curl -X DELETE 'https://example.com/sections/string'
Example Response
{  "deleted": true}
GET
/courses/{course_id}/sections

Use to see when a course meets each week, or to find a section or meeting id before changing or cancelling a class. A section (e.g. LEC0101) has one or more weekly times (meetings) that all run in the section's weeks. Optionally only one term of a year-long course.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

course_id*Course Id

Course id

Query Parameters

term_id?|

Only this term's sections

Response Body

Successful Response

application/json
  1. response
items*array<>

By term, type and section code

Example Request
curl -X GET 'https://example.com/courses/string/sections'
Example Response
{  "items": [    {      "id": "string",      "course_id": "string",      "term_id": "string",      "type_code": "string",      "section_code": "string",      "instructor": "string",      "recurrence": "weekly",      "anchor_week": 0,      "start_week": 0,      "end_week": 0,      "skip_breaks": true,      "meetings": [        {          "id": "string",          "section_id": "string",          "weekday": 0,          "start_time": "14:15:22Z",          "end_time": "14:15:22Z",          "location": "string",          "title": "string",          "enabled": true,          "source_kind": "string",          "source_ref": "string",          "exceptions": [            {              "id": "string",              "meeting_id": "string",              "original_date": "2019-08-24",              "kind": "cancelled",              "new_date": "2019-08-24",              "new_start_time": "14:15:22Z",              "new_end_time": "14:15:22Z",              "new_location": "string",              "note": "string",              "imported": true            }          ],          "created_at": "2019-08-24T14:15:22Z",          "updated_at": "2019-08-24T14:15:22Z"        }      ],      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  ]}
PUT
/courses/{course_id}/sections

The app's section editor: the section's fields and weeks, and its times updated, added and deleted together. Sem and MCP use schedule.section.update and the schedule.meeting tools.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

course_id*Course Id

Course id

Request Body

application/json
  1. body
term_id*Term Id

Term of the course the section runs in

Length1 <= length <= 64
type_code*Type Code

Event type code of the Program, e.g. 'LEC'

Match^[A-Za-z0-9]{1,8}$
section_code?Section Code

Section, e.g. 'LEC0101'

Lengthlength <= 32
Default""
instructor?|

Instructor

section_id?|

The section edited; null adds one

weeks?

Weeks of all times

times*array<>

Its weekly times

Items1 <= items <= 20

Response Body

Successful Response

application/json
  1. response

A class section with its weekly times; all of them run in the section's weeks.

id*Id
course_id*Course Id
term_id*Term Id
type_code*Type Code
section_code*Section Code

e.g. 'LEC0101'; empty when the source has none

instructor*string|null
recurrence*Recurrence
Value in"weekly""biweekly"
anchor_week*Anchor Week

Biweekly: the term week it starts alternating from

start_week*Start Week
end_week*|

Last term week; null = until the end of term

skip_breaks*Skip Breaks
meetings*array<>

Weekly times, by weekday and start time

created_at*Created At
Formatdate-time
updated_at*Updated At
Formatdate-time
Example Request
curl -X PUT 'https://example.com/courses/string/sections' \  -H 'Content-Type: application/json' \  -d '{  "term_id": "string",  "type_code": "string",  "times": [    {      "weekday": 1,      "start_time": "14:15:22Z",      "end_time": "14:15:22Z"    }  ]}'
Example Response
{  "id": "string",  "course_id": "string",  "term_id": "string",  "type_code": "string",  "section_code": "string",  "instructor": "string",  "recurrence": "weekly",  "anchor_week": 0,  "start_week": 0,  "end_week": 0,  "skip_breaks": true,  "meetings": [    {      "id": "string",      "section_id": "string",      "weekday": 0,      "start_time": "14:15:22Z",      "end_time": "14:15:22Z",      "location": "string",      "title": "string",      "enabled": true,      "source_kind": "string",      "source_ref": "string",      "exceptions": [        {          "id": "string",          "meeting_id": "string",          "original_date": "2019-08-24",          "kind": "cancelled",          "new_date": "2019-08-24",          "new_start_time": "14:15:22Z",          "new_end_time": "14:15:22Z",          "new_location": "string",          "note": "string",          "imported": true        }      ],      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  ],  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}
GET
/terms/{term_id}/sections

For the term timetable; schedule.section.list is per course.

Authorization

cookiesemestra_session<token>

Set by the sign-in endpoints for the web app. Requests other than GET, HEAD and OPTIONS also need the X-Semestra-CSRF header set to the semestra_csrf cookie.

Path Parameters

term_id*Term Id

Term id

Response Body

Successful Response

application/json
  1. response
items*array<>

By term, type and section code

Example Request
curl -X GET 'https://example.com/terms/string/sections'
Example Response
{  "items": [    {      "id": "string",      "course_id": "string",      "term_id": "string",      "type_code": "string",      "section_code": "string",      "instructor": "string",      "recurrence": "weekly",      "anchor_week": 0,      "start_week": 0,      "end_week": 0,      "skip_breaks": true,      "meetings": [        {          "id": "string",          "section_id": "string",          "weekday": 0,          "start_time": "14:15:22Z",          "end_time": "14:15:22Z",          "location": "string",          "title": "string",          "enabled": true,          "source_kind": "string",          "source_ref": "string",          "exceptions": [            {              "id": "string",              "meeting_id": "string",              "original_date": "2019-08-24",              "kind": "cancelled",              "new_date": "2019-08-24",              "new_start_time": "14:15:22Z",              "new_end_time": "14:15:22Z",              "new_location": "string",              "note": "string",              "imported": true            }          ],          "created_at": "2019-08-24T14:15:22Z",          "updated_at": "2019-08-24T14:15:22Z"        }      ],      "created_at": "2019-08-24T14:15:22Z",      "updated_at": "2019-08-24T14:15:22Z"    }  ]}