attendance

Attendance

Per-session attendance rosters and marks.

5 endpoints

GET /api/v1/groups/{id}/attendance/summary

Per-student attendance rates and totals for one group, sorted by rate ascending.

Requires authenticationScopeattendance.read

Path & query parameters

NameInTypeConstraints
idrequired
pathstring
from
querystring (date)
to
querystring (date)

curl example

curl
curl -X GET "https://api.yourdomain.com/api/v1/groups/37386ae0-3738-7738-8386-37386ae03738/attendance/summary" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

Responses

200
NameTypeConstraints
groupIdrequired
string (uuid)
fromrequired
string (date)
torequired
string (date)
studentsrequired
array<object>
json
{
  "groupId": "6dc7fce6-6dc7-7dc7-8c7f-6dc7fce66dc7",
  "from": "2026-03-02",
  "to": "2026-03-02",
  "students": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "firstName": "Ada",
      "lastName": "Lovelace",
      "present": 0,
      "absent": 0,
      "late": 0,
      "excused": 0,
      "totalHeld": 0,
      "rate": 0
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

GET /api/v1/me/attendance

Self attendance (student) or one linked child’s attendance (guardian, via `?studentId`).

Requires authenticationScopeNo additional permission

Path & query parameters

NameInTypeConstraints
cursor
querystring
limit
queryinteger1–100 · default: 25
from
querystring (date)
to
querystring (date)
studentId
querystring (uuid)

curl example

curl
curl -X GET "https://api.yourdomain.com/api/v1/me/attendance" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

Responses

200
NameTypeConstraints
datarequired
array<object>
nextCursorrequired
string | null
raterequired
object
json
{
  "data": [
    {
      "sessionId": "736a51cd-736a-736a-86a5-736a51cd736a",
      "groupId": "6dc7fce6-6dc7-7dc7-8c7f-6dc7fce66dc7",
      "scheduledStart": "2026-03-02T09:00:00.000Z",
      "status": "present",
      "minutesLate": 0,
      "note": "string",
      "markedAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "nextCursor": null,
  "rate": {
    "present": 0,
    "absent": 0,
    "late": 0,
    "excused": 0,
    "totalHeld": 0,
    "rate": 0
  }
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

GET /api/v1/sessions/{id}/attendance

Roster for one session: every actively-enrolled student, merged with any existing attendance records.

Requires authenticationScopeattendance.read

Path & query parameters

NameInTypeConstraints
idrequired
pathstring

curl example

curl
curl -X GET "https://api.yourdomain.com/api/v1/sessions/37386ae0-3738-7738-8386-37386ae03738/attendance" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

Responses

200
NameTypeConstraints
sessionIdrequired
string (uuid)
groupIdrequired
string (uuid)
scheduledStartrequired
string (date-time)
statusrequired
enum: "scheduled" | "held" | "cancelled"
entriesrequired
array<object>
json
{
  "sessionId": "736a51cd-736a-736a-86a5-736a51cd736a",
  "groupId": "6dc7fce6-6dc7-7dc7-8c7f-6dc7fce66dc7",
  "scheduledStart": "2026-03-02T09:00:00.000Z",
  "status": "scheduled",
  "entries": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "firstName": "Ada",
      "lastName": "Lovelace",
      "status": "present",
      "minutesLate": 0,
      "note": "string",
      "markedAt": "2026-03-02T09:00:00.000Z"
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

PUT /api/v1/sessions/{id}/attendance

Bulk upsert one session’s attendance. Marks the session held; idempotent (re-PUT updates statuses).

Requires authenticationScopeattendance.mark

Path & query parameters

NameInTypeConstraints
idrequired
pathstring

Request body

NameTypeConstraints
entriesrequired
array<object>

Example

json
{
  "entries": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "status": "present",
      "minutesLate": 0,
      "note": "string"
    }
  ]
}

curl example

curl
curl -X PUT "https://api.yourdomain.com/api/v1/sessions/37386ae0-3738-7738-8386-37386ae03738/attendance" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "entries": [
      {
        "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
        "status": "present",
        "minutesLate": 0,
        "note": "string"
      }
    ]
  }'

Responses

200
NameTypeConstraints
sessionIdrequired
string (uuid)
groupIdrequired
string (uuid)
scheduledStartrequired
string (date-time)
statusrequired
enum: "scheduled" | "held" | "cancelled"
entriesrequired
array<object>
json
{
  "sessionId": "736a51cd-736a-736a-86a5-736a51cd736a",
  "groupId": "6dc7fce6-6dc7-7dc7-8c7f-6dc7fce66dc7",
  "scheduledStart": "2026-03-02T09:00:00.000Z",
  "status": "scheduled",
  "entries": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "firstName": "Ada",
      "lastName": "Lovelace",
      "status": "present",
      "minutesLate": 0,
      "note": "string",
      "markedAt": "2026-03-02T09:00:00.000Z"
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

GET /api/v1/students/{id}/attendance

One student’s attendance history (cursor-paginated) plus rate summary.

Requires authenticationScopeattendance.read

Path & query parameters

NameInTypeConstraints
idrequired
pathstring
cursor
querystring
limit
queryinteger1–100 · default: 25
from
querystring (date)
to
querystring (date)

curl example

curl
curl -X GET "https://api.yourdomain.com/api/v1/students/37386ae0-3738-7738-8386-37386ae03738/attendance" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

Responses

200
NameTypeConstraints
datarequired
array<object>
nextCursorrequired
string | null
raterequired
object
json
{
  "data": [
    {
      "sessionId": "736a51cd-736a-736a-86a5-736a51cd736a",
      "groupId": "6dc7fce6-6dc7-7dc7-8c7f-6dc7fce66dc7",
      "scheduledStart": "2026-03-02T09:00:00.000Z",
      "status": "present",
      "minutesLate": 0,
      "note": "string",
      "markedAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "nextCursor": null,
  "rate": {
    "present": 0,
    "absent": 0,
    "late": 0,
    "excused": 0,
    "totalHeld": 0,
    "rate": 0
  }
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

Returns the shared `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. Every code is listed in the Conventions guide.