> For the complete documentation index, see [llms.txt](https://docs.mymedtrics.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mymedtrics.com/api-reference/connect-api/models.md).

# Models

## The ErrorEnvelope object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"ErrorEnvelope":{"type":"object","required":["error"],"description":"Structured error envelope. error.code is the machine-readable discriminant. Typed detail schemas are provided for codes where structured data aids client remediation. Use the discriminator.mapping to select the correct variant schema; for all other codes see GenericApiError.\n","properties":{"error":{"anyOf":[{"$ref":"#/components/schemas/InvalidStatusError"},{"$ref":"#/components/schemas/InvalidWebhookEventsError"},{"$ref":"#/components/schemas/RateLimitedError"},{"$ref":"#/components/schemas/CursorResourceMismatchError"},{"$ref":"#/components/schemas/InvalidIdError"},{"$ref":"#/components/schemas/UnsupportedApiDateError"},{"$ref":"#/components/schemas/InactiveClientError"},{"$ref":"#/components/schemas/InvalidWebhookUrlError"},{"$ref":"#/components/schemas/GenericApiError"}],"discriminator":{"propertyName":"code","mapping":{"invalid_status":"#/components/schemas/InvalidStatusError","invalid_webhook_events":"#/components/schemas/InvalidWebhookEventsError","rate_limited":"#/components/schemas/RateLimitedError","cursor_resource_mismatch":"#/components/schemas/CursorResourceMismatchError","invalid_id":"#/components/schemas/InvalidIdError","unsupported_api_date":"#/components/schemas/UnsupportedApiDateError","inactive_client":"#/components/schemas/InactiveClientError","invalid_webhook_url":"#/components/schemas/InvalidWebhookUrlError"}}}}},"InvalidStatusError":{"description":"Returned when a status query parameter value is outside the allowed enum. HTTP 400. details.field identifies the parameter; details.allowed lists every accepted value.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"invalid_status"},"details":{"type":"object","required":["field","allowed"],"additionalProperties":false,"description":"Structured remediation data for invalid_status.","properties":{"field":{"type":"string","description":"Query parameter name that received the invalid value (e.g. enrollment_status, status).\n"},"allowed":{"type":"array","items":{"type":"string"},"description":"Full list of accepted values for the parameter."}}}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}},"InvalidWebhookEventsError":{"description":"Returned when event_types contains values not in the approved Connect API event list, or when event_types is empty. HTTP 400. details.unsupported_events lists the rejected entries (empty array when event_types was missing or entirely empty).\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"invalid_webhook_events"},"details":{"type":"object","required":["unsupported_events"],"additionalProperties":false,"description":"Structured remediation data for invalid_webhook_events.","properties":{"unsupported_events":{"type":"array","items":{"type":"string"},"description":"Event type strings that are not approved Connect API event names. Empty array indicates event_types was missing or contained only invalid entries.\n"}}}}}]},"RateLimitedError":{"description":"Returned when the request or API app rate limit is exceeded. HTTP 429. details.retry_after_seconds indicates the wait duration before retrying.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"rate_limited"},"details":{"type":"object","required":["retry_after_seconds"],"additionalProperties":false,"description":"Structured remediation data for rate_limited.","properties":{"retry_after_seconds":{"type":"integer","description":"Seconds to wait before retrying. Mirrors the Retry-After response header value.\n"}}}}}]},"CursorResourceMismatchError":{"description":"Returned when the cursor was issued for a different resource type than the endpoint being called. HTTP 400. details.expected_resource is the resource this endpoint serves; details.cursor_resource is what the cursor encodes.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"cursor_resource_mismatch"},"details":{"type":"object","required":["expected_resource","cursor_resource"],"additionalProperties":false,"description":"Structured remediation data for cursor_resource_mismatch.","properties":{"expected_resource":{"type":"string","description":"Resource type this endpoint serves (e.g. programs, learners)."},"cursor_resource":{"type":"string","description":"Resource type encoded in the submitted cursor."}}}}}]},"InvalidIdError":{"description":"Returned when a path parameter public ID does not match the expected prefix for the resource. HTTP 400. details.field is the parameter name; details.expected_prefix is the required ID prefix.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"invalid_id"},"details":{"type":"object","required":["field","expected_prefix"],"additionalProperties":false,"description":"Structured remediation data for invalid_id.","properties":{"field":{"type":"string","description":"Path or query parameter name that received the invalid ID."},"expected_prefix":{"type":"string","description":"Required ID prefix for this parameter."}}}}}]},"UnsupportedApiDateError":{"description":"Returned when the Medtrics-API-Date header is missing, malformed (not YYYY-MM-DD), or not a supported contract date. HTTP 400. details.supported_dates lists all accepted values. details.reason is one of \"missing\", \"malformed\", or \"not_supported\".\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"unsupported_api_date"},"details":{"type":"object","required":["reason","supported_dates"],"additionalProperties":false,"description":"Structured remediation data for unsupported_api_date.","properties":{"reason":{"type":"string","enum":["missing","malformed","not_supported"],"description":"Specific cause: \"missing\" when the header is absent, \"malformed\" when the value is not YYYY-MM-DD format, \"not_supported\" when the format is valid but the date is not a known contract date.\n"},"supported_dates":{"type":"array","items":{"type":"string"},"description":"All accepted Medtrics-API-Date values."}}}}}]},"InactiveClientError":{"description":"Returned when the authenticated API client is revoked, expired, deleted, or in a non-active status. HTTP 403. No structured details beyond the human-readable message.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","properties":{"code":{"type":"string","const":"inactive_client"}}}]},"InvalidWebhookUrlError":{"description":"Returned when target_url fails HTTPS validation or is otherwise rejected. HTTP 422. No structured details field beyond the human-readable message.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","properties":{"code":{"type":"string","const":"invalid_webhook_url"}}}]},"GenericApiError":{"description":"Catch-all error variant for codes that carry no structured remediation data (invalid_cursor, not_found, invalid_credentials, scope_not_allowed, invalid_webhook_tolerance, internal_error, and any future codes not covered by a typed variant in the discriminator.mapping). details is absent or empty for these codes.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","properties":{"details":{"type":"object","additionalProperties":true,"description":"Absent or empty for most generic error codes."}}}]}}}}
```

## The ApiErrorBase object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The GenericApiError object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"GenericApiError":{"description":"Catch-all error variant for codes that carry no structured remediation data (invalid_cursor, not_found, invalid_credentials, scope_not_allowed, invalid_webhook_tolerance, internal_error, and any future codes not covered by a typed variant in the discriminator.mapping). details is absent or empty for these codes.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","properties":{"details":{"type":"object","additionalProperties":true,"description":"Absent or empty for most generic error codes."}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The InvalidStatusError object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"InvalidStatusError":{"description":"Returned when a status query parameter value is outside the allowed enum. HTTP 400. details.field identifies the parameter; details.allowed lists every accepted value.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"invalid_status"},"details":{"type":"object","required":["field","allowed"],"additionalProperties":false,"description":"Structured remediation data for invalid_status.","properties":{"field":{"type":"string","description":"Query parameter name that received the invalid value (e.g. enrollment_status, status).\n"},"allowed":{"type":"array","items":{"type":"string"},"description":"Full list of accepted values for the parameter."}}}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The InvalidWebhookEventsError object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"InvalidWebhookEventsError":{"description":"Returned when event_types contains values not in the approved Connect API event list, or when event_types is empty. HTTP 400. details.unsupported_events lists the rejected entries (empty array when event_types was missing or entirely empty).\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"invalid_webhook_events"},"details":{"type":"object","required":["unsupported_events"],"additionalProperties":false,"description":"Structured remediation data for invalid_webhook_events.","properties":{"unsupported_events":{"type":"array","items":{"type":"string"},"description":"Event type strings that are not approved Connect API event names. Empty array indicates event_types was missing or contained only invalid entries.\n"}}}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The CursorResourceMismatchError object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"CursorResourceMismatchError":{"description":"Returned when the cursor was issued for a different resource type than the endpoint being called. HTTP 400. details.expected_resource is the resource this endpoint serves; details.cursor_resource is what the cursor encodes.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"cursor_resource_mismatch"},"details":{"type":"object","required":["expected_resource","cursor_resource"],"additionalProperties":false,"description":"Structured remediation data for cursor_resource_mismatch.","properties":{"expected_resource":{"type":"string","description":"Resource type this endpoint serves (e.g. programs, learners)."},"cursor_resource":{"type":"string","description":"Resource type encoded in the submitted cursor."}}}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The InvalidIdError object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"InvalidIdError":{"description":"Returned when a path parameter public ID does not match the expected prefix for the resource. HTTP 400. details.field is the parameter name; details.expected_prefix is the required ID prefix.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"invalid_id"},"details":{"type":"object","required":["field","expected_prefix"],"additionalProperties":false,"description":"Structured remediation data for invalid_id.","properties":{"field":{"type":"string","description":"Path or query parameter name that received the invalid ID."},"expected_prefix":{"type":"string","description":"Required ID prefix for this parameter."}}}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The UnsupportedApiDateError object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"UnsupportedApiDateError":{"description":"Returned when the Medtrics-API-Date header is missing, malformed (not YYYY-MM-DD), or not a supported contract date. HTTP 400. details.supported_dates lists all accepted values. details.reason is one of \"missing\", \"malformed\", or \"not_supported\".\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"unsupported_api_date"},"details":{"type":"object","required":["reason","supported_dates"],"additionalProperties":false,"description":"Structured remediation data for unsupported_api_date.","properties":{"reason":{"type":"string","enum":["missing","malformed","not_supported"],"description":"Specific cause: \"missing\" when the header is absent, \"malformed\" when the value is not YYYY-MM-DD format, \"not_supported\" when the format is valid but the date is not a known contract date.\n"},"supported_dates":{"type":"array","items":{"type":"string"},"description":"All accepted Medtrics-API-Date values."}}}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The InactiveClientError object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"InactiveClientError":{"description":"Returned when the authenticated API client is revoked, expired, deleted, or in a non-active status. HTTP 403. No structured details beyond the human-readable message.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","properties":{"code":{"type":"string","const":"inactive_client"}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The InvalidWebhookUrlError object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"InvalidWebhookUrlError":{"description":"Returned when target_url fails HTTPS validation or is otherwise rejected. HTTP 422. No structured details field beyond the human-readable message.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","properties":{"code":{"type":"string","const":"invalid_webhook_url"}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The RateLimitedError object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"RateLimitedError":{"description":"Returned when the request or API app rate limit is exceeded. HTTP 429. details.retry_after_seconds indicates the wait duration before retrying.\n","allOf":[{"$ref":"#/components/schemas/ApiErrorBase"},{"type":"object","required":["details"],"properties":{"code":{"type":"string","const":"rate_limited"},"details":{"type":"object","required":["retry_after_seconds"],"additionalProperties":false,"description":"Structured remediation data for rate_limited.","properties":{"retry_after_seconds":{"type":"integer","description":"Seconds to wait before retrying. Mirrors the Retry-After response header value.\n"}}}}}]},"ApiErrorBase":{"type":"object","required":["code","message","request_id"],"description":"Common fields shared by every Connect API error response.","properties":{"code":{"type":"string","description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable error description."},"request_id":{"type":"string","description":"Request correlation ID. Include this value when reporting issues to support alongside the Medtrics-Request-ID response header.\n"}}}}}}
```

## The Pagination object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Pagination":{"type":"object","description":"Cursor pagination envelope. Exposes only limit and next_cursor. Count fields (approximate_total, total_count_exact, or any equivalent) are intentionally absent and reserved for future Medtrics-API-Date additions once a concrete partner use case justifies a count strategy per route. pagination.limit is the effective page size after server-side clamp, not the value the client requested.","required":["limit","next_cursor"],"properties":{"limit":{"type":"integer","description":"Effective page size after server-side clamping. Compare to your requested limit to detect ceiling enforcement."},"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor. Pass as the cursor query parameter on the next request. null when no more pages exist."}}}}}}
```

## The GenericListResponse object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"GenericListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Pagination":{"type":"object","description":"Cursor pagination envelope. Exposes only limit and next_cursor. Count fields (approximate_total, total_count_exact, or any equivalent) are intentionally absent and reserved for future Medtrics-API-Date additions once a concrete partner use case justifies a count strategy per route. pagination.limit is the effective page size after server-side clamp, not the value the client requested.","required":["limit","next_cursor"],"properties":{"limit":{"type":"integer","description":"Effective page size after server-side clamping. Compare to your requested limit to detect ceiling enforcement."},"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor. Pass as the cursor query parameter on the next request. null when no more pages exist."}}}}}}
```

## The GenericItemResponse object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"GenericItemResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","additionalProperties":true}}}}}}
```

## The RoleDesignate object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"RoleDesignate":{"type":"string","description":"Work designation of a role. Canonical source is the role_designate_type DB enum.","enum":["internal","external"]}}}}
```

## The ProgramMembershipStatus object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"ProgramMembershipStatus":{"type":"string","description":"Status of a learner enrollment (program_memberships.status). Canonical source is the affiliation_status DB enum.","enum":["active","inactive","graduated","transferred","terminated","on_leave","pending"]}}}}
```

## The FormAssignmentStatusFilter object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"FormAssignmentStatusFilter":{"type":"string","description":"Filter for evaluation status. Accepts canonical form_assignments.status values plus the virtual\nvalues 'missing' (resolves in SQL to status != 'completed') and 'unable_to_assess' (resolves to\nstatus = 'cancelled' with an \"Unable to assess:\" notes prefix or metadata.unable_to_assess = true).\nThe response status field always returns the real database value; 'missing'/'unable_to_assess'\nare filter conveniences only.\n","enum":["draft","pending","in_progress","completed","overdue","cancelled","expired","declined","missing","unable_to_assess"]}}}}
```

## The FormAssignmentStatus object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"FormAssignmentStatus":{"type":"string","description":"Canonical status of a form assignment. Does not include the virtual 'missing' filter value.","enum":["draft","pending","in_progress","completed","overdue","cancelled","expired","declined"]}}}}
```

## The RotationStatus object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"RotationStatus":{"type":"string","description":"Normalized rotation assignment status returned by the gateway. draft, published, archived, and scheduled all normalize to 'scheduled'. Derived from block_schedules.status via normalizeRotationStatus().\n","enum":["scheduled","in_progress","completed","cancelled"]}}}}
```

## The Learner object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Learner":{"type":"object","description":"A person (backed by profiles.id). One learner may hold zero or more enrollments across visible programs.","required":["id","first_name","last_name","email","status","program_ids","primary_program_id","active_enrollment_count","total_enrollment_count","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the learner (learner_ prefix). Backed by profiles.id."},"first_name":{"type":"string"},"last_name":{"type":"string"},"display_name":{"type":["string","null"]},"email":{"type":"string","format":"email"},"status":{"type":"string","enum":["active","inactive"],"description":"Aggregated status. 'active' if at least one visible enrollment is currently active; otherwise 'inactive'."},"program_ids":{"type":"array","items":{"type":"string"},"description":"Array of distinct prog_ public IDs from this learner's currently active, non-ended, non-deleted enrollments within tenant scope. Returned in stable order (program_id ASC). Empty array is valid when listed with a non-active enrollment_status filter."},"primary_program_id":{"type":["string","null"],"description":"Public ID (prog_ prefix) of the enrollment with is_primary = true and status = 'active', or null if none."},"active_enrollment_count":{"type":"integer"},"total_enrollment_count":{"type":"integer"},"home_site_id":{"type":["string","null"],"description":"Public ID of the learner's home site (site_ prefix), or null when profiles.home_site_id is unset."},"home_site_legacy_id":{"type":["string","null"],"description":"Legacy source_id for the home site from etl_id_registry, or null when no ETL mapping exists."},"role_id":{"type":["string","null"],"description":"Public ID (role_ prefix) of the role on the learner's primary program membership, or null when no primary membership exists."},"role_legacy_id":{"type":["string","null"],"description":"Legacy source_id for that role from etl_id_registry, or null when no ETL mapping exists."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The Enrollment object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Enrollment":{"type":"object","description":"A single program_memberships row. One enrollment per program_memberships.id, decoupled from learner_id.","required":["id","learner_id","program_id","status","is_primary","started_on","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the enrollment (enroll_ prefix). Backed by program_memberships.id."},"learner_id":{"type":"string","description":"Public ID of the learner (learner_ prefix). Backed by program_memberships.user_id."},"program_id":{"type":"string","description":"Public ID of the program (prog_ prefix)."},"status":{"$ref":"#/components/schemas/ProgramMembershipStatus"},"is_primary":{"type":"boolean"},"started_on":{"type":"string","format":"date"},"ended_on":{"type":["string","null"],"format":"date"},"expected_graduation":{"type":["string","null"],"format":"date"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ProgramMembershipStatus":{"type":"string","description":"Status of a learner enrollment (program_memberships.status). Canonical source is the affiliation_status DB enum.","enum":["active","inactive","graduated","transferred","terminated","on_leave","pending"]}}}}
```

## The OAuthTokenResponse object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"OAuthTokenResponse":{"type":"object","required":["access_token","token_type","expires_in","scope"],"properties":{"access_token":{"type":"string"},"token_type":{"type":"string"},"expires_in":{"type":"integer"},"scope":{"type":"string"}}}}}}
```

## The ImportJobStatus object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"ImportJobStatus":{"type":"string","enum":["queued","processing","completed","completed_with_errors","failed","cancelled"]}}}}
```

## The ImportJob object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"ImportJob":{"type":"object","description":"Tracks the lifecycle of a bulk resource import request.","required":["id","resource_type","status","mode","processed_count","failed_count","created_at","links"],"properties":{"id":{"type":"string","description":"Public ID of the import job (job_ prefix)."},"resource_type":{"type":"string","enum":["learners","programs","rotations","evaluations"]},"status":{"$ref":"#/components/schemas/ImportJobStatus"},"mode":{"type":"string","enum":["validate_only","import"]},"requested_count":{"type":["integer","null"]},"processed_count":{"type":"integer"},"failed_count":{"type":"integer"},"error_summary":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"links":{"type":"object","required":["status"],"properties":{"status":{"type":"string","description":"URL to poll for job status."}}}}},"ImportJobStatus":{"type":"string","enum":["queued","processing","completed","completed_with_errors","failed","cancelled"]}}}}
```

## The CreateWebhookSubscriptionRequest object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"CreateWebhookSubscriptionRequest":{"type":"object","required":["name","target_url","event_types"],"properties":{"name":{"type":"string"},"target_url":{"type":"string","format":"uri"},"event_types":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"timestamp_tolerance_seconds":{"type":"integer","minimum":60,"maximum":600}}},"WebhookEventType":{"type":"string","description":"Approved event type for webhook subscriptions.","enum":["program.updated","learner.updated","rotation.assignment_changed","evaluation.completed","import_job.completed"]}}}}
```

## The WebhookStatus object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"WebhookStatus":{"type":"string","description":"Operational status of a webhook subscription. Canonical source is the webhook_status DB enum.","enum":["active","disabled","failing","suspended"]}}}}
```

## The WebhookEventType object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"WebhookEventType":{"type":"string","description":"Approved event type for webhook subscriptions.","enum":["program.updated","learner.updated","rotation.assignment_changed","evaluation.completed","import_job.completed"]}}}}
```

## The WebhookSubscription object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"WebhookSubscription":{"type":"object","description":"A webhook subscription owned by an API app. Never includes signing_secret.","required":["id","name","target_url","event_types","status","created_at"],"properties":{"id":{"type":"string","description":"Public ID of the webhook subscription (wh_ prefix)."},"name":{"type":"string"},"target_url":{"type":"string","format":"uri"},"event_types":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"status":{"$ref":"#/components/schemas/WebhookStatus"},"last_success_at":{"type":["string","null"],"format":"date-time"},"last_failure_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"WebhookEventType":{"type":"string","description":"Approved event type for webhook subscriptions.","enum":["program.updated","learner.updated","rotation.assignment_changed","evaluation.completed","import_job.completed"]},"WebhookStatus":{"type":"string","description":"Operational status of a webhook subscription. Canonical source is the webhook_status DB enum.","enum":["active","disabled","failing","suspended"]}}}}
```

## The WebhookSubscriptionCreateResponse object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"WebhookSubscriptionCreateResponse":{"allOf":[{"$ref":"#/components/schemas/WebhookSubscription"},{"type":"object","description":"Returned only in the 201 body for POST /connect/webhooks (first call per Idempotency-Key). signing_secret (whsec_ prefix) is present exactly once and cannot be recovered later. Idempotency-key replay returns HTTP 200 with WebhookSubscription (no signing_secret).\n","required":["signing_secret"],"properties":{"signing_secret":{"type":"string","description":"Webhook signing secret (whsec_ prefix). Present only in the 201 response. Store it immediately — no subsequent request, including idempotency-key replay, can reveal it again.\n"}}}]},"WebhookSubscription":{"type":"object","description":"A webhook subscription owned by an API app. Never includes signing_secret.","required":["id","name","target_url","event_types","status","created_at"],"properties":{"id":{"type":"string","description":"Public ID of the webhook subscription (wh_ prefix)."},"name":{"type":"string"},"target_url":{"type":"string","format":"uri"},"event_types":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"status":{"$ref":"#/components/schemas/WebhookStatus"},"last_success_at":{"type":["string","null"],"format":"date-time"},"last_failure_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"WebhookEventType":{"type":"string","description":"Approved event type for webhook subscriptions.","enum":["program.updated","learner.updated","rotation.assignment_changed","evaluation.completed","import_job.completed"]},"WebhookStatus":{"type":"string","description":"Operational status of a webhook subscription. Canonical source is the webhook_status DB enum.","enum":["active","disabled","failing","suspended"]}}}}
```

## The WebhookDeliveryStatus object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"WebhookDeliveryStatus":{"type":"string","description":"Delivery attempt status. Canonical source is the api_webhook_delivery_status DB enum.","enum":["pending","sent","failed","retrying","disabled"]}}}}
```

## The WebhookDelivery object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"WebhookDelivery":{"type":"object","description":"A single webhook delivery attempt record. Never includes signing_secret.","required":["id","webhook_id","event_type","status","attempt_count","created_at"],"properties":{"id":{"type":"string","description":"Public ID of the delivery record (deliv_ prefix)."},"webhook_id":{"type":"string","description":"Public ID of the parent webhook subscription (wh_ prefix)."},"event_type":{"$ref":"#/components/schemas/WebhookEventType"},"status":{"$ref":"#/components/schemas/WebhookDeliveryStatus"},"attempt_count":{"type":"integer"},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"WebhookEventType":{"type":"string","description":"Approved event type for webhook subscriptions.","enum":["program.updated","learner.updated","rotation.assignment_changed","evaluation.completed","import_job.completed"]},"WebhookDeliveryStatus":{"type":"string","description":"Delivery attempt status. Canonical source is the api_webhook_delivery_status DB enum.","enum":["pending","sent","failed","retrying","disabled"]}}}}
```

## The Program object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Program":{"type":"object","description":"An accredited training program owned by an institution or organization.","required":["id","institution_id","organization_id","name","is_active","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the program (prog_ prefix). Backed by programs.id."},"institution_id":{"type":"string","format":"uuid","description":"UUID of the institution that owns this program."},"organization_id":{"type":"string","format":"uuid","description":"UUID of the organization that owns this program."},"name":{"type":"string"},"short_name":{"type":["string","null"]},"code":{"type":["string","null"]},"program_type":{"type":["string","null"]},"specialty":{"type":["string","null"]},"subspecialty":{"type":["string","null"]},"is_active":{"type":"boolean","description":"Operational on/off flag controlling platform access."},"accreditation_status":{"type":["string","null"],"description":"Code of the program's regulatory accreditation standing (accreditation_statuses.code). Null when unset."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The Role object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Role":{"type":"object","description":"A role designation associated with a program or organization.","required":["id","name","designate","is_system","requires_sso","allow_log_hours","notifications_email","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the role (role_ prefix). Backed by roles.id."},"name":{"type":"string"},"code":{"type":["string","null"]},"description":{"type":["string","null"]},"designate":{"$ref":"#/components/schemas/RoleDesignate","nullable":true},"program_id":{"type":["string","null"],"description":"Public program ID (prog_ prefix). Null for organization-level roles."},"is_system":{"type":"boolean"},"legacy_id":{"type":["string","null"]},"requires_sso":{"type":"boolean"},"allow_log_hours":{"type":"boolean","description":"Whether members holding this role may log work hours."},"notifications_email":{"type":"boolean"},"user_type_legacy_id":{"type":["string","null"],"description":"Legacy SIS user_type id resolved via the ETL id registry. Null for org-scoped clients or roles without a legacy mapping."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"RoleDesignate":{"type":"string","description":"Work designation of a role. Canonical source is the role_designate_type DB enum.","enum":["internal","external"]}}}}
```

## The GroupTag object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"GroupTag":{"type":"object","description":"An institution-scoped group tag.","required":["id","name","is_active","group_count","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the group tag (gtag_ prefix). Backed by group_tags.id."},"name":{"type":"string"},"description":{"type":["string","null"]},"color":{"type":["string","null"]},"is_active":{"type":"boolean"},"group_count":{"type":"integer","description":"Number of non-deleted groups currently assigned to this tag."},"legacy_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The GroupLeaderRole object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"GroupLeaderRole":{"type":"object","description":"A group leader role designation scoped to a program. Legacy analog is /api/users/group_roles/.","required":["id","name","is_active","program_id","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the group leader role (grole_ prefix). Backed by group_leader_roles.id."},"name":{"type":"string"},"code":{"type":["string","null"]},"description":{"type":["string","null"]},"color":{"type":["string","null"]},"display_order":{"type":"integer"},"is_active":{"type":"boolean"},"program_id":{"type":["string","null"],"description":"Public program ID (prog_ prefix). Backed by group_leader_roles.program_id."},"legacy_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The Group object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Group":{"type":"object","description":"A cohort group scoped to an institution within the authenticated API app tenant.","required":["id","name","is_active","member_count","leader_count","tag_legacy_ids","tags_data","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the group (group_ prefix). Backed by groups.id."},"name":{"type":"string"},"description":{"type":["string","null"]},"institution_id":{"type":"string","description":"Public ID of the owning institution."},"program_id":{"type":["string","null"],"description":"Public ID of the associated program (prog_ prefix). Null when not program-scoped."},"program_legacy_id":{"type":["string","null"],"description":"Legacy source_id of the associated program from etl_id_registry. Null when program_id is null or no ETL mapping exists."},"academic_period_id":{"type":["string","null"],"description":"Public ID of the associated academic period (ap_ prefix). Null when not period-scoped."},"academic_period_name":{"type":["string","null"],"description":"Name of the associated academic period. Null when academic_period_id is null."},"academic_period_legacy_id":{"type":["string","null"],"description":"Legacy source_id of the associated academic period from etl_id_registry. Null when academic_period_id is null or no ETL mapping exists."},"is_active":{"type":"boolean"},"member_count":{"type":"integer","description":"Number of non-deleted members currently in this group."},"leader_count":{"type":"integer","description":"Number of group leaders currently assigned to this group."},"tag_legacy_ids":{"type":"array","items":{"type":"string"},"description":"Legacy source_ids of group tags assigned to this group. Empty array when no tags are assigned."},"tags_data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"active":{"type":"boolean"}}},"description":"Denormalized tag objects with legacy id, name, and active flag."},"legacy_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The GroupMember object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"GroupMember":{"type":"object","description":"A group membership record linking a user to a group within the authenticated API app tenant.","required":["id","group_id","user_id","user_first_name","user_last_name","user_email","group_role_legacy_ids","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the group member record (gmember_ prefix). Backed by group_members.id."},"group_id":{"type":"string","description":"Public ID of the containing group (group_ prefix)."},"group_legacy_id":{"type":["string","null"],"description":"Legacy source_id of the group from etl_id_registry. Null when no ETL mapping exists."},"user_id":{"type":"string","description":"Public ID of the member user."},"user_legacy_id":{"type":["string","null"],"description":"Legacy source_id of the user from etl_id_registry. Null when no ETL mapping exists."},"user_first_name":{"type":"string"},"user_last_name":{"type":"string"},"user_email":{"type":"string"},"group_role_legacy_ids":{"type":"array","items":{"type":"string"},"description":"Legacy IDs of group roles assigned to this member. Currently always empty ([])."},"legacy_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The AcademicPeriod object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"AcademicPeriod":{"type":"object","description":"An academic year or semester period scoped to the authenticated API app tenant.","required":["id","name","start_date","end_date","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the academic period (ap_ prefix). Backed by academic_periods.id."},"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"period_type":{"type":["string","null"],"description":"Academic period classification. Enum: academic_period, academic_year, semester, trimester, quarter, pre_clinical, clinical.\n"},"institution_legacy_id":{"type":["string","null"],"description":"Legacy source_id of the owning institution from etl_id_registry (source_entity_type='institution'). Null when no ETL mapping exists.\n"},"program_legacy_id":{"type":["string","null"],"description":"Legacy source_id of the associated program from etl_id_registry (source_entity_type='program'). Null when program_id IS NULL or no ETL mapping exists.\n"},"legacy_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The Block object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Block":{"type":"object","description":"A rotation block (date range) within an academic period, scoped to the authenticated API app tenant.","required":["id","name","start_date","end_date","academic_period_id","legacy_id","clinical_schedule_legacy_id","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the block (block_ prefix). Backed by blocks.id."},"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"academic_period_id":{"type":"string","description":"Public ID of the parent academic period (ap_ prefix). Backed by academic_periods.id."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='block'), minted on create."},"clinical_schedule_legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID of the associated ProgramSchedule (clinical_schedules) from etl_id_registry (source_entity_type='clinical_schedule'). Null when the block has no clinical_schedule_id or when ETL has not registered the mapping."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The Score object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Score":{"type":"object","description":"A gradebook score scoped to the authenticated API app tenant (program→institution). Legacy analog is /api/gradebook/scores/ (Score). PHI/FERPA.","required":["id","legacy_id","learner_id","program_id","score_type_id","score_date","is_final","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the score (score_ prefix). Backed by scores.id."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='score'), minted on create."},"learner_id":{"type":"string","description":"Public ID of the learner (learner_ prefix). Backed by scores.learner_id."},"learner_legacy_id":{"type":["string","null"]},"program_id":{"type":"string","description":"Public ID of the program (prog_ prefix). Backed by scores.program_id."},"program_legacy_id":{"type":["string","null"]},"score_type_id":{"type":"string","description":"Public ID of the score type (stype_ prefix). Backed by scores.score_type_id."},"score_type_legacy_id":{"type":["string","null"]},"status_id":{"type":["string","null"],"description":"Public ID of the score status (sstat_ prefix). Backed by scores.status_id."},"block_schedule_id":{"type":["string","null"],"description":"Public ID of the clinical placement (rotsched_ prefix). Backed by scores.block_schedule_id (classic user_schedule)."},"block_schedule_legacy_id":{"type":["string","null"]},"score_date":{"type":"string","format":"date"},"numeric_score":{"type":["number","null"]},"letter_grade":{"type":["string","null"]},"percentile":{"type":["number","null"]},"is_final":{"type":"boolean"},"notes":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The ExamScore object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"ExamScore":{"type":"object","description":"An exam score scoped to the authenticated API app tenant (program→institution). Legacy analog is /api/users/exam-score/ (ExamScore). PHI/FERPA.","required":["id","legacy_id","learner_id","program_id","exam_type_id","exam_date","score","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the exam score (exsc_ prefix). Backed by exam_scores.id."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='exam_score'), minted on create."},"learner_id":{"type":"string","description":"Public ID of the learner (learner_ prefix)."},"learner_legacy_id":{"type":["string","null"]},"program_id":{"type":"string","description":"Public ID of the program (prog_ prefix)."},"program_legacy_id":{"type":["string","null"]},"exam_type_id":{"type":"string","description":"Public ID of the exam type (etype_ prefix). Backed by exam_scores.exam_type_id."},"exam_status_id":{"type":["string","null"],"description":"Public ID of the exam status (estat_ prefix)."},"exam_date":{"type":"string","format":"date"},"score":{"type":"number"},"percentile":{"type":["number","null"]},"passing_score":{"type":["number","null"]},"is_passing":{"type":["boolean","null"]},"source":{"type":"string","description":"'api' for Connect-created rows."},"source_reference":{"type":["string","null"],"description":"External idempotency reference."},"notes":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The ScoreType object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"ScoreType":{"type":"object","description":"A gradebook score type (vocabulary) usable within a program. Read-only via the Connect API.","required":["id","legacy_id","name","value_mode","is_active","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the score type (stype_ prefix). Backed by score_types.id."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='score_type')."},"name":{"type":"string"},"code":{"type":["string","null"]},"value_mode":{"type":"string","enum":["numeric_status","status_only"]},"program_id":{"type":["string","null"],"description":"Public ID of the owning program (prog_ prefix); null for global/shared types."},"is_active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The ExamType object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"ExamType":{"type":"object","description":"An exam type (vocabulary). Read-only via the Connect API.","required":["id","legacy_id","name","is_active","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the exam type (etype_ prefix). Backed by exam_types.id."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='exam_type')."},"name":{"type":"string"},"is_active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The RotationSite object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"RotationSite":{"type":"object","description":"A link between a rotation and its one live site (gme/ime percentages).","required":["id","legacy_id","rotation_id","site_id","is_primary","gme_percentage","ime_percentage","is_active","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the rotation-site link (rsite_ prefix). Backed by rotation_sites.id."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='rotation_site')."},"rotation_id":{"type":"string","description":"Public ID of the rotation (rotdef_ prefix). Backed by rotation_sites.rotation_id."},"rotation_legacy_id":{"type":["string","null"]},"site_id":{"type":"string","description":"Public ID of the site (site_ prefix). Backed by rotation_sites.site_id."},"site_legacy_id":{"type":["string","null"]},"is_primary":{"type":"boolean","description":"Always true. A rotation has one live site, which is its primary site."},"gme_percentage":{"type":"integer"},"ime_percentage":{"type":"integer"},"is_active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The CurriculumCourse object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"CurriculumCourse":{"type":"object","description":"A curriculum course (classic curriculum-course-rotation), program-scoped.","required":["id","legacy_id","program_id","academic_period_id","name","is_required","is_active","course_type","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the curriculum course (ccr_ prefix). Backed by curriculum_courses.id."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='curriculum_course')."},"program_id":{"type":"string","description":"Public ID of the program (prog_ prefix). Backed by curriculum_courses.program_id."},"program_legacy_id":{"type":["string","null"]},"academic_period_id":{"type":"string","description":"Public ID of the academic period (ap_ prefix). Backed by curriculum_courses.academic_period_id."},"academic_period_legacy_id":{"type":["string","null"]},"name":{"type":"string"},"code":{"type":["string","null"]},"description":{"type":["string","null"]},"credits":{"type":["integer","null"],"description":"Whole-number credits. Fractional credit values stored in Medtrics are rounded to the nearest integer (0.5 rounds up)."},"is_required":{"type":"boolean"},"is_active":{"type":"boolean"},"course_type":{"type":"string","enum":["course","rotation"]},"start_date":{"type":["string","null"],"format":"date"},"end_date":{"type":["string","null"],"format":"date"},"graded_course_rotation_legacy_id":{"type":["string","null"],"description":"Legacy ID of the linked graded course rotation (etl_id_registry source_entity_type='graded_course_rotation'). Null when the course has no GCR link or the GCR has no legacy mapping."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The GradedCourseRotation object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"GradedCourseRotation":{"type":"object","description":"A graded course rotation (gradebook hub), program-scoped.","required":["id","legacy_id","program_id","name","gcr_type","is_required","is_active","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the graded course rotation (gcr_ prefix). Backed by graded_course_rotations.id."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='graded_course_rotation')."},"program_id":{"type":"string","description":"Public ID of the program (prog_ prefix). Backed by graded_course_rotations.program_id."},"program_legacy_id":{"type":["string","null"]},"name":{"type":"string"},"code":{"type":["string","null"]},"description":{"type":["string","null"]},"gcr_type":{"type":"string","enum":["course","rotation"]},"weeks":{"type":["integer","null"]},"credits":{"type":["number","null"]},"is_required":{"type":"boolean"},"is_active":{"type":"boolean"},"parent_id":{"type":["string","null"],"description":"Public ID (gcr_ prefix) of the parent GCR (self-FK lineage), if any."},"parent_legacy_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The CaseLog object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"CaseLog":{"type":"object","description":"A patient encounter log scoped to the authenticated API app tenant. Tenant scope resolved via program→institution. Legacy analog is /api/rotations/procedure_logs/ (ProcedureLog).","required":["id","encounter_date","status","created_at","updated_at","legacy_id","primary_diagnosis_legacy_ids","secondary_diagnosis_legacy_ids","procedure_legacy_ids","preceptor_legacy_ids"],"properties":{"id":{"type":"string","description":"Public ID of the case log (clog_ prefix). Backed by case_logs.id."},"user_id":{"type":["string","null"],"description":"Public ID of the learner (learner_ prefix). Null when no ETL mapping exists."},"template_id":{"type":["string","null"],"description":"Public ID of the case template (ctmpl_ prefix). Null when unresolved."},"block_schedule_id":{"type":["string","null"],"description":"Public ID of the block schedule (rotsched_ prefix). Null until ETL Phase A."},"clinical_rotation_instance_id":{"type":["string","null"],"description":"Public ID of the CRI (rotinst_ prefix). Null until ETL Phase A."},"site_id":{"type":["string","null"],"description":"Public ID of the clinical site (site_ prefix). Null until ETL Phase A."},"encounter_date":{"type":"string","format":"date"},"patient_identifier":{"type":["string","null"],"description":"Opaque encrypted value, never the plaintext patient reference. Not stable: it changes when the case log is saved again and on any encryption key or cipher rotation. Do not store, compare or use it as an identifier."},"patient_age":{"type":["integer","null"]},"patient_gender":{"type":["string","null"]},"clinical_setting":{"type":["string","null"]},"chief_complaint":{"type":["string","null"]},"performance_level":{"type":["string","null"]},"self_performance_level":{"type":["string","null"]},"procedure_duration":{"type":["integer","null"]},"supervisor_id":{"type":["string","null"]},"status":{"type":"string"},"submitted_at":{"type":["string","null"],"format":"date-time"},"notes":{"type":["string","null"]},"clinical_site":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='case_log')."},"user_legacy_id":{"type":["string","null"]},"supervisor_legacy_id":{"type":["string","null"]},"template_legacy_id":{"type":["string","null"]},"user_schedule_legacy_id":{"type":["string","null"]},"rotation_legacy_id":{"type":["string","null"]},"primary_diagnosis_legacy_ids":{"type":"array","items":{"type":"string"}},"secondary_diagnosis_legacy_ids":{"type":"array","items":{"type":"string"}},"procedure_legacy_ids":{"type":"array","items":{"type":"string"}},"preceptor_legacy_ids":{"type":"array","items":{"type":"string"}}}}}}}
```

## The CaseTemplate object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"CaseTemplate":{"type":"object","description":"A hierarchical case/procedure template. case_templates is a global table (no tenant scope). Legacy analog is /api/procedures/procedure_setups/ (ProcedureSetup).","required":["id","name","legacy_id","parent_legacy_id","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the case template (ctmpl_ prefix). Backed by case_templates.id."},"name":{"type":"string"},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='case_template'). Null when no ETL mapping exists."},"parent_legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID of the parent template (procedure_parent) from etl_id_registry. Null when the template has no parent or the parent has no ETL mapping."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The RotationDefinition object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"RotationDefinition":{"type":"object","description":"A clinical rotation catalog entry scoped to the authenticated API app tenant. Represents a rotation definition (name, code) owned by a program. Legacy analog is /api-banner/rotations/ (Create Rotations).","required":["id","program_id","name","is_active","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the rotation definition (rotdef_ prefix). Backed by rotations.id."},"program_id":{"type":"string","description":"Public ID of the owning program (prog_ prefix). Backed by rotations.program_id."},"name":{"type":"string"},"code":{"type":["string","null"],"description":"Short code for the rotation within the program. Unique per program when present."},"description":{"type":["string","null"],"description":"Free-text description of the rotation."},"is_active":{"type":"boolean"},"primary_site_id":{"type":["string","null"],"description":"Public ID of the catalog site (site_ prefix) from the one live rotation_sites.site_id. Null when the rotation has no linked site."},"curriculum_file_url":{"type":["string","null"],"description":"URL of the attached curriculum/syllabus file."},"curriculum_file_name":{"type":["string","null"],"description":"Original filename of the attached curriculum/syllabus file."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='rotation'). Null until ETL registers rotation mappings."},"program_legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) of the owning program from etl_id_registry (source_entity_type='program'). Bridge own-id source for the program FK. Null until ETL registers the program."},"primary_site_legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) of the catalog site from etl_id_registry (source_entity_type='site'). Bridge own-id source for the site FK. Null when no site is linked or ETL not yet registered."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"program_name":{"type":["string","null"],"description":"Name of the owning program. Bridge annotation for legacy /api-banner/rotations/ parity."},"site_name":{"type":"string","description":"Empty string when the rotation has no linked site, or the single catalog site's name. Arrays are length 0 or 1; there is no \"Multiple Sites\" literal."},"graded_course_rotation_legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) of the linked graded course rotation from etl_id_registry (source_entity_type='graded_course_rotation'). Null until the graded_course_rotations ETL phase has run for this institution."},"sites":{"type":"array","maxItems":1,"description":"The one live rotation_sites catalog site (length 0 or 1), in a legacy-shaped object for near-literal bridge pass-through into /api-banner/rotations/ sites[]. Each entry's legacy_id is null until ETL registers that specific site.","items":{"type":"object","properties":{"id":{"type":["integer","null"],"description":"Legacy SIS integer ID of the site from etl_id_registry. Null until ETL registers this site."},"display_name":{"type":"string"},"site_id":{"type":"string","description":"Site code."},"active":{"type":"boolean"},"name":{"type":"string"},"description":{"type":"null","description":"Always null; no Oracle source."},"designate":{"type":"null","description":"Always null; no Oracle source."},"is_default":{"type":"boolean","description":"True for the rotation's one catalog site."},"address":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zip_code":{"type":"string"},"country":{"type":["string","null"]},"contact_name":{"type":"string","description":"Always empty string; no Oracle source."},"phone":{"type":"string"},"student_min":{"type":["integer","null"]},"student_max":{"type":["integer","null"]},"created_date":{"type":"string","format":"date-time"},"updated_date":{"type":"string","format":"date-time"},"employer":{"type":"null","description":"Always null; no Oracle source."},"programs":{"type":"array","items":{},"description":"Always an empty array; no cross-program M2M in the new model."}}}},"rotation_sites":{"type":"array","maxItems":1,"description":"The one live rotation_sites join row (length 0 or 1), in a legacy-shaped object for near-literal bridge pass-through into /api-banner/rotations/ rotation_sites[]. Each entry's legacy_id is null until ETL registers that specific rotation_site row.","items":{"type":"object","properties":{"id":{"type":["integer","null"],"description":"Legacy SIS integer ID of this rotation_site row from etl_id_registry. Null until ETL registers this row."},"display_name":{"type":"string"},"gme":{"type":["number","null"],"description":"GME percentage."},"ime":{"type":["number","null"],"description":"IME percentage."},"irfdpu":{"type":["number","null"]},"ipfdpu":{"type":["number","null"]},"non_provider_site_percentage":{"type":["number","null"]},"created_date":{"type":"string","format":"date-time"},"updated_date":{"type":"string","format":"date-time"},"rotation":{"type":["integer","null"],"description":"Legacy SIS integer ID of the parent rotation. Null until ETL registers the rotation."},"site":{"type":["integer","null"],"description":"Legacy SIS integer ID of the site. Null until ETL registers the site."}}}}}}}}}
```

## The ClinicalSchedule object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"ClinicalSchedule":{"type":"object","description":"A clinical schedule definition scoped to the authenticated API app tenant. Owns M2M access lists for admin users, participant users, view-only users, sites, and role-based view access. Legacy analog is /api-banner/program-schedules/.","required":["id","program_id","academic_period_id","name","schedule_details","show_rotation_tab_default","restrict_rotation_view","show_block_naming","enable_rotation_block_directors","admin_user_ids","participant_user_ids","view_only_user_ids","site_ids","view_role_names","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the clinical schedule (csched_ prefix). Backed by clinical_schedules.id."},"program_id":{"type":"string","description":"Public ID of the owning program (prog_ prefix)."},"academic_period_id":{"type":"string","description":"Public ID of the linked academic period (ap_ prefix)."},"name":{"type":"string"},"description":{"type":["string","null"],"description":"Free-text description of the schedule."},"schedule_details":{"type":"boolean","description":"Corresponds to schedule_config.scheduleDetails. Default false."},"show_rotation_tab_default":{"type":"boolean","description":"Corresponds to schedule_config.showRotationTabDefault. Default false."},"restrict_rotation_view":{"type":"boolean","description":"Corresponds to schedule_config.restrictRotationView. Default false."},"show_block_naming":{"type":"boolean","description":"Corresponds to schedule_config.showBlockNaming. Default true."},"enable_rotation_block_directors":{"type":"boolean","description":"Corresponds to schedule_config.enableRotationBlockDirectors. Default false."},"admin_user_ids":{"type":"array","items":{"type":"string"},"description":"Public IDs (user_ prefix) of schedule administrators from clinical_schedule_admins."},"participant_user_ids":{"type":"array","items":{"type":"string"},"description":"Public IDs (user_ prefix) of users with access_type='participant' from clinical_schedule_users."},"view_only_user_ids":{"type":"array","items":{"type":"string"},"description":"Public IDs (user_ prefix) of users with access_type='view_only' from clinical_schedule_users."},"site_ids":{"type":"array","items":{"type":"string"},"description":"Public IDs (site_ prefix) of associated sites from clinical_schedule_sites."},"view_role_names":{"type":"array","items":{"type":"string"},"description":"Role names with access_type='view' from clinical_schedule_roles (name strings, no IDs)."},"updated_by_id":{"type":["string","null"],"description":"Public ID (user_ prefix) of the last user to update this schedule. Null when not set."},"legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) from etl_id_registry (source_entity_type='clinical_schedule'). Null until ETL registers mappings."},"program_legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) of the owning program. Bridge own-id source for the program FK."},"academic_period_legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) of the academic period. Bridge own-id source for the academic_year FK."},"admin_user_legacy_ids":{"type":"array","items":{"type":"string"},"description":"Legacy SIS integer IDs (as strings) for admin users. Null entries omitted; array empty until ETL registers user mappings."},"participant_user_legacy_ids":{"type":"array","items":{"type":"string"},"description":"Legacy SIS integer IDs (as strings) for participant users."},"view_only_user_legacy_ids":{"type":"array","items":{"type":"string"},"description":"Legacy SIS integer IDs (as strings) for view-only users."},"site_legacy_ids":{"type":"array","items":{"type":"string"},"description":"Legacy SIS integer IDs (as strings) for associated sites."},"updated_by_legacy_id":{"type":["string","null"],"description":"Legacy SIS integer ID (as string) of the last updater. Null when updated_by_id is null or ETL not yet registered."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The Site object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Site":{"type":"object","description":"A clinical or training site scoped to the authenticated API app tenant.","required":["id","name","country","is_primary","is_active","is_internal","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the site (site_ prefix). Backed by sites.id."},"legacy_id":{"type":["string","null"]},"name":{"type":"string"},"short_name":{"type":["string","null"]},"code":{"type":["string","null"]},"site_type":{"type":["string","null"],"description":"Site type classification (e.g. hospital, clinic, ambulatory, va, community, other)."},"address_line_1":{"type":["string","null"]},"address_line_2":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"postal_code":{"type":["string","null"]},"country":{"type":"string"},"phone":{"type":["string","null"]},"fax":{"type":["string","null"]},"email":{"type":["string","null"]},"is_primary":{"type":"boolean"},"is_active":{"type":"boolean"},"is_internal":{"type":"boolean","description":"Mirror of the site relationship category (internal = institution's own site, external = partner site). Maintained from site_relationships.category; ETL-migrated sites derive it from the legacy designate field."},"latitude":{"type":["number","null"]},"longitude":{"type":["number","null"]},"min_trainees":{"type":["integer","null"]},"max_trainees":{"type":["integer","null"]},"program_id":{"type":["string","null"],"description":"Public program ID (prog_ prefix). Null when the site is not tied to a specific program."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```

## The Rotation object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Rotation":{"type":"object","description":"A clinical rotation schedule instance (block_schedules row) assigned to a learner within a visible program. id uses the rotsched_ prefix (backed by block_schedules.id). rotation_instance_id uses the rotinst_ prefix (backed by clinical_rotation_instances.id).\n","required":["id","learner_id","rotation_instance_id","program_id","name","starts_on","ends_on","status","is_confirmed","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the rotation schedule (rotsched_ prefix). Backed by block_schedules.id."},"learner_id":{"type":"string","description":"Public learner ID (learner_ prefix). Backed by block_schedules.user_id."},"rotation_instance_id":{"type":"string","description":"Public rotation instance ID (rotinst_ prefix). Backed by clinical_rotation_instances.id."},"program_id":{"type":"string","description":"Public program ID (prog_ prefix)."},"name":{"type":"string"},"starts_on":{"type":"string","format":"date"},"ends_on":{"type":"string","format":"date"},"status":{"$ref":"#/components/schemas/RotationStatus"},"is_confirmed":{"type":"boolean"},"publication_state":{"type":["string","null"],"enum":["unpublished","published","cancelled",null],"description":"Canonical learner-publication state. Null means the owning program remains on the legacy model."},"mutation_version":{"type":"string","description":"Decimal string revision for optimistic concurrency; encoded as a string to preserve bigint precision."},"enrollment_confirmation":{"oneOf":[{"type":"null"},{"type":"object","required":["confirmed","source","confirmed_at"],"properties":{"confirmed":{"type":"boolean"},"source":{"type":["string","null"],"enum":["manual","sis","legacy",null]},"confirmed_at":{"type":["string","null"],"format":"date-time"}}}],"description":"Null when enrollment confirmation tracking is disabled for the program; otherwise the current confirmation evidence."},"date_progress":{"type":["string","null"],"enum":["upcoming","in_progress","ended",null],"description":"Calculated from institution-local start/end dates and the current institution-local date, independent of publication state."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"RotationStatus":{"type":"string","description":"Normalized rotation assignment status returned by the gateway. draft, published, archived, and scheduled all normalize to 'scheduled'. Derived from block_schedules.status via normalizeRotationStatus().\n","enum":["scheduled","in_progress","completed","cancelled"]}}}}
```

## The Evaluation object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Evaluation":{"type":"object","description":"A form assignment (evaluation) record for a learner within a visible program. id uses the eval_ prefix (backed by form_assignments.id). learner_id is the evaluated person (backed by form_assignments.recipient_id). It is null when the form evaluates a rotation, site, course or program rather than a person, for open forms whose subject is chosen when the evaluator starts the form, and when the evaluated person's profile has been removed. evaluator_id is the person filling out the form (backed by form_assignments.responder_id). legacy_id, learner_legacy_id, evaluator_legacy_id, form_legacy_id, and rotation_legacy_id are populated from etl_id_registry when a mapping exists; they are otherwise null.\n","required":["id","learner_id","program_id","status","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the evaluation (eval_ prefix). Backed by form_assignments.id."},"legacy_id":{"type":["string","null"],"description":"Legacy numeric form_assignment id from etl_id_registry, if migrated."},"learner_id":{"type":["string","null"],"description":"Public ID of the evaluated person (learner_ prefix). Backed by form_assignments.recipient_id. Null for evaluations of a rotation, site, course or program, for open forms that have not been started, and when the evaluated person's profile has been removed."},"learner_legacy_id":{"type":["string","null"]},"learner_first_name":{"type":["string","null"]},"learner_last_name":{"type":["string","null"]},"learner_email":{"type":["string","null"]},"evaluator_id":{"type":["string","null"],"description":"Public ID of the person filling out the form (learner_ prefix). Backed by form_assignments.responder_id."},"evaluator_legacy_id":{"type":["string","null"]},"evaluator_first_name":{"type":["string","null"]},"evaluator_last_name":{"type":["string","null"]},"evaluator_email":{"type":["string","null"]},"program_id":{"type":"string","description":"Public program ID (prog_ prefix)."},"program_name":{"type":["string","null"]},"form_legacy_id":{"type":["string","null"],"description":"Legacy numeric form id from etl_id_registry (source_entity_type 'form'), if the underlying form was migrated; null for native-created forms."},"form_type":{"type":["string","null"],"description":"form_types.name for the underlying form (e.g. Rotation, Course, Session, Event, Program, General, Shift)."},"is_anonymous":{"type":["boolean","null"]},"rotation_instance_id":{"type":["string","null"],"description":"Public rotation instance ID (rotinst_ prefix), if linked to a rotation."},"rotation_legacy_id":{"type":["string","null"]},"site_count":{"type":["integer","null"],"description":"Count of distinct sites on the rotation definition backing rotation_instance_id. Null when rotation_instance_id is null (no rotation linked); 0 when the rotation has no sites."},"site_name":{"type":["string","null"],"description":"Name of the single site when site_count is 1; null when site_count is null or not exactly 1. No \"Multiple Sites\" literal here — that legacy microcopy is synthesized by the bridge only."},"rotation_schedule_id":{"type":["string","null"],"description":"Public rotation schedule ID (rotsched_ prefix), if linked to a block schedule."},"title":{"type":"string","description":"Form template name for this evaluation."},"status":{"$ref":"#/components/schemas/FormAssignmentStatus"},"completed":{"type":"boolean"},"canceled":{"type":"boolean","description":"status = cancelled and NOT flagged unable_to_assess."},"unable_to_assess":{"type":"boolean","description":"status = cancelled with an \"Unable to assess:\" notes prefix or metadata.unable_to_assess = true."},"submitted_dates":{"type":["array","null"],"items":{"type":"string","format":"date-time"},"description":"created_at of each non-deleted form_responses row for this assignment."},"published_on":{"type":["string","null"],"format":"date-time"},"due_on":{"type":["string","null"],"format":"date"},"assigned_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"score_summary":{"type":["object","null"],"additionalProperties":true,"description":"Aggregate score data if available; null for most evaluation types."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"FormAssignmentStatus":{"type":"string","description":"Canonical status of a form assignment. Does not include the virtual 'missing' filter value.","enum":["draft","pending","in_progress","completed","overdue","cancelled","expired","declined"]}}}}
```

## The Advancement object

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"components":{"schemas":{"Advancement":{"type":"object","description":"A role advancement schedule record. id uses the advsch_ prefix (backed by role_advancement_schedules.id). selected_user_ids contains learner_ public IDs resolved from UUID[]. legacy_id is populated only for well-defined 1:1 schedules (ETL-migrated or natively created single-user schedules); it is null for grouped multi-user pending schedules, where one Oracle row maps to many legacy ids. Consumed by the legacy SIS bridge for /api/roles/advancement_residents/.\n","required":["id","program_id","source_role_id","target_role_id","selection_mode","execution_status","effective_date","created_at","updated_at"],"properties":{"id":{"type":"string","description":"Public ID of the advancement schedule (advsch_ prefix). Backed by role_advancement_schedules.id."},"program_id":{"type":"string","description":"Public program ID (prog_ prefix)."},"source_role_id":{"type":"string","description":"Public ID of the source role (role_ prefix). Members of this role are advanced."},"target_role_id":{"type":"string","description":"Public ID of the target role (role_ prefix). Members are advanced into this role."},"target_role_name":{"type":["string","null"],"description":"Name of the target role (denormalized to avoid N+1 bridge lookups)."},"selection_mode":{"type":"string","enum":["by_individuals","by_role"],"description":"How users are selected. by_individuals uses selected_user_ids; by_role resolves current source_role members."},"selected_user_ids":{"type":"array","items":{"type":"string"},"description":"Learner public IDs (learner_ prefix) scheduled for advancement. Empty when selection_mode is by_role."},"effective_date":{"type":"string","format":"date","description":"Date the advancement takes effect (ISO 8601, YYYY-MM-DD)."},"execution_status":{"type":"string","enum":["pending","executing","completed","failed"],"description":"Current lifecycle status of the schedule."},"users_advanced_count":{"type":["integer","null"],"description":"Number of users advanced. Populated after execution; null for pending/executing schedules."},"legacy_id":{"type":["string","null"],"description":"Legacy integer id, non-null only for well-defined 1:1 schedules (ETL-migrated or natively created single-user schedules). Null for grouped multi-user pending schedules, since one Oracle row maps to many legacy ids there."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.mymedtrics.com/api-reference/connect-api/models.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
