> 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/sites.md).

# Sites

Clinical sites scoped to the authenticated API app tenant, optionally tied to a program.

## List visible sites.

> Returns cursor-paged clinical and training sites scoped to the authenticated API app tenant.

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"tags":[{"name":"Sites","description":"Clinical sites scoped to the authenticated API app tenant, optionally tied to a program."}],"servers":[{"url":"https://sandbox.mymedtrics.com","description":"Client sandbox — shared demo tenant, X-Medtrics-Sandbox-Key or a sandbox API app"},{"url":"https://{client}.mymedtrics.com","description":"Your Medtrics instance","variables":{"client":{"default":"<client-name>","description":"The tenant subdomain Medtrics assigns to your institution"}}}],"security":[{"BearerToken":[]},{"SandboxApiKey":[]}],"components":{"securitySchemes":{"BearerToken":{"type":"http","scheme":"bearer"},"SandboxApiKey":{"type":"apiKey","in":"header","name":"X-Medtrics-Sandbox-Key"}},"parameters":{"ApiDateHeader":{"name":"Medtrics-API-Date","in":"header","required":true,"description":"API contract date. Use 2026-10-27 for this version. Contract dates select request behavior: rotation creates require explicit placement references from 2026-10-27; earlier accepted dates retain compatibility handling. Unknown dates return HTTP 400 with error.code unsupported_api_date.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},"Limit":{"name":"limit","in":"query","required":false,"description":"Maximum number of records to return per page. The server may return fewer rows than requested. Values above the maximum (100) are silently clamped to 100. Values below the minimum (1) are silently clamped to 1. The effective value after clamping is always returned in pagination.limit so callers can detect that they hit the gateway ceiling. Per-client max_page_size overrides are documented as a tenant-configurable lower cap that never raises the public ceiling.\n","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},"Cursor":{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}},"ProgramIdQuery":{"name":"program_id","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by program public ID (prog_ prefix). Returns only records belonging to this program."},"SiteName":{"name":"name","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by site name (case-insensitive exact match)."},"SiteIsActive":{"name":"is_active","in":"query","required":false,"schema":{"type":"boolean"},"description":"Filter by active status. Omit to return all sites regardless of status."},"LegacyIdQuery":{"name":"legacy_id","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by legacy source ID from etl_id_registry. Useful for bridge lookups."}},"responses":{"SiteListResponse":{"description":"Cursor-paged site records.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Site"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"BadRequest":{"description":"Invalid request parameters.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"Unauthorized":{"description":"Missing or invalid credentials.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"Forbidden":{"description":"Credential lacks tenant visibility or required scope.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"RateLimited":{"description":"Request or API app rate limit exceeded.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"InternalError":{"description":"Unexpected server error.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"headers":{"MedtricsRequestId":{"description":"Correlates all gateway logs for the request.","schema":{"type":"string"}},"MedtricsApiDate":{"description":"API contract date applied to the request.","schema":{"type":"string"}},"RateLimitLimit":{"description":"Request limit for the current window.","schema":{"type":"string"}},"RateLimitRemaining":{"description":"Remaining requests in the current window.","schema":{"type":"string"}},"RateLimitReset":{"description":"Unix seconds when the current rate-limit window resets.","schema":{"type":"string"}}},"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"}}},"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."}}},"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."}}}]}}},"paths":{"/connect/sites":{"get":{"operationId":"listSites","tags":["Sites"],"summary":"List visible sites.","description":"Returns cursor-paged clinical and training sites scoped to the authenticated API app tenant.","parameters":[{"$ref":"#/components/parameters/ApiDateHeader"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/ProgramIdQuery"},{"$ref":"#/components/parameters/SiteName"},{"$ref":"#/components/parameters/SiteIsActive"},{"$ref":"#/components/parameters/LegacyIdQuery"}],"responses":{"200":{"$ref":"#/components/responses/SiteListResponse"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}}}}
```

## Get a site.

> Returns one clinical or training site when it belongs to the authenticated API app tenant.

```json
{"openapi":"3.1.0","info":{"title":"Medtrics Connect API","version":"2026-10-27"},"tags":[{"name":"Sites","description":"Clinical sites scoped to the authenticated API app tenant, optionally tied to a program."}],"servers":[{"url":"https://sandbox.mymedtrics.com","description":"Client sandbox — shared demo tenant, X-Medtrics-Sandbox-Key or a sandbox API app"},{"url":"https://{client}.mymedtrics.com","description":"Your Medtrics instance","variables":{"client":{"default":"<client-name>","description":"The tenant subdomain Medtrics assigns to your institution"}}}],"security":[{"BearerToken":[]},{"SandboxApiKey":[]}],"components":{"securitySchemes":{"BearerToken":{"type":"http","scheme":"bearer"},"SandboxApiKey":{"type":"apiKey","in":"header","name":"X-Medtrics-Sandbox-Key"}},"parameters":{"ApiDateHeader":{"name":"Medtrics-API-Date","in":"header","required":true,"description":"API contract date. Use 2026-10-27 for this version. Contract dates select request behavior: rotation creates require explicit placement references from 2026-10-27; earlier accepted dates retain compatibility handling. Unknown dates return HTTP 400 with error.code unsupported_api_date.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},"SiteId":{"name":"siteId","in":"path","required":true,"schema":{"type":"string"},"description":"Public ID of the site (site_ prefix). Backed by sites.id."}},"responses":{"SiteItemResponse":{"description":"Single site record.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Site"}}}}}},"Unauthorized":{"description":"Missing or invalid credentials.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"Forbidden":{"description":"Credential lacks tenant visibility or required scope.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"NotFound":{"description":"Resource not found or outside tenant scope.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"RateLimited":{"description":"Request or API app rate limit exceeded.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"InternalError":{"description":"Unexpected server error.","headers":{"Medtrics-Request-ID":{"$ref":"#/components/headers/MedtricsRequestId"},"Medtrics-API-Date":{"$ref":"#/components/headers/MedtricsApiDate"},"Medtrics-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"Medtrics-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"Medtrics-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"headers":{"MedtricsRequestId":{"description":"Correlates all gateway logs for the request.","schema":{"type":"string"}},"MedtricsApiDate":{"description":"API contract date applied to the request.","schema":{"type":"string"}},"RateLimitLimit":{"description":"Request limit for the current window.","schema":{"type":"string"}},"RateLimitRemaining":{"description":"Remaining requests in the current window.","schema":{"type":"string"}},"RateLimitReset":{"description":"Unix seconds when the current rate-limit window resets.","schema":{"type":"string"}}},"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"}}},"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."}}}]}}},"paths":{"/connect/sites/{siteId}":{"get":{"operationId":"getSite","tags":["Sites"],"summary":"Get a site.","description":"Returns one clinical or training site when it belongs to the authenticated API app tenant.","parameters":[{"$ref":"#/components/parameters/ApiDateHeader"},{"$ref":"#/components/parameters/SiteId"}],"responses":{"200":{"$ref":"#/components/responses/SiteItemResponse"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}}}}
```


---

# 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/sites.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.
