Dartmouth API Developer Portal

Academic Attendance API - POST

Supports addition or update of attendance status for a student enrolled in a course.

Required Scopes

Scope Description
api:academic:enrollments:read.sensitive This scope is required in order to read sensitive enrollment attributes (e.g. final_grade, attendance). Granting of this scope is via the Undergraduate Registrars Office
api:academic:enrollments:write This scope is required in order to write enrollment attributes (i.e. attendance). Granting of this scope is via the Undergraduate Registrars Office
urn:dartmouth:people:private This optional scope is required in order to get or set attendances for FERPA-protected students. Granting of this scope is via the Undergraduate Registrars Office

Request

POST /api/academic/enrollment/attendance/

Required Headers

Authorization: Bearer {jwt}
Content-Type: application/json

Payload

POST payload must be included in the request body and must include all attendance attributes; note that meeting_date must include time and must be utc. Here is an example payload:

{
    "attendance": {
        "sis_term_code": "202001",
        "crn": "12345",
        "netid": "f000000",         // SORSATR_USER_ID
        "meeting_date": "2023-07-26T04:00:00Z", // SORSATR_MEET_DATE, YYYY-MM-DD
        "expected_hours": 65,   // SORSATR_EXPECT_HRS
        "actual_hours": 60,     // SORSATR_ACTUAL_HRS
        "absent_hours": 5,      // SORSATR_ABSENT_HRS
        "comment": "Comment text goes here", // SORSATR_COMMENT
        "has_attended": true,   // SORSATR_ATTEND_IND, stored as 'Y' or 'N'
    }
}

Notes on usage

The enrollment/attendances API checks the presence of required scopes. It then submits the request to a task queue, which returns the url of the task in the location header. The consumer must poll the task until completion. The task checks validity of the payload and then performs the task. If successful, the URL of the created or updated attendance is included in the task 'path' attribute.

The payload contains a complete attendance object: including term, student, course, meeting date/hours and has_attended boolean.

Data is written to the table SORSATR in Banner. This links to the SSRMEET table to define the course section. The data is collected into the DART_IPAAS view sis_enrollment_attendances_v.

Conversions needed: netid to pidm for SORSATR_PIDM, crn to SSRMEET id for SORSATR_SURROGATE_ID_SSRMEET

The function in Banner that processes and stores the data is ban_data_mgr.api_enrl_attendance_patching.create_attendance_record

Returns

Status Code Description
202 The required scopes are in place and the task has been added to the task queue
403 The required scopes are in not in place

Sample Request

https://api.dartmouth.edu/api/academic/enrollment/attendance

Sample Return

{
    "status": "accepted"
}

Sample Response Header

Location: /api/tasks/5cddb466b68a450c3b102bfd

Task Monitoring

After a POST request has been accepted, the consumer must poll the task until completion using the following request:

GET /api/tasks/{id}

Here is an example using the task id from above:

https://api.dartmouth.edu/api/tasks/5cddb466b68a450c3b102bfd

Sample Incomplete Task

For incomplete tasks, status is 'accepted'; path and message are null:

{
    "resource": "academic.enrollment.attendances",
    "action": "POST",
    "resource_id": null,
    "payload": {
        "attendance": {
            "sis_term_code": "202306",
            "crn": "60704",
            "netid": "f005ck1",
            "meeting_date": "2023-07-26T04:00:00Z",
            "expected_hours": 51,
            "actual_hours": 61,
            "absent_hours": 0,
            "comment": "Comment text goes here",
            "has_attended": true
        }
    },
    "requester": {
        "sub": "f003ghc",
        "name": "Integration Test User",
        "email": "Integration.Test.User@dartmouth.edu",
        "scope": "api:academic:enrollments:write,api:academic:enrollments:read.sensitive",
        "exp": "1691014663",
        "iat": "1691003863"
    },
    "status": "accepted",
    "request_date": "2023-08-02T19:17:58Z",
    "completed_date": null,
    "path": null,
    "worker_data": null,
    "id": "5cddb466b68a450c3b102bfd",
    "message": null
}

Sample Successfull Task

For successfully completed tasks, path is set to the url of the attendance that was created and message provides details of the operation completed.

{
    "resource": "academic.enrollment.attendances",
    "action": "POST",
    "resource_id": null,
    "payload": {
        "attendance": {
            "sis_term_code": "202306",
            "crn": "60704",
            "netid": "f005ck1",
            "meeting_date": "2023-07-26T04:00:00Z",
            "expected_hours": 51,
            "actual_hours": 61,
            "absent_hours": 0,
            "comment": "Comment text goes here",
            "has_attended": true
        }
    },
    "requester": {
        "sub": "f003ghc",
        "name": "Integration Test User",
        "email": "Integration.Test.User@dartmouth.edu",
        "scope": "api:academic:enrollments:write,api:academic:enrollments:read.sensitive",
        "exp": "1691014663",
        "iat": "1691003863"
    },
    "status": "complete",
    "request_date": "2023-08-02T19:17:58Z",
    "completed_date": "2023-08-02T19:17:59.923515",
    "path": "/academic/enrollment/attendances/64c95fddac69d92a5de09821",
    "worker_data": {},
    "id": "64caabe62ef1539044c5abf7",
    "message": "Attendance created successfully."
}

Sample Failed Task

For failed tasks, path is set to the called url and message provides details of the failure.

{
    "resource": "academic.enrollment.attendances",
    "action": "POST",
    "resource_id": null,
    "payload": {
        "attendance": {
            "xxsis_term_code": "202306",
            "crn": "60704",
            "netid": "f005ck1",
            "xxmeeting_date": "2023-07-26T04:00:00Z",
            "expected_hours": "55",
            "actual_hours": 56,
            "absent_hours": 0,
            "comment": "Comment text goes here",
            "has_attended": true
        }
    },
    "requester": {
        "sub": "f003ghc",
        "name": "Integration Test User",
        "email": "Integration.Test.User@dartmouth.edu",
        "scope": "api:academic:enrollments:write,api:academic:enrollments:read.sensitive",
        "exp": "1691083255",
        "iat": "1691072455"
    },
    "status": "error",
    "request_date": "2023-08-03T14:21:26Z",
    "completed_date": null,
    "path": null,
    "worker_data": {},
    "id": "64cbb7e6340005f7f7170fff",
    "message": "Payload is invalid: [<ValidationError: \"'55' is not of type 'number'\">, <ValidationError: \"'sis_term_code' is a required property\">, <ValidationError: \"'meeting_date' is a required property\">]"
}