Index
YouSleep Pydantic models and data validation.
See also the yousleep_common.types module for common data types (enums, annotated primitives etc.)
API_KEY_PREFIX = 'ysk_'
module-attribute
¶
Every API key starts with this; the server recognises a key by it.
CalendarGranularity = Literal['day', 'week', 'month']
module-attribute
¶
The span of one calendar bin.
LongitudinalBasis = Literal['session-index', 'calendar']
module-attribute
¶
What a bin is: a position within the subject's series, or a calendar span.
LongitudinalRegime = Literal['derived', 'declared']
module-attribute
¶
Where session positions came from; set on session-index sections only.
MAX_BATCH_ANALYSIS_IDS = 100
module-attribute
¶
Analysis ids in one batch cancel, status poll, events or blocks read.
MAX_BATCH_ANALYSIS_ITEMS = 500
module-attribute
¶
Analyses (targets × pipeline steps) in one batch submission.
MAX_BATCH_CHANNEL_PATCHES = 200
module-attribute
¶
Patches in one bulk channel patch.
MAX_BATCH_RECORDING_IDS = 100
module-attribute
¶
Recording ids in one batch recording-details read.
MAX_BATCH_STUDY_IDS = 100
module-attribute
¶
Study ids in one batch recordings-by-studies or studies-by-ids read.
MAX_BATCH_STUDY_ITEMS = 500
module-attribute
¶
Studies created, metadata patches or lights assignments in one request.
NOT_SET_STRATUM_LABEL = 'Not set'
module-attribute
¶
Stratum label for studies missing the stratified metadata factor.
Contract, not a display nicety: a stratified report accounts for every
study, so studies without the factor form their own stratum under this
exact label — the parallel of UNTAGGED_GROUP_LABEL for tag grouping.
Ordered last.
REDACTED_DETAIL_KEYS = frozenset({'email_hash'})
module-attribute
¶
Keys an audit event's detail never carries on the wire.
The one-way email hash a deleted account leaves behind exists so a support lookup by address can find the row; the lookup is a server-side filter, and the hash itself is never handed out.
STUDY_IMPORT_COLUMNS = [StudyImportColumn(key='study', kind='study_key', aliases=['study', 'study_name', 'name', 'study_id', 'id'], description='The study each row addresses, by exact name or id. Required.'), StudyImportColumn(key='subject_key', kind='text', aliases=['subject_key', 'subject', 'subject_id', 'subject_code', 'participant', 'participant_id'], description="The person the study belongs to. Rows sharing a key within the project form one subject's series. Compared case- and whitespace-insensitively; blank leaves the study standing alone."), StudyImportColumn(key='session_index', kind='integer', aliases=['session_index', 'session', 'night', 'night_index', 'visit', 'visit_index'], description="Declared position of the study in its subject's series, 1 = first. Blank orders by recording start instead. A subject whose studies are only partly numbered is left out of session-indexed figures and named in a warning."), StudyImportColumn(key='age', kind='integer', aliases=['age', 'age_years', 'subject_age'], unit='years', description='Subject age in years (0–125). NULL clears.'), StudyImportColumn(key='sex', kind='sex', aliases=['sex', 'gender'], description="Subject sex (the platform's Sex vocabulary). NULL clears."), StudyImportColumn(key='bmi', kind='decimal', aliases=['bmi', 'body_mass_index'], unit='kg/m²', description='Body mass index (5–200). NULL clears.'), StudyImportColumn(key='lights_off_clock', kind='clock', aliases=['lights_off', 'lights_off_clock', 'lights off', 'loff'], description="Lights-off as wall clock HH:MM[:SS] in the recording's own frame, resolved with overnight wrap. Only valid while the study's recording span is ≤ 24 h — longer spans must use the datetime or ms spelling."), StudyImportColumn(key='lights_on_clock', kind='clock', aliases=['lights_on', 'lights_on_clock', 'lights on', 'lon'], description='Lights-on as wall clock HH:MM[:SS], resolved with overnight wrap after lights-off.'), StudyImportColumn(key='lights_off_datetime', kind='datetime', aliases=['lights_off_datetime', 'lights_off_at'], description="Lights-off as an absolute datetime in the recording's wall-clock frame (alternate spelling)."), StudyImportColumn(key='lights_on_datetime', kind='datetime', aliases=['lights_on_datetime', 'lights_on_at'], description='Lights-on as an absolute datetime (alternate spelling).'), StudyImportColumn(key='lights_off_ms', kind='elapsed_ms', aliases=['lights_off_ms', 'lights_off_elapsed_ms'], unit='ms', description='Lights-off as milliseconds from recording start (alternate spelling).'), StudyImportColumn(key='lights_on_ms', kind='elapsed_ms', aliases=['lights_on_ms', 'lights_on_elapsed_ms'], unit='ms', description='Lights-on as milliseconds from recording start (alternate spelling).')]
module-attribute
¶
The one column table: frontend auto-mapping, SDK docs, and the template download all derive from this — never duplicate it.
StudyOrder = Literal['created', 'subject']
module-attribute
¶
How a study listing is ordered.
created is the order the studies were created in — the default, and
what pagination has always walked. subject puts a person's studies
together and in series order: subjects in key order, within a subject the
declared visit numbers first and unnumbered nights after them, and the
studies that belong to no subject last. A paginated listing ordered this
way can be read (and drawn) grouped by person.
AccessToken
pydantic-model
¶
Bases: BaseModel
Access token details.
Fields:
-
access_token(str) -
access_token_expires_utc_seconds(int) -
user_id(UUID7)
AdminAnalysisConfigOut
pydantic-model
¶
Bases: BaseModel
An analysis in the registry, and who it is offered to.
Fields:
-
analysis_config_id(str) -
name(str) -
origin(Literal['yousleep', 'third-party']) -
registered_at(datetime) -
visibility(AnalysisVisibility) -
owner_org_id(UUID | None) -
owner_org_name(str | None) -
promoted_at(datetime | None) -
promotion_refused(str | None)
origin
pydantic-field
¶
Who developed it, as its provenance declares.
owner_org_id = None
pydantic-field
¶
The organization whose members see and run it while it is private.
promoted_at = None
pydantic-field
¶
When it was published; null if it never was.
promotion_refused = None
pydantic-field
¶
Why a promotion would be refused now; null when it would be accepted.
AdminAnalysisConfigUpdate
pydantic-model
¶
Bases: BaseModel
Change who an analysis is offered to. Omitted fields stay as they are.
visibility moves an analysis one way: private to public is a
promotion, and either to withdrawn is a withdrawal. Nothing returns
to private; a changed analysis is registered as a new version.
Fields:
-
owner_org_id(UUID | None) -
visibility(AnalysisVisibility | None)
AdminAnalysisFilter
pydantic-model
¶
Bases: _FilterBase
Predicate over every analysis on the platform; at least one field must be set.
Mirrors the admin analysis list endpoint's filter query parameters. The server applies it to live, not-yet-settled analyses only when the operation is a cancellation, so a filter can never address a finished run.
Fields:
-
user_id(UUID | None) -
status_any(list[AnalysisStatus] | None)
Validators:
-
_at_least_one_predicate
AdminAnalysisListResponse
pydantic-model
¶
Bases: PaginatedResponse
A page of analyses across accounts, newest first.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
analyses(list[AdminAnalysisOut])
AdminAnalysisOut
pydantic-model
¶
Bases: AnalysisIdMixin, AnalysisStatusMixin, AnalysisTimingMixin
An analysis as an administrator operates on it.
Its status, timing, owner, cost and outcome, and the ids of what it ran on. Never the names people gave their projects, studies or files, which operating the platform does not need.
Config:
from_attributes:True
Fields:
-
enqueue_time(datetime) -
start_time(datetime | None) -
end_time(datetime | None) -
status(AnalysisStatus) -
status_message(str | None) -
failure_code(ErrorCode | None) -
id(UUID) -
analysis_config_id(str) -
analysis_config_name(AnalysisConfigNameStr) -
project_id(UUID | None) -
recording_id(UUID | None) -
user_id(UUID | None) -
user_email(str | None) -
org_id(UUID | None) -
cost(float) -
analysis_hours(float) -
exit_code(int | None) -
deleted_at(datetime | None)
analysis_config_id
pydantic-field
¶
ID of the analysis configuration used for the analysis.
analysis_config_name
pydantic-field
¶
Name of the analysis configuration used for the analysis.
analysis_hours
pydantic-field
¶
Signal hours the analysis was priced on.
cost
pydantic-field
¶
Credits charged for the analysis, or held while it is live.
deleted_at = None
pydantic-field
¶
When the analysis was deleted, for listings that include deleted rows. Null for live analyses.
exit_code = None
pydantic-field
¶
Exit code of the analysis process, once it has run.
org_id = None
pydantic-field
¶
The owning organization. Null when it was erased.
project_id = None
pydantic-field
¶
ID of the project the analysis belongs to. None if deleted.
recording_id = None
pydantic-field
¶
ID of the recording the analysis ran on. None if deleted.
user_email = None
pydantic-field
¶
The owning account's email. Null when that account was erased.
user_id = None
pydantic-field
¶
The owning account. Null when that account was erased.
AdminAnalysisSelector
pydantic-model
¶
Bases: _SelectorBase
Address a set of analyses across accounts: one of ids | filter | all.
all addresses every live analysis on the platform and, like every
live-set mode, must state the count the caller resolved.
Fields:
-
ids(list[UUID] | None) -
all(bool) -
filter(AdminAnalysisFilter | None)
Validators:
-
_exactly_one_mode
filter = None
pydantic-field
¶
Server-resolved predicate (live set).
AdminCancelAnalysesRequest
pydantic-model
¶
Bases: BaseModel
Cancel analyses across accounts.
Addresses its subjects with a selector. Only live, not-yet-settled analyses are cancelled; a finished one addressed by id is reported as an error, and a filter never resolves to one.
Fields:
-
selector(AdminAnalysisSelector) -
expected_count(int | None)
Validators:
-
_guard
expected_count = None
pydantic-field
¶
Required for live-set selectors (filter/all): the resolved count the caller saw on the admin analysis list. The server re-resolves and rejects on a mismatch.
AdminCancelAnalysesResponse
pydantic-model
¶
Bases: BaseModel
Outcome of one page of an admin cancellation.
Fields:
-
results(list[BatchCancelResult]) -
summary(AdminCancelSummary)
AdminCancelSummary
pydantic-model
¶
Bases: BatchCancelSummary
Counts for one page of an admin cancellation.
Fields:
-
total(int) -
cancelled(int) -
errors(int) -
remaining(int)
remaining
pydantic-field
¶
Live analyses the selector still addresses after this page. Call again with the same selector until this is zero; each call handles at most the server's per-request cap.
AdminCapabilityRequestDecline
pydantic-model
¶
Bases: BaseModel
Decline a request for a capability, with the reason the organisation is shown.
Fields:
-
reason(str)
AdminCapabilityRequestOut
pydantic-model
¶
Bases: CapabilityRequestOut
A request for a capability as administrators see it: with its organisation.
Fields:
-
id(UUID) -
org_id(UUID) -
capability(SiteCapability) -
status(CapabilityRequestStatus) -
requested_by(UUID | None) -
requested_by_name(str | None) -
note(str) -
created_at(datetime) -
decision(CapabilityRequestDecision | None) -
org_name(str | None) -
decided_by(UUID | None)
AdminCapabilityRequestPage
pydantic-model
¶
Bases: BaseModel
One page of requests for capabilities across organisations, pending first, oldest first.
Config:
frozen:True
Fields:
-
requests(list[AdminCapabilityRequestOut]) -
total(int)
AdminCreditRequestApprove
pydantic-model
¶
Bases: BaseModel
Approve a grant or extension request, as asked or with changes.
Fields:
-
amount(int | None) -
term_months(int | None) -
note(str | None)
AdminCreditRequestDecline
pydantic-model
¶
Bases: BaseModel
Decline a grant or extension request, with a reason the requester is sent.
Fields:
-
reason(CreditRequestDeclineReason) -
note(str | None) -
notify(bool)
AdminCreditRequestOut
pydantic-model
¶
Bases: CreditRequestOut
A request as administrators see it: with its organization and the decision's note.
Fields:
-
id(UUID) -
org_id(UUID) -
kind(CreditRequestKind) -
status(CreditRequestStatus) -
grant_id(UUID | None) -
requested_by(UUID | None) -
requested_by_name(str | None) -
plan(CreditPlan | None) -
computed_credits(NonNegativeInt | None) -
buffer_pct(int | None) -
requested_credits(NonNegativeInt | None) -
term_months(int) -
text(str) -
created_at(datetime) -
decision(CreditRequestDecision | None) -
org_name(str | None) -
decided_by(UUID | None) -
decision_note(str | None)
AdminCreditRequestPage
pydantic-model
¶
Bases: BaseModel
One page of requests across organizations, pending first, oldest first.
Config:
frozen:True
Fields:
-
requests(list[AdminCreditRequestOut]) -
total(int)
AdminDemoDatasetCreate
pydantic-model
¶
Bases: BaseModel
Request body for POST /admin/demo-datasets.
Fields:
-
name(str) -
full_name(str) -
description(str) -
version(str) -
source_name(str) -
source_url(HttpUrl) -
licence_name(str) -
licence_url(HttpUrl) -
studies(list[DemoStudyCreate])
AdminDemoDatasetOut
pydantic-model
¶
Bases: BaseModel
Admin-facing response for a demo dataset.
Fields:
-
id(UUID) -
name(str) -
full_name(str) -
description(str) -
version(str) -
source_name(str) -
source_url(HttpUrl) -
licence_name(str) -
licence_url(HttpUrl) -
study_count(int) -
recording_count(int) -
created_at(datetime) -
updated_at(datetime)
AdminEntitlementChange
pydantic-model
¶
Bases: BaseModel
Turn one of an organisation's capabilities on or off.
On needs the owner's acceptance of the latest published site agreement, unless the platform operates the organisation itself. Off is always allowed; it stops new work at the organisation's site, and nothing already there is touched.
Fields:
-
on(bool) -
reason(str)
reason
pydantic-field
¶
Why, for the organisation's audit trail and the administrators.
AdminGrantCreate
pydantic-model
¶
Bases: BaseModel
Research credits an administrator grants an organization directly.
Fields:
-
amount(int) -
term_months(int | None) -
reason(str)
AdminHealthDetail
pydantic-model
¶
Bases: BaseModel
The API's health, dependency by dependency.
The public health endpoint reports only the overall status. This breakdown is for operators. It is always returned with 200; the status fields carry the diagnosis.
Fields:
-
status(Literal['ok', 'degraded', 'unhealthy']) -
postgres(Literal['ok', 'error']) -
redis(Literal['ok', 'error']) -
runners(Literal['ok', 'none seen'])
postgres
pydantic-field
¶
Whether the database answers a trivial query in time.
redis
pydantic-field
¶
Whether Redis answers a ping in time.
runners
pydantic-field
¶
Whether an approved runner has asked for work in the last few minutes.
status
pydantic-field
¶
ok when every dependency answers and a runner has been seen recently; degraded when no runner has, so analyses wait but everything else works; unhealthy when the database or Redis does not answer.
AdminOrganizationDetailOut
pydantic-model
¶
Bases: AdminOrganizationOut
One organization with its members, as the operators see it.
Fields:
-
id(UUID) -
name(str) -
created_at(datetime) -
deleted_at(datetime | None) -
owner_user_id(UUID | None) -
owner_email(str | None) -
owner_name(str | None) -
member_count(int) -
pending_invitation_count(int) -
seat_limit(int | None) -
effective_seat_limit(int | None) -
study_limit(int | None) -
effective_study_limit(int | None) -
project_limit(int | None) -
effective_project_limit(int | None) -
project_count(int) -
storage_bytes(int) -
storage_ceiling_gb(int | None) -
effective_storage_ceiling_gb(float) -
credits(OrgCredits) -
storage_insolvent_since(datetime | None) -
platform_operated(bool) -
analyses_at_site(bool) -
recordings_at_site(bool) -
site_compute_factor(float | None) -
effective_site_compute_factor(float) -
members(list[MemberOut]) -
capabilities(OrganizationCapabilities | None)
AdminOrganizationListResponse
pydantic-model
¶
Bases: PaginatedResponse
Paginated organization list response.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
organizations(list[AdminOrganizationOut])
AdminOrganizationOut
pydantic-model
¶
Bases: BaseModel
An organization as the operators list it.
Identity, owner, seats, projects, storage and credits in one row, with
the overrides an administrator may set and the values actually in
force. Retired organizations (deleted_at set) are listed only on
request.
Config:
from_attributes:True
Fields:
-
id(UUID) -
name(str) -
created_at(datetime) -
deleted_at(datetime | None) -
owner_user_id(UUID | None) -
owner_email(str | None) -
owner_name(str | None) -
member_count(int) -
pending_invitation_count(int) -
seat_limit(int | None) -
effective_seat_limit(int | None) -
study_limit(int | None) -
effective_study_limit(int | None) -
project_limit(int | None) -
effective_project_limit(int | None) -
project_count(int) -
storage_bytes(int) -
storage_ceiling_gb(int | None) -
effective_storage_ceiling_gb(float) -
credits(OrgCredits) -
storage_insolvent_since(datetime | None) -
platform_operated(bool) -
analyses_at_site(bool) -
recordings_at_site(bool) -
site_compute_factor(float | None) -
effective_site_compute_factor(float)
analyses_at_site = False
pydantic-field
¶
Whether the organisation's analyses run at its site.
credits
pydantic-field
¶
The organization's credit balance.
deleted_at = None
pydantic-field
¶
When the organization was retired, if it was.
effective_project_limit = None
pydantic-field
¶
The projects the organization may hold — the override, else the configured default; null when uncapped.
effective_seat_limit = None
pydantic-field
¶
The seat limit in force — the override, else the configured default; null when uncapped.
effective_site_compute_factor = 0
pydantic-field
¶
The factor in force on the platform price for analyses run at the organisation's site: the override, else the platform's.
effective_storage_ceiling_gb = 0
pydantic-field
¶
The storage ceiling in force (GB).
effective_study_limit = None
pydantic-field
¶
The studies one project may hold — the override, else the configured default, never above the platform's ceiling.
owner_user_id = None
pydantic-field
¶
The owner's user id (every live organization has one).
pending_invitation_count = 0
pydantic-field
¶
Invitations sent and not yet accepted, revoked or expired.
platform_operated = False
pydantic-field
¶
Whether the platform operates the organisation itself.
project_limit = None
pydantic-field
¶
The project-limit override, if set.
recordings_at_site = False
pydantic-field
¶
Whether the organisation's new projects keep their recordings in its bucket.
seat_limit = None
pydantic-field
¶
The seat-limit override, if set.
site_compute_factor = None
pydantic-field
¶
The site-compute factor override, if set.
storage_bytes = 0
pydantic-field
¶
Bytes held against the organization's storage ceiling.
storage_ceiling_gb = None
pydantic-field
¶
The storage-ceiling override (GB), if set.
storage_insolvent_since = None
pydantic-field
¶
When the balance stopped covering the storage debit; null = solvent.
study_limit = None
pydantic-field
¶
The per-project study-limit override, if set.
AdminOrganizationUpdate
pydantic-model
¶
Bases: BaseModel
An administrator's change to an organization's limits and settings.
Each limit, and the site-compute factor, is an override of the platform's
configured default: a value sets it, an explicit null clears it (back
to the default), and an omitted field is left unchanged. Servers distinguish the last two through
model_fields_set. An unknown field is refused, not ignored.
Config:
extra:forbid
Fields:
-
storage_ceiling_gb(int | None) -
seat_limit(int | None) -
project_limit(int | None) -
study_limit(int | None) -
platform_operated(bool | None) -
analyses_at_site(bool | None) -
recordings_at_site(bool | None) -
site_compute_factor(float | None)
Validators:
-
_switches_are_set_or_left
analyses_at_site = None
pydantic-field
¶
Whether the organisation's analyses run at its site. Turning it on needs site compute and an approved runner of the organisation's site pool taking work. It takes effect at the next submission; an analysis already queued stays where it is. It cannot be cleared to null.
platform_operated = None
pydantic-field
¶
Whether the platform operates the organisation itself, as for a demonstration site. Such an organisation's capabilities are turned on without an acceptance of the site agreement. It cannot be cleared to null.
project_limit = None
pydantic-field
¶
Projects the organization may hold.
recordings_at_site = None
pydantic-field
¶
Whether the organisation's new projects keep their recordings in its registered bucket. Turning it on needs site storage, analyses at the site, and a bucket whose browser check passed with its current key. Existing projects keep where they are stored. It cannot be cleared to null.
seat_limit = None
pydantic-field
¶
Members plus pending invitations the organization may hold.
site_compute_factor = None
pydantic-field
¶
The organisation's own factor on the platform price for analyses run at its site, as its agreement sets it. Null clears it back to the platform's factor.
storage_ceiling_gb = None
pydantic-field
¶
The storage the organization may use (GB).
study_limit = None
pydantic-field
¶
Studies one of the organization's projects may hold, at most the platform's ceiling.
AdminOwnershipTransfer
pydantic-model
¶
Bases: BaseModel
Hand an organization to one of its members, by an administrator.
The recovery path for an organization whose owner is unreachable: the current owner becomes an admin and both are told by email. Audited with the administrator as the actor.
Fields:
-
new_owner_user_id(UUID)
new_owner_user_id
pydantic-field
¶
The member who becomes the owner.
AdminPendingInvitation
pydantic-model
¶
Bases: BaseModel
An open invitation addressed to an account's email, as the admin views show it.
Tells an administrator reviewing an applicant who asked them to join, and into which organization, before the account is approved.
Config:
frozen:True
Fields:
-
id(UUID) -
organization_id(UUID) -
organization_name(str) -
invited_by_id(UUID | None) -
invited_by_name(str | None) -
invited_by_email(str | None) -
role(MembershipRole) -
created_at(datetime) -
expires_at(datetime)
created_at
pydantic-field
¶
When it was sent.
expires_at
pydantic-field
¶
When it stops being acceptable.
id
pydantic-field
¶
Unique identifier of the invitation.
invited_by_email = None
pydantic-field
¶
Email of the member who sent it; null when that account was deleted.
invited_by_id = None
pydantic-field
¶
The member who sent it; null when that account was deleted.
invited_by_name = None
pydantic-field
¶
Display name of the member who sent it, if set.
organization_id
pydantic-field
¶
The organization that sent it.
organization_name
pydantic-field
¶
The organization's display name.
role
pydantic-field
¶
The role the invitee would join with.
AdminQueueSummary
pydantic-model
¶
Bases: BaseModel
The queue in one read.
What is live, how long the oldest has waited, and who holds it.
Fields:
-
by_status(dict[AnalysisStatus, int]) -
oldest_waiting_seconds(float | None) -
per_user(list[AdminQueueUserShare]) -
sampled_at(datetime)
by_status
pydantic-field
¶
Live analyses by status; statuses with none are absent.
oldest_waiting_seconds = None
pydantic-field
¶
Age of the oldest analysis still waiting to run (pending or enqueued), or null when nothing waits.
per_user
pydantic-field
¶
Accounts holding live analyses, most first, capped by the server.
sampled_at
pydantic-field
¶
When this summary was read.
AdminQueueUserShare
pydantic-model
¶
Bases: BaseModel
One account's share of the live analyses.
Fields:
-
user_id(UUID) -
user_email(str | None) -
active(int)
AdminUserCreate
pydantic-model
¶
Bases: BaseModel
Admin user creation request.
Fields:
-
email(EmailStr) -
password(NewPasswordStr | None) -
name(str | None) -
role(Role) -
permissions(list[Permission] | None) -
organization(str | None) -
position(str | None) -
credits(int) -
confirm_email(bool) -
generate_password(bool)
Validators:
-
_require_password_unless_generated
confirm_email = True
pydantic-field
¶
Whether to pre-confirm the user's email address.
credits = 0
pydantic-field
¶
Research credits granted to the new account's organization on top of its starter grant; they never expire.
email
pydantic-field
¶
Email address for the new user.
generate_password = False
pydantic-field
¶
If true, ignore password, generate a strong random password, and email the user a one-time link to set their own password. The email is always pre-confirmed in this mode so the setup link can be delivered.
name = None
pydantic-field
¶
The new user's name. Defaults to the email local-part if omitted (admin-provisioned accounts are not request-access applicants).
organization = None
pydantic-field
¶
Organization the user belongs to.
password = None
pydantic-field
¶
Password for the new user. Required unless generate_password is set, in which case any supplied value is ignored.
permissions = None
pydantic-field
¶
Permissions for the new user. None uses config defaults.
position = None
pydantic-field
¶
Position of the user in their organization.
role = Role.USER
pydantic-field
¶
Authorization role for the new user (user or admin).
AdminUserListResponse
pydantic-model
¶
Bases: PaginatedResponse
Paginated user list response.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
users(list[AdminUserOut])
AdminUserOut
pydantic-model
¶
Bases: UserOut
An account as the operators see it.
The account's own settings and state. What belongs to its organization
(limits, overrides, the credit balance) is read and set on the
organization: :class:AdminOrganizationOut.
Config:
from_attributes:True
Fields:
-
name(None | str) -
organization(None | str) -
position(None | str) -
usage_type(UsageType | None) -
purpose(None | str) -
id(UUID7) -
permissions(list[Permission]) -
role(Role) -
email(EmailStr) -
email_confirmed_at(datetime | None) -
approved_at(datetime | None) -
consent_required(bool) -
pending_consents(list[PendingConsent]) -
has_billing_account(bool) -
organization_id(UUID | None) -
organization_name(str | None) -
organization_role(MembershipRole | None) -
created_at(datetime | None) -
last_login_at(datetime | None) -
disabled(bool) -
stripe_customer_id(str | None) -
can_upload(bool) -
can_submit(bool) -
can_create_api_keys(bool) -
pending_invitations(list[AdminPendingInvitation])
can_create_api_keys
pydantic-field
¶
Whether the account may create API keys — it holds the api-key-create permission. Granted by an administrator; server-derived from the permission set, never stored separately.
can_submit
pydantic-field
¶
Whether the account may submit analyses — it holds the analysis-create permission, directly or through the wildcard. Server-derived from the permission set, never stored separately.
can_upload
pydantic-field
¶
Whether the account may register recordings — it holds the recording-create permission, directly or through the wildcard. Server-derived from the permission set, never stored separately.
pending_invitations
pydantic-field
¶
Open invitations addressed to the account's email: not accepted, not revoked, not expired, from an organization that still exists. Shows who invited an applicant awaiting approval, and where to.
AdminUserReject
pydantic-model
¶
Bases: BaseModel
An admin's decision to decline an access request.
reason is chosen from a fixed list and is what the applicant is told.
note is the reviewer's own words: it is recorded with the decision and
is never sent, because an explanation written for a colleague should not
become an external statement about a named person.
Fields:
-
reason(RegistrationRejectionReason) -
note(str | None) -
notify(bool)
note = None
pydantic-field
¶
The reviewer's note, for the audit record. Never sent to the applicant.
notify = True
pydantic-field
¶
Whether to email the applicant. Leave true unless there is a reason not to reach this address at all.
reason
pydantic-field
¶
Why the request was declined. The applicant is told this, in the platform's own wording, unless the reason carries no detail.
AdminUserUpdate
pydantic-model
¶
Bases: BaseModel
Admin user update request; an omitted field is left unchanged.
The account's own settings only: an organization's limits and credits
are set on the organization (:class:AdminOrganizationUpdate,
:class:CreditAdjustment). An unknown field is refused, not ignored, so
a limit sent here fails instead of silently changing nothing.
Config:
extra:forbid
Fields:
-
email(EmailStr | None) -
password(NewPasswordStr | None) -
role(Role | None) -
usage_type(UsageType | None) -
permissions(list[Permission] | None) -
disabled(bool | None) -
organization(str | None) -
position(str | None) -
can_upload(bool | None) -
can_submit(bool | None) -
can_create_api_keys(bool | None)
Validators:
-
_switches_or_permissions
can_create_api_keys = None
pydantic-field
¶
Grant (true) or withdraw (false) the ability to create API keys. Same mechanism as can_upload, on the api-key-create permission. Withdrawing leaves existing keys working and revocable; it stops new ones. Cannot be combined with permissions in one request.
can_submit = None
pydantic-field
¶
Grant (true) or withdraw (false) the ability to submit analyses. Same mechanism as can_upload, on the analysis-create permission. Cannot be combined with permissions in one request.
can_upload = None
pydantic-field
¶
Grant (true) or withdraw (false) the ability to register recordings. The server edits the permission set accordingly — withdrawing expands a wildcard grant into its other members — so this is the same gate the recording routes check, not a second one. Cannot be combined with permissions in one request.
disabled = None
pydantic-field
¶
Whether to disable or enable the user.
email = None
pydantic-field
¶
New email address.
organization = None
pydantic-field
¶
New organization.
password = None
pydantic-field
¶
New password.
permissions = None
pydantic-field
¶
New permissions list.
position = None
pydantic-field
¶
New position.
role = None
pydantic-field
¶
New authorization role (user or admin).
usage_type = None
pydantic-field
¶
New usage type. Switching changes which licence the user must consent to (they are re-gated on the new licence) and which analysis configs they may run — but outputs keep the licence they were produced under.
AnalysisBiomarkersResponse
pydantic-model
¶
Bases: BiomarkerResult
A single analysis's biomarker result plus its presentation table.
Extends BiomarkerResult (so existing consumers of the analysis biomarkers endpoint keep working unchanged) with the server-defined TableModel that renders it — formatted values, curated summary flags, and any configured status tokens.
Fields:
-
biomarkers(Biomarkers) -
qc(QCMetrics) -
metadata(dict[str, str | int | float | bool | None]) -
table(TableModel | None)
table = None
pydantic-field
¶
Server-defined presentation table for the result. None for producers predating the field.
AnalysisConfig
pydantic-model
¶
Bases: AnalysisConfigBase
The full analysis configuration: what is stored, hashed and run.
Adds what the catalogue does not serve: the image, the scheduling priority and the resources the analysis claims.
Config:
frozen:True
Fields:
-
identification(Identification) -
purpose(Purpose) -
provenance(Provenance) -
licence(Licence | LegalDocumentShort) -
evidence(Evidence) -
inputs(Inputs) -
outputs(Outputs) -
parameters(Parameters) -
cost(CostModel) -
runs_at(list[RunPlace]) -
docker(DockerSettings) -
priority(Priority) -
resources(ResourceRequirements)
Validators:
-
_provenance_written_before_it_existed -
runs_on_the_platform→runs_at -
the_declaration_covers_the_licence_class -
validated_regime_is_yousleeps_own_claim
priority
pydantic-field
¶
Scheduling priority. A platform decision; an author leaves it out.
compute_config_sha1()
¶
Compute the SHA1 hash of the analysis configuration JSON serialized.
load_validated_analysis_config(config_id, configs_dir)
classmethod
¶
Load and validate an analysis configuration from a YAML file by its filename.
:param config_id: ID of the analysis configuration file. :param configs_dir: Directory where the analysis configuration files are stored. :return: Validated analysis configuration.
AnalysisConfigBase
pydantic-model
¶
Bases: BaseModel
What an analysis configuration says that anyone may read.
The shared part of two models: AnalysisConfig, the full configuration
that is stored, hashed and run, and AnalysisConfigOut, what the
catalogue serves. What the platform knows about an analysis rather than
what the configuration says (whether its image is present, who it is
offered to) lives on the response model only, so it never enters a
configuration's identity.
Fields:
-
identification(Identification) -
purpose(Purpose) -
provenance(Provenance) -
licence(Licence | LegalDocumentShort) -
evidence(Evidence) -
inputs(Inputs) -
outputs(Outputs) -
parameters(Parameters) -
cost(CostModel) -
runs_at(list[RunPlace])
Validators:
-
_provenance_written_before_it_existed -
runs_on_the_platform→runs_at -
the_declaration_covers_the_licence_class -
validated_regime_is_yousleeps_own_claim
cost
pydantic-field
¶
Declarative pricing facts (work scaling + parameter surcharges). Defaults = flat per-signal-hour pricing; the quote endpoints always report the final figure.
evidence
pydantic-field
¶
What the analysis cites. An analysis with nothing to cite yet omits it.
identification
pydantic-field
¶
The identification object of the analysis configuration
licence
pydantic-field
¶
The licence of the analysis.
parameters
pydantic-field
¶
Parameters the analysis accepts. Omitted when it takes none.
provenance
pydantic-field
¶
Who developed the analysis, and what youSleep claims about it.
purpose
pydantic-field
¶
The purpose of the analysis.
runs_at
pydantic-field
¶
Where the analysis may run: on the platform, or on the platform and at an organisation's site. Its owner sets it, and a change applies to submissions made after it. Left out when it is the platform only. An organisation may run a platform-only analysis at its site only under an exception a platform administrator records.
runs_on_the_platform(runs_at)
pydantic-validator
¶
Require the platform among the places, and keep them in one order.
Every analysis runs on the platform; a site is the only addition. The order is fixed so two configurations that say the same thing hash the same.
the_declaration_covers_the_licence_class()
pydantic-validator
¶
Refuse a commercial licence class on a declaration that ticked non-commercial use.
The declaration is what the developer said the analysis may be offered for; the licence class is what the platform offers it for. The second cannot exceed the first.
validated_regime_is_yousleeps_own_claim()
pydantic-validator
¶
Refuse a validated regime on an analysis youSleep did not develop.
The regime says which values of a parameter the analysis was characterised
at, and the platform says it in its own voice: every other value is then
presented to the user as a research setting. That is a claim to make about
one's own work. A developer's published operating point for their own
analysis belongs under evidence, where a reader can see whose claim it
is, rather than being restated here as the platform's.
AnalysisConfigOut
pydantic-model
¶
Bases: AnalysisConfigBase
What the catalogue serves: the readable configuration and the platform's facts about it.
Fields:
-
identification(Identification) -
purpose(Purpose) -
provenance(Provenance) -
licence(Licence | LegalDocumentShort) -
evidence(Evidence) -
inputs(Inputs) -
outputs(Outputs) -
parameters(Parameters) -
cost(CostModel) -
runs_at(list[RunPlace]) -
available(bool) -
visibility(AnalysisVisibility) -
credits_per_signal_hour(float) -
site_allowance(SiteAllowance | None)
Validators:
-
_provenance_written_before_it_existed -
runs_on_the_platform→runs_at -
the_declaration_covers_the_licence_class -
validated_regime_is_yousleeps_own_claim
available = False
pydantic-field
¶
Whether the analysis's image is present in the registry, as the platform last checked.
credit
property
¶
Return the credit this analysis's results carry, wherever they are shown.
credits_per_signal_hour = 0
pydantic-field
¶
What the analysis costs per hour of recorded signal, before channel and parameter adjustments, as the platform charges it.
site_allowance = None
pydantic-field
¶
Where the caller's organisation may run the analysis, for a signed-in caller. Null for an anonymous caller, and from a server that predates it.
spend_class
property
¶
Return the spend class the analysis's licence gives it.
visibility = AnalysisVisibility.PUBLIC
pydantic-field
¶
Where the analysis is offered. A caller sees a private analysis only when it belongs to the caller's organization.
AnalysisFilter
pydantic-model
¶
Bases: _FilterBase
Predicate over a project's analyses; at least one field must be set.
Fields:
-
status_any(list[AnalysisStatus] | None) -
analysis_config_id(str | None)
Validators:
-
_at_least_one_predicate
AnalysisListResponse
pydantic-model
¶
Bases: PaginatedResponse
A page of analyses, of a project or of a recording.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
analyses(list[AnalysisOut])
AnalysisLogs
pydantic-model
¶
AnalysisManifest
pydantic-model
¶
Bases: BaseModel
The document an analysis container receives, and nothing else.
Config:
extra:forbidfrozen:True
Fields:
-
manifest_version(Literal[1]) -
analysis(ManifestAnalysis) -
inputs(ManifestInputs) -
slots(list[SlotDefinition]) -
parameters(dict[str, ParameterValue]) -
resources(ManifestResources) -
outputs(ManifestOutputs)
Validators:
-
_consistent
AnalysisOut
pydantic-model
¶
Bases: AnalysisIdMixin, AnalysisStatusMixin, AnalysisTimingMixin
Analysis information available to user.
Combines identification, timing, context annotations, and cost fields into a single flat response model.
Fields:
-
enqueue_time(datetime) -
start_time(datetime | None) -
end_time(datetime | None) -
status(AnalysisStatus) -
status_message(str | None) -
failure_code(ErrorCode | None) -
id(UUID) -
owner_id(UUID | None) -
analysis_types(list[AnalysisType]) -
analysis_config_name(AnalysisConfigNameStr) -
analysis_config_id(str) -
parameter_hash(str | None) -
study_name(NameString | None) -
study_id(UUID | None) -
project_name(NameString | None) -
project_id(UUID | None) -
recording_id(UUID | None) -
recording_file_name(str | None) -
channels(list[ChannelName] | None) -
parameters(list[tuple[str, str | int | float | bool]]) -
research_parameters(list[str] | None) -
analysis_hours(NonNegativeFloat) -
cost(NonNegativeFloat) -
cost_currency(Currency) -
deleted(bool)
analysis_config_id
pydantic-field
¶
ID of the analysis configuration used for the analysis.
analysis_config_name
pydantic-field
¶
Name of the analysis configuration used for the analysis.
analysis_hours = 0
pydantic-field
¶
Number of hours of recording analysed.
analysis_types
pydantic-field
¶
List of analysis types the analysis performed.
channels = None
pydantic-field
¶
Channels used in the analysis. None if all available channels were used.
cost = 0
pydantic-field
¶
Cost of the analysis.
cost_currency = Currency.CREDITS
pydantic-field
¶
The currency of the cost.
deleted = False
pydantic-field
¶
Flag indicating if the analysis has been deleted
owner_id = None
pydantic-field
¶
The member who added it. Only they, or the project's owner, may change or remove it; it passes to the project's owner when they leave the organization.
parameter_hash = None
pydantic-field
¶
SHA-1 hash of the analysis parameters (config ID + parameters + dependencies + channels).
parameters
pydantic-field
¶
Parameters used in the analysis.
project_id = None
pydantic-field
¶
ID of the project the analysis belongs to. None if deleted.
project_name = None
pydantic-field
¶
Name of the project the analysis belongs to. None if deleted.
recording_file_name = None
pydantic-field
¶
Name of the recording file the analysis was performed on. None if deleted.
recording_id = None
pydantic-field
¶
ID of the recording the analysis was performed on. None if deleted.
research_parameters = None
pydantic-field
¶
Parameters (by API name) whose value lay outside the analysis configuration's validated regime. A non-empty list marks this analysis as run in research mode: fully supported, but its outputs are exploratory because the analysis was not characterised at those values. Empty when every parameter was within the regime (or no regime is declared). None when not derived — the value could not be resolved against the configuration.
study_id = None
pydantic-field
¶
ID of the study the analysis belongs to. None if deleted.
study_name = None
pydantic-field
¶
Name of the study the analysis belongs to. None if deleted.
AnalysisParameter
pydantic-model
¶
Bases: BaseModel
Represents an analysis-specific parameter.
Analysis parameters are used to configure the analysis and can be of type 'str', 'int', or 'float'. Can be set by the user unless there is only a single choice in which case it is considered a hard coded parameters.
Fields:
-
name(ParameterNameStr) -
description(DescriptionStr) -
key(ParameterKeyStr) -
type(Literal['str', 'int', 'float', 'bool']) -
range(Range | None) -
choices(Choices | None) -
default(str | int | float | bool) -
validated_regime(list[str | int | float | bool] | None)
Validators:
-
_key_from_legacy_argument -
validate_range_choices -
validate_choices→choices -
validate_range→range -
validate_default -
validate_validated_regime
api_name
property
¶
Return the name a request uses for this parameter: its key.
Kept as a computed field so the API schema and every client keep the name they have always read; it is the key by another name.
choices = None
pydantic-field
¶
The list of choices for the parameter. If set, the parameter is considered a choice parameter and the user must select one of the choices. If choises is a length 1 list the parameter is considered a hard coded parameter and the user cannot change the value. Must be set if range is not set.
default
pydantic-field
¶
The default value of the parameter. Must be one of the choices if choices is set or must be in range if range is set. REQUIRED: All parameters must have a default for consistent hash computation.
description
pydantic-field
¶
A brief description of the parameter.
key
pydantic-field
¶
The machine key of the parameter, unique within the analysis: what a request names it by, the key it has in the analysis manifest's parameters, and the name the parameter hash is computed over. Lowercase letters, digits, hyphens and underscores.
name
pydantic-field
¶
The name of the parameter. Must be unique among all parameters of the analysis. The name must be a contain only lowercase alphabetical characters and underscores ('_') and be between 2 and 32 characters long.
range = None
pydantic-field
¶
The range of acceptable values for the parameter. Must be set if choices is not set.
type
pydantic-field
¶
The type of the parameter. Can be 'str', 'int', 'float', or 'bool'.
validated_regime = None
pydantic-field
¶
The value(s) of this parameter at which the analysis has been validated — its validated regime. Every other accepted value stays fully supported and runnable, but is a research setting: the analysis was not characterised there, so its outputs are exploratory and should be interpreted as such. This is a different statement from 'default', which only says which value is pre-selected for the user; an analysis may pre-select a value it was never validated at, or be validated at several values of which only one is pre-selected. List every validated value when more than one qualifies. Leave unset (null) when the validated regime is not declared, in which case no value is claimed to be a research setting and none is claimed to be validated. Each entry must be an accepted value of this parameter: one of 'choices', or inside 'range'.
get_validated_value_or_default(value)
¶
Return the value if it is not None, otherwise return the default value.
Every parameter declares a default, so a value is always returned.
is_research_mode(value)
¶
Return whether value falls outside this parameter's validated regime.
Always False when no validated regime is declared: an undeclared regime makes no claim about any value, so nothing is presented as research mode.
Pass a normalized value — the output of :meth:validate_value or
:meth:get_validated_value_or_default. A raw, uncoerced submission such as the
string "3840" does not match the integer 3840 and would be reported as research.
validate_choices(choices)
pydantic-validator
¶
Validate that all choices are unique and of the same type.
validate_default()
pydantic-validator
¶
Validate that the default value is one of the choices if choices is set.
validate_range(range)
pydantic-validator
¶
Validate that the range values are of the same type and either int or float.
validate_range_choices(data)
pydantic-validator
¶
Validate the range and choices fields.
Validate that only one of 'range' and 'choices' can be set and that at least one of them is set.
validate_validated_regime()
pydantic-validator
¶
Validate that every declared validated-regime value is an accepted value.
A validated regime that names a value the parameter does not accept could never be selected, so it would silently mark every selectable value as research mode.
validate_value(value)
¶
Validate the value of the parameter and return the value if it is valid.
AnalysisRequest
pydantic-model
¶
Bases: BaseModel
Analysis request information.
Fields:
-
analysis_config_id(AnalysisConfigIdStr) -
channels(list[ChannelName] | None) -
parameters(list[tuple[str, str | int | float | bool]]) -
dependencies(list[tuple[str, list[EventType]]])
Validators:
analysis_config_id
pydantic-field
¶
The unique analysis config type identifier (e.g., 'u-sleep-research-v1')
channels = None
pydantic-field
¶
Optional list of specific channels (by name) to use in the analysisIf not specified, all channels of types and/or exact match to the analysis' requirements available on the study will be used.
dependencies
pydantic-field
¶
A list of 2-tuples of format (parameter_hash, list of typed events) where parameter_hash identifies a dependency analysis by its parameter hash (SHA-1 hex string), and typed events specify which events are required as input from that dependency. The present analysis will only be run if all dependencies have status COMPLETED. This hash-based approach enables order-independent submission: you can submit an analysis before its dependencies exist, and it will wait in DEPENDENCY status until they complete. If any dependency fails/cancels, this analysis will also fail.
parameters
pydantic-field
¶
Parameters to use in the analysis as per the analysis config. Each parameter is a tuple of [name, value] where name is the api_name from the analysis config.
get_analysis_request_hash(include=('analysis_config_id', 'parameters', 'dependencies', 'channels'))
¶
Return a sha1 hash of the JSON str serialized analysis request.
This can be used to compare the analysis submission against other analysis submissions. Note that only the fields specified in the include set are considered when creating the hash. Per default, all fields are included. This flag is useful to ensure consistent outputs of this function if the class is used as a base class for other classes, which may define other fields in the model.
Boolean parameters are stored as Python bool and serialize consistently to JSON as true/false (lowercase), ensuring consistent hashing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
include
|
Sequence[str]
|
The fields to include in the hash. |
('analysis_config_id', 'parameters', 'dependencies', 'channels')
|
Returns:
| Type | Description |
|---|---|
str
|
The sha1 hash of the analysis and its parameters. |
validate_channels(value)
pydantic-validator
¶
Validate that all channels are unique.
AnalysisResponse
pydantic-model
¶
Bases: AnalysisIdMixin, AnalysisStatusMixin
Internal response that can include logs/events/exit_code.
Fields:
-
status(AnalysisStatus) -
status_message(str | None) -
failure_code(ErrorCode | None) -
id(UUID) -
logs(AnalysisLogs | None) -
exit_code(int | None) -
events(EventsPayload | None)
events = None
pydantic-field
¶
Result of the analysis if successful. Can be a list of Events, a URL to download, or the literal 'default-storage' indicating backend storage.
exit_code = None
pydantic-field
¶
Exit code of the analysis process if it was run
logs = None
pydantic-field
¶
Logs of the analysis if it was run.
AnalysisRunOut
pydantic-model
¶
Bases: BaseModel
Where an analysis runs or ran, and on what.
The place is known from submission. The image digest and the inputs' SHA-256 come from the runner's attestation once the run's result is accepted; until then, and for a run that predates attestations, they are empty.
Fields:
-
analysis_id(UUID) -
place(RunPlace) -
image_digest(str | None) -
input_sha256(list[str]) -
runner_name(str | None) -
recorded_at(datetime | None)
image_digest = None
pydantic-field
¶
The digest of the image that ran.
input_sha256
pydantic-field
¶
The inputs, as the runner read them.
place
pydantic-field
¶
On the platform, or at the organisation's own site.
recorded_at = None
pydantic-field
¶
When the run's result was accepted.
runner_name = None
pydantic-field
¶
The runner that ran it. Shown to the organisation's owners and admins, and to platform administrators; None for anyone else.
AnalysisSelector
pydantic-model
¶
Bases: _SelectorBase
Address a set of analyses: exactly one of ids | filter | all.
Fields:
-
ids(list[UUID] | None) -
all(bool) -
filter(AnalysisFilter | None)
Validators:
-
_exactly_one_mode
filter = None
pydantic-field
¶
Server-resolved predicate (live set).
AnalysisSubmission
pydantic-model
¶
Bases: AnalysisRequest
Analysis submission information.
Fields:
-
analysis_config_id(AnalysisConfigIdStr) -
channels(list[ChannelName] | None) -
parameters(list[tuple[str, str | int | float | bool]]) -
dependencies(list[tuple[str, list[EventType]]]) -
id(UUID7) -
manifest(AnalysisManifest) -
docker_volumes(dict[str, DockerVolumeDict]) -
remote_file_mappings(list[RemoteFileMapping]) -
priority(NonNegativeInt) -
analysis_hours(NonNegativeFloat) -
max_sample_rate_hz(PositiveFloat | None) -
container_image(str) -
resource_requirements(ResourceRequirements) -
resolved_resources(ResolvedResourceClaim | None)
Validators:
analysis_hours
pydantic-field
¶
The number of hours of signal that were processed by the analysis. This is used for cost estimation and setting usage limits.
container_image
pydantic-field
¶
The full image name of the container to be used for the analysis including registry, repository, and tag.
docker_volumes
pydantic-field
¶
The volumes to be mounted in the docker container. The keys are the host paths or docker volume names and the values are dictionaries with parameters 'bind' and 'mode'.
id
pydantic-field
¶
Unique identifier of the analysis
manifest
pydantic-field
¶
The document the container receives: inputs by path with their description, the resolved channels, slots, typed parameters, the resource claim and the output path. The container reads this and nothing else.
max_sample_rate_hz = None
pydantic-field
¶
Maximum NATIVE sample rate (Hz) across the resolved channel selection. Feeds the per-kHz term of the memory formula (see ResourceRequirements) so recordings sampled above an analysis's working rate are provisioned proportionally more memory. Always populated on submissions built by the current api-server (every ingested channel carries a sample rate — EDF is the only supported format and its parser computes the rate from required header fields). Optional ONLY so that submissions persisted as JSONB before this field existed still validate when re-dispatched after deploy (e.g. an analysis queued on unresolved dependencies); consumers must substitute a conservative assumed rate for None rather than 0, which would silently under-size the claim.
priority = 0
pydantic-field
¶
Priority of the analysis. Higher priority analyses are executed first.
remote_file_mappings
pydantic-field
¶
A list of remote file mappings for the analysis submission. The mappings specify how the input and output files should be mapped to/from the local file system of the analysis container.
resolved_resources = None
pydantic-field
¶
The resource claim resolved for THIS submission from resource_requirements and the submission's hours, resolved channel count and native sample rate. Resolved once at submission so the container's memory hint and the orchestrator's cgroup ceiling are two renderings of one number rather than two independent derivations. Optional ONLY so that submissions persisted as JSONB before this field existed still validate when re-dispatched after deploy (e.g. an analysis queued on unresolved dependencies); consumers must fall back to deriving the claim from the coefficients for None rather than treating it as a zero claim, which would leave the analysis unbounded.
resource_requirements
pydantic-field
¶
The resource requirement COEFFICIENTS for the analysis, snapshotted from the analysis config at submission so a later re-calibration cannot rewrite what an existing analysis ran under. These are rates; resolved_resources holds the quantities they produced for this submission.
AnalysisUsage
pydantic-model
¶
Bases: BaseModel
Response model for the analysis usage endpoint.
Fields:
-
analyses(NonNegativeInt) -
credit_cost(NonNegativeFloat) -
signal_hours(NonNegativeFloat)
AnnotatedAnalysisEvents
pydantic-model
¶
Bases: BaseModel
Events with associated analysis metadata for API download.
Fields:
-
events(list[Event]) -
analysis(AnalysisOut)
AnnotatedEventStats
pydantic-model
¶
Bases: BaseModel
Event statistics with associated analysis metadata.
Fields:
-
event_stats(list[EventStats]) -
analysis(ReportAnalysisInfo)
ApiKeyCreate
pydantic-model
¶
Bases: BaseModel
Request to create an API key on the signed-in account.
Fields:
-
name(str) -
description(str | None) -
scopes(list[Permission]) -
expires_in_days(int | None) -
password(str)
Validators:
-
_scopes_are_scopeable
description = None
pydantic-field
¶
What the key is for and what holds it, for the account's own records: a device, a system, an integration.
expires_in_days = None
pydantic-field
¶
Days until the key expires, at most the server's maximum. Omitted means the server's default lifetime. Every key expires; rotate by creating the next key before this one lapses.
name
pydantic-field
¶
A label for telling keys apart, such as the system that will hold it.
password
pydantic-field
¶
The account password, entered again: creating a long-lived credential is confirmed by the person, not only by their session.
scopes
pydantic-field
¶
The permissions the key may exercise. A key never holds more than its owner holds at the time of a request, and cannot be scoped to account (user:*) or key (api_key:*) management. The server reports which permissions may be delegated (GET /status/permissions, key_scopeable) and refuses any other.
ApiKeyCreated
pydantic-model
¶
Bases: ApiKeyOut
The response to creating a key: the listing fields plus the secret.
Fields:
-
id(UUID7) -
name(str) -
description(str | None) -
prefix(str) -
scopes(list[Permission]) -
created_at(datetime) -
expires_at(datetime) -
last_used_at(datetime | None) -
expired(bool) -
secret(str)
secret
pydantic-field
¶
The full key. It appears only in this response; store it in a secret manager now. Send it as Authorization: Bearer <key>.
ApiKeyOut
pydantic-model
¶
Bases: BaseModel
An API key as listed on the account: everything except the secret.
Config:
from_attributes:True
Fields:
-
id(UUID7) -
name(str) -
description(str | None) -
prefix(str) -
scopes(list[Permission]) -
created_at(datetime) -
expires_at(datetime) -
last_used_at(datetime | None) -
expired(bool)
description = None
pydantic-field
¶
What the key is for and what holds it.
expired
pydantic-field
¶
Whether the key has passed its expiry. An expired key no longer authenticates; delete it and create a new one.
expires_at
pydantic-field
¶
When the key stops authenticating requests.
last_used_at = None
pydantic-field
¶
When the key last authenticated a request, recorded to the hour; null if it never has.
prefix
pydantic-field
¶
The first characters of the key, for telling keys apart in a list or a log. Never enough to use the key.
scopes
pydantic-field
¶
The permissions the key was created with.
AuditActionInfo
pydantic-model
¶
Bases: BaseModel
One audit action as the server records it.
The vocabulary is served so that a client renders it instead of keeping a copy: an audit view offers as filters exactly the actions its reader can receive, named as the server names them.
Fields:
action
pydantic-field
¶
The action, as its events carry it.
item_keys
pydantic-field
¶
The detail keys of this action that hold item ids, alone or in a list: the ids an audit view's item filter matches.
name
pydantic-field
¶
How the action reads.
readers
pydantic-field
¶
Who can ever read an event of this action, besides the platform's administrators: organisation (its owner and admins), project (the project's owner) and subject (the person it is about).
removal
pydantic-field
¶
Whether the action records something removed for good: a deletion or a purge.
AuditEventListResponse
pydantic-model
¶
Bases: PaginatedResponse
A page of audit events, newest first.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
events(list[AuditEventOut]) -
export_limit(int)
export_limit
pydantic-field
¶
The most events one CSV export of this view holds. An export of more is refused: narrow the filters until total fits.
AuditEventOut
pydantic-model
¶
Bases: BaseModel
One audit event, as recorded.
Config:
from_attributes:True
Fields:
-
id(UUID) -
occurred_at(datetime) -
actor(str) -
action(str) -
org_id(UUID | None) -
user_id(UUID | None) -
detail(dict[str, Any])
Validators:
-
_redact→detail
action
pydantic-field
¶
What happened. A plain string, so a newly recorded kind of action needs no client update; the server serves its vocabulary at GET /status/audit-actions.
actor
pydantic-field
¶
Who acted: admin:<user id> for an administrator, user:<user id> for an account owner, system:<name> for a scheduled task.
detail
pydantic-field
¶
Non-personal context of the action — counts, bytes, dates, the names of fields that changed. Keys vary by action.
id
pydantic-field
¶
Identifier of the event; time-ordered.
occurred_at
pydantic-field
¶
When the action happened.
org_id = None
pydantic-field
¶
The affected organization, when the action concerns one. A bare identifier: the organization may no longer exist.
user_id = None
pydantic-field
¶
The affected account, when the action concerns one. A bare identifier: the account may no longer exist.
AuditFilters
pydantic-model
¶
Bases: BaseModel
What narrows an audit view: the same filters on every view.
Config:
extra:forbid
Fields:
-
actions(list[str] | None) -
since(datetime | None) -
until(datetime | None) -
user_id(UUID | None) -
resource_id(UUID | None)
actions = None
pydantic-field
¶
Only events recording one of these actions.
resource_id = None
pydantic-field
¶
Only events naming this item: a project, study, recording, analysis, export, invitation or API key.
since = None
pydantic-field
¶
Only events at or after this time.
until = None
pydantic-field
¶
Only events before this time.
user_id = None
pydantic-field
¶
Only events concerning this account.
AxisTick
pydantic-model
¶
Bases: BaseModel
One axis tick: value, normalized position, display label.
Fields:
-
value(float) -
fraction(float) -
label(str) -
clock_label(str | None)
clock_label = None
pydantic-field
¶
Wall-clock display label (e.g. '23:00') for time axes whose producer knows the recording start. None on non-time axes or producers predating the field; consumers offer an Elapsed/Clock toggle when present.
fraction
pydantic-field
¶
Position, 0 (left) … 1 (right).
label
pydantic-field
¶
Display label for the tick.
value
pydantic-field
¶
Tick value in the domain's unit.
BaseSummaryStats
pydantic-model
¶
Bases: BaseModel
Base model for aggregated distribution statistics.
Shared by both event summary stats and biomarker summary stats.
Fields:
-
analysis_config_id(str) -
analysis_parameters(list[tuple[str, str | int | float | bool]]) -
stats(dict[str, DistributionStats]) -
origins(list[StatsOrigin]) -
origins_ref(str | None) -
origins_summary(OriginsSummary | None)
analysis_config_id
pydantic-field
¶
The ID of the analysis configuration.
analysis_parameters
pydantic-field
¶
The analysis parameters used in computation.
origins
pydantic-field
¶
Studies/analyses that contributed to these stats. May be empty when origins_ref is set — the referenced shared list on the response envelope is then authoritative (large reports carry each distinct origins list once instead of repeating it per entry).
origins_ref = None
pydantic-field
¶
Key into the response envelope's origins_sets when the origins list is shared between entries. None when origins is carried inline.
origins_summary = None
pydantic-field
¶
Aggregate provenance. Always derivable from the origins list when one is carried; on very large reports the producer may carry ONLY this summary (origins empty, origins_ref None) to bound the payload — renderers must then read counts, group labels, window sources and research-regime markers from here, and fetch per-study detail from the audit endpoints. None for producers predating the field.
stats
pydantic-field
¶
Metric name to distribution statistics.
BatchAnalysesQuote
pydantic-model
¶
Bases: BaseModel
Pre-flight cost quote for a batch submission (same body as the submit).
Runs the exact per-step validation/pricing path the submission uses, so a
quoted (non-error) step submits at that price. The aggregate mirrors
:class:~yousleep_common.models.billing.BillingQuote: each balance the
batch uses gets its own line, and blocked_reason applies when any of
them cannot cover its part, against the org's current balances. Advisory — the submission's own reserve remains the gate.
Fields:
-
results(list[BatchQuoteResult]) -
summary(BatchQuoteSummary) -
total_estimated_credits(NonNegativeInt) -
wallets(list[WalletQuote]) -
blocked_reason(Literal['insufficient_credits'] | None) -
input_coverage(list[StepInputCoverage]) -
placement(RunPlacement | None) -
studies_without_recordings(list[UUID])
blocked_reason = None
pydantic-field
¶
Why the batch would be rejected (a balance it uses cannot cover its part), or null.
input_coverage
pydantic-field
¶
Per step, how many recordings have each declared input.
placement = None
pydantic-field
¶
Where the batch's analyses would run. Null from a server that predates it, and when no step was quoted.
studies_without_recordings
pydantic-field
¶
Studies the selector addressed that have no recording to analyse; they are not among the results. Empty for explicit targets.
total_estimated_credits
pydantic-field
¶
Sum of the quoted steps' credit costs (errored steps excluded).
wallets
pydantic-field
¶
What the batch asks of each balance it uses: research analyses of grants, commercial ones of purchased credits.
BatchAnalysisIdsRequest
pydantic-model
¶
Bases: BaseModel
Shared base for batch requests that take a list of analysis IDs.
Fields:
-
analysis_ids(list[UUID])
BatchAnalysisPipelineStep
pydantic-model
¶
Bases: BaseModel
A single step in a batch analysis pipeline.
Fields:
-
step_id(str | None) -
analysis_config_id(AnalysisConfigIdStr) -
default_channels(list[str] | None) -
parameters(list[tuple[str, str | int | float | bool]]) -
depends_on(list[str]) -
per_recording_overrides(dict[UUID, BatchRecordingOverride] | None)
BatchAnalysisResult
pydantic-model
¶
Bases: BaseModel
Result for a single (target, step) pair in a batch analysis response.
Fields:
-
target(BatchAnalysisTarget) -
step_id(str) -
status(Literal['submitted', 'error']) -
analysis(AnalysisOut | None) -
error(BatchItemError | None)
BatchAnalysisStatusResult
pydantic-model
¶
Bases: BaseModel
Result for a single analysis in batch status polling.
Fields:
-
analysis_id(UUID) -
status(Literal['ok', 'error']) -
analysis(AnalysisOut | None) -
error(BatchItemError | None)
BatchAnalysisStatusSummary
pydantic-model
¶
Bases: _OkErrorSummary
Summary for batch analysis status polling.
Fields:
-
total(int) -
ok(int) -
errors(int)
BatchAnalysisSummary
pydantic-model
¶
Bases: BatchSummary
Summary for batch analysis submission.
Fields:
-
total(int) -
submitted(int) -
errors(int)
BatchAnalysisTarget
pydantic-model
¶
Bases: BaseModel
A target recording for batch analysis submission.
Fields:
-
study_id(UUID) -
recording_id(UUID)
BatchCancelAnalysesRequest
pydantic-model
¶
Bases: BatchAnalysisIdsRequest
Request body for batch analysis cancellation.
Fields:
-
analysis_ids(list[UUID])
BatchCancelAnalysesResponse
pydantic-model
¶
Bases: BaseModel
Response for batch analysis cancellation.
Fields:
-
results(list[BatchCancelResult]) -
summary(BatchCancelSummary)
BatchCancelResult
pydantic-model
¶
Bases: BaseModel
Result for a single analysis cancellation.
Fields:
-
analysis_id(UUID) -
status(Literal['cancelled', 'error']) -
error(BatchItemError | None)
BatchCancelSummary
pydantic-model
¶
Bases: BatchSummary
Summary for batch analysis cancellation.
Fields:
-
total(int) -
cancelled(int) -
errors(int)
BatchChannelPatchSummary
pydantic-model
¶
Bases: BatchSummary
Summary for the bulk channel patch (total = number of patches submitted).
Fields:
-
total(int) -
updated(int) -
errors(int) -
channels_updated(int)
BatchCreateStudiesRequest
pydantic-model
¶
BatchCreateStudiesResponse
pydantic-model
¶
Bases: BaseModel
Response for batch study creation.
Fields:
-
results(list[BatchStudyResult]) -
summary(BatchStudySummary)
BatchDeleteAccepted
pydantic-model
¶
Bases: BaseModel
The delete resolved and was enqueued (fire-and-return).
Deletion runs as a background cascade; list endpoints hide the affected rows for the run's duration. The ids were resolved at acceptance — rows created after this response are not part of the run.
Fields:
-
count(int)
count
pydantic-field
¶
Rows resolved and scheduled for deletion.
BatchEventBlocksResult
pydantic-model
¶
Bases: BaseModel
Result for a single analysis in batch event-block retrieval.
Fields:
-
analysis_id(UUID) -
status(Literal['ok', 'error']) -
document(EventBlocksDocument | None) -
count(int | None) -
error(BatchItemError | None)
count = None
pydantic-field
¶
Events the document decodes to — the sum of every block's slot count.
BatchEventResult
pydantic-model
¶
Bases: BaseModel
Result for a single analysis in batch event retrieval.
Fields:
-
analysis_id(UUID) -
status(Literal['ok', 'error']) -
events(list[Event] | None) -
count(int | None) -
error(BatchItemError | None)
BatchEventSummary
pydantic-model
¶
Bases: _OkErrorSummary
Summary for batch event retrieval.
Fields:
-
total(int) -
ok(int) -
errors(int)
BatchGetAnalysesStatusRequest
pydantic-model
¶
Bases: BatchAnalysisIdsRequest
Request body for batch analysis status polling.
Fields:
-
analysis_ids(list[UUID])
BatchGetAnalysesStatusResponse
pydantic-model
¶
Bases: BaseModel
Response for batch analysis status polling.
Fields:
-
results(dict[str, BatchAnalysisStatusResult]) -
summary(BatchAnalysisStatusSummary)
BatchGetEventBlocksRequest
pydantic-model
¶
Bases: BatchAnalysisIdsRequest
Request body for batch event-block retrieval.
Deliberately carries no filter. The single-analysis block endpoint has none either — a block document is meant to be fetched once and sliced locally — and giving the batch form a filter the per-analysis form lacks would make the two disagree about what a block document is.
Fields:
-
analysis_ids(list[UUID])
analysis_ids
pydantic-field
¶
Analyses to fetch blocks for — at most the schema's maxItems per request, which is the cap the server enforces (GET /status/limits reports the same number).
BatchGetEventBlocksResponse
pydantic-model
¶
Bases: BaseModel
Response for batch event-block retrieval.
Fields:
-
results(dict[str, BatchEventBlocksResult]) -
summary(BatchEventSummary)
BatchGetEventsRequest
pydantic-model
¶
Bases: BatchAnalysisIdsRequest
Request body for batch event retrieval.
Fields:
-
analysis_ids(list[UUID]) -
filter(EventsFilter | None)
BatchGetEventsResponse
pydantic-model
¶
Bases: BaseModel
Response for batch event retrieval.
Fields:
-
results(dict[str, BatchEventResult]) -
summary(BatchEventSummary)
BatchGetRecordingsByStudiesRequest
pydantic-model
¶
Bases: BaseModel
Request body for fetching the recordings of multiple studies in one call.
Fields:
-
study_ids(list[UUID])
BatchGetRecordingsByStudiesResponse
pydantic-model
¶
Bases: BaseModel
Response for batch recordings-by-study retrieval (keyed by study id).
Fields:
-
results(dict[str, BatchRecordingsByStudyResult]) -
summary(BatchRecordingsByStudySummary)
BatchGetRecordingsDetailsRequest
pydantic-model
¶
Bases: BaseModel
Request body for batch recording details retrieval.
Fields:
-
recording_ids(list[UUID])
BatchGetRecordingsDetailsResponse
pydantic-model
¶
Bases: BaseModel
Response for batch recording details retrieval.
Fields:
-
results(dict[str, BatchRecordingDetailResult]) -
summary(BatchRecordingDetailSummary)
BatchGetStudiesByIdsRequest
pydantic-model
¶
Bases: BaseModel
Request body for fetching multiple studies by id in one call.
Fields:
-
study_ids(list[UUID])
BatchGetStudiesByIdsResponse
pydantic-model
¶
Bases: BaseModel
Response for batch study by-id retrieval (keyed by study id).
Fields:
-
results(dict[str, BatchStudyByIdResult]) -
summary(BatchStudyByIdSummary)
BatchItemError
pydantic-model
¶
BatchPatchChannelsRequest
pydantic-model
¶
BatchPatchChannelsResponse
pydantic-model
¶
Bases: BaseModel
Response for the bulk channel patch.
Fields:
-
results(list[ChannelPatchResult]) -
summary(BatchChannelPatchSummary)
BatchPatchStudiesMetadataRequest
pydantic-model
¶
Bases: BaseModel
Apply metadata patches across many studies (207 per-item results).
Fields:
-
items(list[StudyMetadataPatch])
BatchPatchStudiesMetadataResponse
pydantic-model
¶
Bases: BaseModel
Per-item results plus the usual batch summary.
Fields:
-
results(list[StudyMetadataResult]) -
summary(BatchStudyMetadataSummary)
BatchQuoteResult
pydantic-model
¶
Bases: BaseModel
Quoted cost (or error) for a single (target, step) pair.
Fields:
-
target(BatchAnalysisTarget) -
step_id(str) -
status(Literal['quoted', 'error']) -
estimated_credits(NonNegativeInt | None) -
error(BatchItemError | None) -
missing_inputs(list[str] | None) -
channels(list[str] | None)
channels = None
pydantic-field
¶
The recording's channels this run receives, by name, in the order the analysis gets them: the platform's match (the first ones in montage order where the recording has more than the analysis takes) or the channels chosen explicitly. Null on a refused result.
missing_inputs = None
pydantic-field
¶
The declared inputs this recording lacks, by name (a channel type, an exact channel, or a subject value); empty when it has every one. Null when the step was not resolved against the recording.
BatchQuoteSummary
pydantic-model
¶
Bases: BatchSummary
Summary for a batch analysis quote.
Fields:
-
total(int) -
quoted(int) -
errors(int)
BatchRecordingDetailResult
pydantic-model
¶
Bases: BaseModel
Result for a single recording in batch details retrieval.
Fields:
-
recording_id(UUID) -
status(Literal['ok', 'error']) -
recording(RecordingOut | None) -
error(BatchItemError | None)
BatchRecordingDetailSummary
pydantic-model
¶
Bases: _OkErrorSummary
Summary for batch recording details retrieval.
Fields:
-
total(int) -
ok(int) -
errors(int)
BatchRecordingOverride
pydantic-model
¶
Bases: BaseModel
Per-recording overrides for a pipeline step.
Fields:
-
channels(list[str] | None)
BatchRecordingsByStudyResult
pydantic-model
¶
Bases: BaseModel
Result for a single study in batch recordings-by-study retrieval.
Fields:
-
study_id(UUID) -
status(Literal['ok', 'error']) -
recordings(list[RecordingOut] | None) -
error(BatchItemError | None)
BatchRecordingsByStudySummary
pydantic-model
¶
Bases: _OkErrorSummary
Summary for batch recordings-by-study retrieval.
Fields:
-
total(int) -
ok(int) -
errors(int)
BatchSetStudyLightsRequest
pydantic-model
¶
Bases: BaseModel
Assign lights markers across many studies (207 per-item results).
Fields:
-
items(list[StudyLightsAssignment]) -
replace_existing(bool)
replace_existing = False
pydantic-field
¶
False: rows whose targeted marker already exists error per-item (manual edits win by default). True: overwrite.
BatchSetStudyLightsResponse
pydantic-model
¶
Bases: BaseModel
Per-item results plus the usual batch summary.
Fields:
-
results(list[StudyLightsResult]) -
summary(BatchStudyMetadataSummary)
BatchStudyByIdResult
pydantic-model
¶
Bases: BaseModel
Result for a single study in batch by-id retrieval.
Fields:
-
study_id(UUID) -
status(Literal['ok', 'error']) -
study(StudyOut | None) -
error(BatchItemError | None)
BatchStudyByIdSummary
pydantic-model
¶
Bases: _OkErrorSummary
Summary for batch study by-id retrieval.
Fields:
-
total(int) -
ok(int) -
errors(int)
BatchStudyItem
pydantic-model
¶
Bases: BaseModel
A single study to create in a batch.
Fields:
-
name(str) -
description(str | None) -
age(int | None) -
bmi(float | None) -
sex(Sex | None) -
tags(list[str] | None) -
subject_key(SubjectKey | None) -
session_index(PositiveInt | None)
session_index = None
pydantic-field
¶
Declared position of this study in its subject's series, 1 = first. Same contract as StudyMetadata.session_index.
subject_key = None
pydantic-field
¶
The person this study belongs to, so a night is filed under its subject at creation rather than patched in afterwards. Same contract as StudyMetadata.subject_key.
BatchStudyMetadataSummary
pydantic-model
¶
Bases: BatchSummary
Summary for a metadata/lights batch.
Fields:
-
total(int) -
updated(int) -
errors(int)
BatchStudyResult
pydantic-model
¶
Bases: BaseModel
Result for a single study in a batch response.
Fields:
-
name(str) -
status(Literal['created', 'error']) -
study(StudyOut | None) -
error(BatchItemError | None)
BatchStudySummary
pydantic-model
¶
Bases: BatchSummary
Summary for batch study creation.
Fields:
-
total(int) -
created(int) -
errors(int)
BatchSubmitAnalysesRequest
pydantic-model
¶
Bases: BaseModel
Request body for batch analysis submission (and its quote).
Targets are addressed either explicitly (targets) or through a study
selector (the batch addressing language): the server resolves the
matched studies to their recordings at acceptance time. Exactly one of
the two must be set. Live-set selectors (filter/all) must state
expected_count — the matched-STUDY total the caller last resolved
(the filtered study list's total); the server re-resolves
and rejects on a mismatch. A selector that resolves to more recordings
than an explicit request may carry is rejected with the resolved count —
narrow the filter and submit in slices.
Fields:
-
pipeline(list[BatchAnalysisPipelineStep]) -
targets(list[BatchAnalysisTarget] | None) -
selector(StudySelector | None) -
complete_inputs_only(bool) -
expected_count(int | None)
Validators:
-
_one_addressing_mode
complete_inputs_only = False
pydantic-field
¶
Leave out recordings that lack an optional input the analysis declares, so every run receives the same inputs. A recording lacking a required input is refused either way.
expected_count = None
pydantic-field
¶
Required for filter/all selectors: the matched-study count the caller saw. The server re-resolves and rejects on a mismatch.
selector = None
pydantic-field
¶
Address targets as a study set; the server resolves each matched study's recordings.
BatchSubmitAnalysesResponse
pydantic-model
¶
Bases: BaseModel
Response for batch analysis submission.
Fields:
-
results(list[BatchAnalysisResult]) -
summary(BatchAnalysisSummary) -
studies_without_recordings(list[UUID])
studies_without_recordings
pydantic-field
¶
Studies the selector addressed that have no recording to analyse; nothing was submitted for them. Empty for explicit targets.
BatchSummary
pydantic-model
¶
Bases: BaseModel
Base summary counts for batch responses. Subclassed per-endpoint.
Fields:
-
total(int)
BillingQuote
pydantic-model
¶
Bases: WalletQuote
Pre-flight cost quote for one analysis: the balance it is paid from, and whether it covers it.
Fields:
-
wallet(CreditBucket) -
estimated_credits(NonNegativeInt) -
available_credits(NonNegativeInt) -
balance_after(int) -
blocked_reason(Literal['insufficient_credits'] | None) -
placement(RunPlacement | None)
placement = None
pydantic-field
¶
Where the analysis would run. Null from a server that predates it.
BillingRates
pydantic-model
¶
Bases: BaseModel
Public billing rates and grant terms (config-fixed platform pricing).
Served by GET /status/billing-rates so clients display the SAME
numbers the server charges and grants with, instead of hardcoding them.
Credits are the unit throughout; euro pricing lives in the Stripe checkout.
Config:
frozen:True
Fields:
-
credit_cost_per_signal_hour(float) -
minimum_credits_per_analysis(int) -
storage_credits_per_gb_month(float) -
storage_grace_days(int) -
starter_grant_credits(int) -
grant_terms_months(list[int]) -
default_grant_term_months(int) -
grant_expiry_banner_days(int) -
grant_buffer_pct(int)
credit_cost_per_signal_hour
pydantic-field
¶
Credits charged per hour of analysed signal, unless an analysis sets its own price.
default_grant_term_months
pydantic-field
¶
The term a request starts at.
grant_buffer_pct
pydantic-field
¶
The margin a grant request adds to its plan's computed cost by default, in percent.
grant_expiry_banner_days
pydantic-field
¶
Days before a grant expires from which the organization's page shows the coming expiry.
grant_terms_months
pydantic-field
¶
The terms, in months, a grant or an extension may be asked for.
minimum_credits_per_analysis
pydantic-field
¶
Minimum credits charged per analysis submission.
starter_grant_credits
pydantic-field
¶
Research credits every new organization receives once; they never expire.
storage_credits_per_gb_month
pydantic-field
¶
Purchased credits charged per GB per month stored above an organization's free ceiling (daily debit). Storage up to the ceiling is free.
storage_grace_days
pydantic-field
¶
Days of grace after paid storage can no longer be paid for before the recordings above the ceiling are deleted.
BiomarkerParameters
pydantic-model
¶
Bases: BaseModel
Parameters for biomarker computation.
TIB window is not included here — it comes from StatisticsWindow, resolved from study events or client override in the report use case.
Fields:
-
epoch_duration_sec(int) -
soremp_threshold_min(float)
BiomarkerResult
pydantic-model
¶
Bases: BaseModel
Complete biomarker computation result for a single analysis.
Fields:
-
biomarkers(Biomarkers) -
qc(QCMetrics) -
metadata(dict[str, str | int | float | bool | None])
BiomarkerSummaryStats
pydantic-model
¶
Bases: BaseSummaryStats
Aggregated biomarker statistics across multiple analyses.
Inherits from BaseSummaryStats — same stats dict pattern as
SummaryStats but without event-specific fields.
Fields:
-
analysis_config_id(str) -
analysis_parameters(list[tuple[str, str | int | float | bool]]) -
stats(dict[str, DistributionStats]) -
origins(list[StatsOrigin]) -
origins_ref(str | None) -
origins_summary(OriginsSummary | None)
Biomarkers
pydantic-model
¶
Bases: BaseModel
13 standard sleep biomarkers.
TST, TIB, SE, SOL and WASO, plus REM latency, SOREMPs, the stage percentages and the sleep fragmentation index. The definitions follow the AASM scoring manual except where a description says otherwise. Each description is the metric's definition as the platform computes it, gotchas included, and is served as its help text. A metric that is undefined for a night (no sleep, no REM) is empty (None), never 0.
Sleep means an epoch scored N1, N2, N3 or REM (R&K stages 1-4 map onto them). "Sleep stage ?" (unscored), the generic "Sleep stage N" and movement time are no stage: they count toward time in bed and nothing else.
Fields:
-
tst_min(float) -
tib_min(float) -
sleep_efficiency_pct(float) -
sleep_onset_latency_min(float) -
waso_min(float | None) -
rem_latency_min(float | None) -
soremps_count(int) -
stage_percentages(StagePercentages) -
fragmentation_index(float | None)
fragmentation_index = None
pydantic-field
¶
Sleep fragmentation index: awakenings (sleep followed by wake) plus shifts to a lighter sleep stage (N3 to N2 or N1, N2 to N1, REM to N1), per hour of total sleep time. Counted between consecutive scored epochs; unscored epochs are skipped. It depends on the epoch length: shorter epochs resolve brief changes that 30-second scoring averages away, so compare it only between analyses with the same epoch length. Empty when no sleep is scored.
rem_latency_min = None
pydantic-field
¶
REM latency: minutes from sleep onset to the first REM epoch, wake in between included. Some software measures it from lights off or the start of the recording instead, which adds the sleep onset latency. Empty when no REM is scored.
sleep_efficiency_pct
pydantic-field
¶
Sleep efficiency: total sleep time as a percentage of time in bed (TST / TIB x 100). Without lights markers TIB is the whole recording, so efficiency reads lower than a lights-off-to-on figure.
sleep_onset_latency_min
pydantic-field
¶
Sleep onset latency: minutes from the start of the statistics window to the first epoch scored N1, N2, N3 or REM. When no sleep is scored it equals time in bed: the night counts as never falling asleep, and enters group means at that value.
soremps_count
pydantic-field
¶
Sleep-onset REM period: 1 when the first REM epoch begins within the SOREMP threshold (15 minutes by default) of sleep onset, otherwise 0. A per-night indicator for a nocturnal recording, not an MSLT's count across naps; summed over nights it is the number of nights with a SOREMP.
stage_percentages
pydantic-field
¶
Stage percentages
tib_min
pydantic-field
¶
Time in bed: the length of the statistics window in minutes, lights off to lights on when the study records them, otherwise the whole recording (the AASM's total recording time). Without lights markers it includes time before lights off and after lights on, which lowers sleep efficiency and lengthens sleep onset latency.
tst_min
pydantic-field
¶
Total sleep time: minutes scored N1, N2, N3 or REM inside the statistics window. Unscored epochs, the generic 'Sleep stage N' and movement time count toward no stage.
waso_min = None
pydantic-field
¶
Wake after sleep onset: minutes of wake between the first and the last epoch scored as sleep. Wake after the final awakening is not included; the AASM definition (TRT - sleep latency - TST) also counts wake until lights on, so it reads higher when the morning wake period is long. Empty when no sleep is scored.
BoxplotBoxValues
pydantic-model
¶
Bases: BaseModel
Five-number summary — raw values or normalized fractions.
Fields:
-
min(float) -
q1(float) -
median(float) -
q3(float) -
max(float)
BoxplotModel
pydantic-model
¶
Bases: BaseModel
A horizontal box-and-whisker chart: shared axis + rows.
Fields:
-
domain_min(float) -
domain_max(float) -
unit_label(str) -
value_format(Literal['duration-hours', 'decimal']) -
decimals(int) -
ticks(list[AxisTick]) -
rows(list[BoxplotRow]) -
svg(str | None)
decimals = 1
pydantic-field
¶
Decimal places for 'decimal' formatting; ignored otherwise. Matches the tick precision the producer chose.
domain_max
pydantic-field
¶
Axis maximum, in the axis unit.
domain_min
pydantic-field
¶
Axis minimum, in the axis unit.
rows
pydantic-field
¶
The rows, in display order.
svg = None
pydantic-field
¶
Server-rendered inline SVG of this chart: the one renderer behind live pages and document exports. Colors are CSS custom-property references the page resolves; elements carry stable classes, native
ticks
pydantic-field
¶
Axis ticks at nice intervals.
unit_label
pydantic-field
¶
Axis caption including the unit, e.g. 'Total duration (h)'.
value_format = 'decimal'
pydantic-field
¶
How a consumer renders one of this chart's VALUES as text (tooltips, data labels). The axis ticks are already formatted in ticks[].label; this is the same rule for the numbers between them, so a tooltip cannot contradict the axis above it. 'duration-hours' means values are hours to be shown as a duration ('1h 30m'); 'decimal' means a plain number at decimals places. Defaults to 'decimal' so a producer predating the field is read literally rather than as hours.
BoxplotPoint
pydantic-model
¶
Bases: BaseModel
One raw observation drawn as a dot, in the axis unit and on the 0…1 domain.
Fields:
fraction
pydantic-field
¶
The same value on the shared domain.
label = None
pydantic-field
¶
Which observation the dot is, for its tooltip — the study, and the subject and visit it belongs to when those are declared. None when the source draws anonymous observations.
value
pydantic-field
¶
The observation, in the axis unit.
BoxplotRow
pydantic-model
¶
Bases: BaseModel
One labelled box-and-whisker row on a shared axis.
Fields:
-
label(str) -
values(BoxplotBoxValues) -
fractions(BoxplotBoxValues) -
n(int | None) -
subjects(int | None) -
color_token(str | None) -
series_key(str | None) -
points(list[BoxplotPoint] | None)
Validators:
color_token = None
pydantic-field
¶
Brand color token NAME (e.g. 'primary-600'); consumers resolve it (CSS variable live, tokens.yaml literal in PDFs).
fractions
pydantic-field
¶
The same box mapped to 0…1 on the shared domain.
label
pydantic-field
¶
Row label (e.g. an event type).
n = None
pydantic-field
¶
Sample count behind the box.
points = None
pydantic-field
¶
Set when the row has too few observations for a box to mean anything (below the producer's configured minimum): the raw observations, drawn as dots on the shared axis instead of the box. values/fractions still carry the five-number summary of the same observations, so a consumer that ignores this field draws a (degenerate) box rather than nothing.
series_key = None
pydantic-field
¶
Stable series identifier stamped as a CSS class hook (e.g. group show/hide).
subjects = None
pydantic-field
¶
Distinct subjects behind the same observations, when the producer knows them and they can differ from n — one person recorded twice in a calendar bin is two observations and one subject. None when subjects are unknown or not meaningful for the row.
values
pydantic-field
¶
Raw five-number summary, in the axis unit (tooltips/data-*).
validate_fractions_bounded()
pydantic-validator
¶
Fractions must lie on the shared 0…1 domain.
values and fractions share a shape but not an invariant — the
bound lives here so a producer whose domain math drifts fails at the
contract, not in a renderer.
CapabilityRequestCreate
pydantic-model
¶
Bases: BaseModel
An owner's request for a capability.
Fields:
-
capability(SiteCapability) -
note(str)
note = ''
pydantic-field
¶
What the organisation wants to use it for, for the administrators.
CapabilityRequestDecision
pydantic-model
¶
CapabilityRequestOut
pydantic-model
¶
Bases: BaseModel
A request for a capability, with its decision once made.
Fields:
-
id(UUID) -
org_id(UUID) -
capability(SiteCapability) -
status(CapabilityRequestStatus) -
requested_by(UUID | None) -
requested_by_name(str | None) -
note(str) -
created_at(datetime) -
decision(CapabilityRequestDecision | None)
CapabilityRequestPage
pydantic-model
¶
Bases: BaseModel
A page of an organisation's requests for capabilities, newest first.
Fields:
-
requests(list[CapabilityRequestOut]) -
total(int)
CapabilityStatus
pydantic-model
¶
Bases: BaseModel
Where an organisation stands with one capability.
Fields:
-
capability(SiteCapability) -
state(CapabilityState) -
changed_at(datetime | None) -
request_id(UUID | None)
ChangePasswordRequest
pydantic-model
¶
Bases: BaseModel
Request for an authenticated user to change their own password.
Fields:
ChannelIdentityPatch
pydantic-model
¶
Bases: BaseModel
A person's correction of what a channel is.
Send a field to set it; send it as null to clear it; leave it out to keep it. Anything set here is recorded as coming from a person and is never overwritten by re-reading the label.
Fields:
-
laterality(ChannelLaterality | None) -
canonical_name(ChannelName | None)
Validators:
-
_says_something
ChannelIdentitySummary
pydantic-model
¶
Bases: BaseModel
What the channels behind one vocabulary entry are, across their recordings.
Fields:
-
canonical_names(list[str]) -
lateralities(list[ChannelLaterality]) -
corrected(NonNegativeInt)
canonical_names
pydantic-field
¶
Distinct canonical names ('C3-M2', 'E1') the entry's channels carry, in first-seen order; empty when none is known.
corrected = 0
pydantic-field
¶
How many of the entry's channels carry an identity a person set.
lateralities
pydantic-field
¶
Distinct sides the entry's channels record, in first-seen order; empty when unknown.
ChannelLocation
pydantic-model
¶
Bases: BaseModel
Location of a channel within a recording.
Fields:
-
channel_index(int) -
study_id(str) -
recording_id(str)
ChannelOut
pydantic-model
¶
Bases: ChannelUpdate
Represents a single channel in a recording.
Fields:
-
name(ChannelName) -
type(ChannelType) -
sample_rate(PositiveFloat | None) -
unit(PhysicalDimension | None) -
index(NonNegativeInt) -
source_name(ChannelName | None) -
canonical_name(ChannelName | None) -
electrode(str | None) -
reference(str | None) -
laterality(ChannelLaterality | None) -
identity_source(ChannelIdentitySource | None)
canonical_name = None
pydantic-field
¶
One spelling for one thing: the electrode and its reference as 'C3-M2', 'E1', 'Fpz-Cz'. Read from the label (C3-A2, C3M2 and EEG C3-M2 all give C3-M2) or set by a person. None when the label names no site.
electrode = None
pydantic-field
¶
The active site in canonical spelling ('C3', 'E1'); None when unknown.
identity_source = None
pydantic-field
¶
Where canonical_name and laterality came from: 'label' (read from the file's label) or 'user' (set by a person, never overwritten by re-reading the label). None on channels registered before identity existed.
index
pydantic-field
¶
The index of the channel in the recording. Must be a positive integer.
laterality = None
pydantic-field
¶
The body side the channel records, from the electrode (odd 10-20 sites and E1 are left, even sites and E2 right) or set by a person. None when the label does not say, or says two things.
reference = None
pydantic-field
¶
The reference site in canonical spelling ('M2', 'Cz'); None when unreferenced or unknown.
source_name = None
pydantic-field
¶
The channel's label as it appears in the source file (EDF) header. Immutable: renaming a channel changes name (the display name) but never this. Analysis containers load signals from the file by this label, so it is what dispatch passes them. None only for channels registered before the field existed.
__hash__()
¶
Hash by JSON serialisation (:func:_json_hash).
ChannelPatch
pydantic-model
¶
Bases: BaseModel
A single bulk channel edit.
Matches every channel named match_name across the project's recordings and
applies the provided fields; unset fields are left unchanged. At least one of
new_name / type / unit must be set.
Fields:
-
match_name(str) -
new_name(ChannelName | None) -
type(ChannelType | None) -
unit(PhysicalDimension | None) -
laterality(ChannelLaterality | None) -
canonical_name(ChannelName | None)
Validators:
-
_require_a_change
canonical_name = None
pydantic-field
¶
The canonical name ('C3-M2', 'E1') of these channels, if setting it; send null to clear. Recorded as set by a person.
laterality = None
pydantic-field
¶
The body side these channels record, if setting it; send null to clear. Recorded as set by a person.
match_name
pydantic-field
¶
Current channel name to match across recordings.
new_name = None
pydantic-field
¶
New channel name (rename), if changing. At most 16 characters, the EDF label length and the limit every channel read enforces — a longer name would be stored and then fail validation on every read of the recording's channels, so it is rejected here.
type = None
pydantic-field
¶
New channel type, if changing.
unit = None
pydantic-field
¶
New physical unit, if changing.
ChannelPatchResult
pydantic-model
¶
Bases: BaseModel
Result for a single channel patch.
Fields:
-
match_name(str) -
status(Literal['updated', 'error']) -
channels_updated(int) -
recordings_affected(int) -
error(BatchItemError | None)
ChannelRef
pydantic-model
¶
Bases: BaseModel
One channel of the recording as the platform resolved it for this run.
Config:
extra:forbidfrozen:True
Fields:
-
index(NonNegativeInt) -
source_name(str) -
name(str) -
type(ChannelType) -
unit(PhysicalDimension | None) -
sample_rate(PositiveFloat | None) -
slot(str | None) -
laterality(ChannelLaterality | None)
Validators:
-
_drop_legacy_derivation
index
pydantic-field
¶
The channel's ordinal in the recording file. Load by this.
laterality = None
pydantic-field
¶
Left or right, when inferred or declared.
name
pydantic-field
¶
The display name the user gave the channel.
sample_rate = None
pydantic-field
¶
Native sampling rate in Hz, if known.
slot = None
pydantic-field
¶
The label of the slot this channel fills, when the configuration declares slots.
source_name
pydantic-field
¶
The label as it appears in the file header, immutable.
type
pydantic-field
¶
The signal type as classified on the platform.
unit = None
pydantic-field
¶
Physical unit, if known.
ChannelRequirement
pydantic-model
¶
Bases: BaseModel
Base channel type & requirement spec used in e.g., ExactChannel and ChannelType.
Fields:
ChannelRequirements
pydantic-model
¶
Bases: BaseModel
Channel requirements for the analysis.
Fields:
-
sampling_rate(Range) -
quality(list[QualityRequirement])
ChannelTypeRequirement
pydantic-model
¶
Bases: ChannelRequirement
Represents a channel type (e.g., EEG or EOG) that the analysis expects.
Fields:
-
type(ChannelType) -
requirements(ChannelRequirements) -
number(Range) -
slots(list[ChannelSlot] | None)
Validators:
number
pydantic-field
¶
The minimum and maximum number of channels of the given type that the analysis expects.
slots = None
pydantic-field
¶
Optional ordered slots giving each expected channel of this type a labelled position (and optionally a required laterality). Only meaningful for fixed-count requirements: when set, 'number' must be exactly [len(slots), len(slots)]. Channels are passed to the analysis in slot order.
validate_slots()
pydantic-validator
¶
Slots imply a fixed count that matches the declared number range.
ChannelUpdate
pydantic-model
¶
Bases: BaseModel
Update model for a channel.
Fields:
-
name(ChannelName) -
type(ChannelType) -
sample_rate(PositiveFloat | None) -
unit(PhysicalDimension | None)
Choices
¶
Bases: RootModel
Represents a list of choices where all choises have the same type and are unique.
Each choice can be a string, integer, float, or boolean.
__getitem__(item)
¶
Return the choice at the given index.
__iter__()
¶
Return an iterator over the choices.
__len__()
¶
Return the number of choices.
validate_choices(values)
classmethod
¶
Validate the choices.
Validate the choises and ensure that all choices have the same type and handles specification as root or 'choices' key in the dictionary.
validate_unique_choices()
¶
Validate that all choices are unique.
ComputePoolListResponse
pydantic-model
¶
Bases: PaginatedResponse
A page of compute pools.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
items(list[ComputePoolOut])
ComputePoolOut
pydantic-model
¶
Bases: BaseModel
A compute pool as administrators see it.
Fields:
-
id(UUID7) -
name(str) -
org_id(UUID7 | None) -
lease_seconds(int) -
queue_timeout_hours(float) -
queued(NonNegativeInt) -
held(NonNegativeInt) -
runner_seen(bool) -
created_at(datetime)
held
pydantic-field
¶
Jobs the pool's runners hold now, starting or running.
lease_seconds
pydantic-field
¶
In force: the pool's own or the default.
org_id
pydantic-field
¶
None for the platform's own pool.
queue_timeout_hours
pydantic-field
¶
In force: the pool's own or the default.
queued
pydantic-field
¶
Jobs waiting for one of the pool's runners.
runner_seen = False
pydantic-field
¶
Whether one of the pool's runners is taking work (a runner's taking_work).
ConsentAcceptItem
pydantic-model
¶
Bases: BaseModel
One document acceptance in a consent submission.
Fields:
-
document(ConsentDocument) -
version(PositiveInt)
ConsentAcceptRequest
pydantic-model
¶
Bases: BaseModel
Body of POST /user/consent — accept one or more documents.
Fields:
-
accepts(list[ConsentAcceptItem])
accepts
pydantic-field
¶
The document acceptances to record.
ConsentRecord
pydantic-model
¶
Bases: BaseModel
An audited acceptance row in the append-only consent ledger.
Config:
from_attributes:True
Fields:
-
document(ConsentDocument) -
version(PositiveInt) -
accepted_at(datetime)
ContactRequestCreate
pydantic-model
¶
Bases: BaseModel
Public submission payload (landing contact form / 'request access').
Fields:
-
type(ContactRequestType) -
email(EmailStr) -
name(str | None) -
organization(str | None) -
message(str) -
website(str | None)
website = None
pydantic-field
¶
Leave empty.
ContactRequestListResponse
pydantic-model
¶
Bases: BaseModel
Paginated list of submissions for the admin feed.
Fields:
-
requests(list[ContactRequestOut]) -
total(int)
ContactRequestOut
pydantic-model
¶
Bases: BaseModel
Admin-facing view of a submission.
Fields:
-
id(UUID) -
type(ContactRequestType) -
status(ContactRequestStatus) -
email(str) -
name(str | None) -
organization(str | None) -
message(str) -
created_at(datetime) -
handled_at(datetime | None)
ContactRequestStatus
¶
Bases: str, Enum
Triage status shown in the admin feed.
ContactRequestType
¶
Bases: str, Enum
What the submission is about — drives the admin-feed filter.
collaboration = 'collaboration'
class-attribute
instance-attribute
¶
Research collaboration, or a commercial enquiry.
One topic rather than two: somebody weighing whether the platform can be used commercially should not have to declare which of the two they are before we have spoken.
ContactRequestUpdate
pydantic-model
¶
Bases: BaseModel
Admin update — currently only the triage status.
Fields:
-
status(ContactRequestStatus)
CreateStudyEventsRequest
pydantic-model
¶
CreditAdjustment
pydantic-model
¶
CreditEntry
pydantic-model
¶
Bases: BaseModel
A single append-only credit ledger entry on an organization.
Config:
from_attributes:Truefrozen:True
Fields:
-
id(UUID) -
org_id(UUID) -
bucket(CreditBucket) -
delta(int) -
reason(CreditReason) -
note(str | None) -
grant_id(UUID | None) -
expires_at(datetime | None) -
created_at(datetime)
bucket
pydantic-field
¶
Which credit pool the entry affects
created_at
pydantic-field
¶
Creation timestamp
delta
pydantic-field
¶
Signed change in credits (positive = grant, negative = charge)
expires_at = None
pydantic-field
¶
When the credits granted by this entry expire, for the retired allowance; null otherwise. A grant's expiry is on the grant.
grant_id = None
pydantic-field
¶
The grant this entry moves, for entries in the grants bucket; null otherwise.
id
pydantic-field
¶
Unique identifier of the ledger entry
note = None
pydantic-field
¶
Free-text context recorded with the entry — for admin adjustments, the reason the administrator gave. None for entries created by automatic flows or predating the field.
org_id
pydantic-field
¶
The organization this entry belongs to
reason
pydantic-field
¶
Why this entry was created
CreditEstimate
pydantic-model
¶
Bases: BaseModel
What a plan would cost, priced as its runs would be.
Config:
frozen:True
Fields:
-
rows(list[CreditEstimateRow]) -
computed_credits(NonNegativeInt) -
buffer_pct(int) -
suggested_credits(NonNegativeInt)
CreditEstimateRequest
pydantic-model
¶
Bases: BaseModel
A plan to price, with the buffer to add.
Fields:
-
plan(CreditPlan) -
buffer_pct(int)
buffer_pct = 10
pydantic-field
¶
Margin added to the computed cost, in percent.
CreditEstimateRow
pydantic-model
¶
Bases: BaseModel
The cost of one row of a plan.
Config:
frozen:True
Fields:
-
analysis_config_id(str) -
name(str) -
runs(NonNegativeInt) -
credits_per_run(NonNegativeInt) -
credits(NonNegativeInt)
CreditGrant
pydantic-model
¶
Bases: BaseModel
One grant of research credits to an organization.
Config:
from_attributes:Truefrozen:True
Fields:
-
id(UUID) -
amount(NonNegativeInt) -
remaining(NonNegativeInt) -
origin(GrantOrigin) -
expires_at(datetime | None) -
request_id(UUID | None) -
created_at(datetime)
amount
pydantic-field
¶
Credits granted.
created_at
pydantic-field
¶
When the grant was made.
expires_at = None
pydantic-field
¶
When what remains of the grant expires, extensions included; null for a grant that never expires.
id
pydantic-field
¶
Unique identifier of the grant.
origin
pydantic-field
¶
How the grant came about.
remaining
pydantic-field
¶
Credits of the grant not yet spent or expired, held ones included.
request_id = None
pydantic-field
¶
The request the grant was approved from, if any.
CreditLedgerPage
pydantic-model
¶
Bases: BaseModel
One page of an organization's credit ledger, newest first.
Config:
frozen:True
Fields:
-
entries(list[CreditEntry]) -
total(int)
CreditPackage
pydantic-model
¶
Bases: BaseModel
A purchasable credit package (one Stripe product).
Assembled by the api-server from its product->credits config plus LIVE Stripe price data, so displayed amounts always match what checkout charges. Clients must render these — never hardcode packages/prices.
Config:
frozen:True
Fields:
-
product_id(str) -
price_id(str) -
name(str) -
credits(int) -
amount_minor(int) -
currency(str)
amount_minor
pydantic-field
¶
Price in the currency's minor unit (e.g. euro cents).
credits
pydantic-field
¶
Credits granted on purchase.
currency
pydantic-field
¶
ISO currency code, e.g. "eur".
name
pydantic-field
¶
Display name from the Stripe product.
price_id
pydantic-field
¶
Stripe price id — pass to the checkout-session endpoint.
product_id
pydantic-field
¶
Stripe product id (fulfilment key).
CreditPlan
pydantic-model
¶
Bases: BaseModel
What a grant is for: studies, their length, and the analyses to run.
Config:
frozen:True
Fields:
-
studies(int) -
average_recording_hours(float) -
rows(list[CreditPlanRow])
CreditPlanRow
pydantic-model
¶
Bases: BaseModel
One analysis in a plan, and how often it runs on each study.
Config:
frozen:True
Fields:
-
analysis_config_id(str) -
runs_per_study(int)
CreditRequestDecision
pydantic-model
¶
Bases: BaseModel
An administrator's decision on a request, as the organization sees it.
Config:
frozen:True
Fields:
-
decision(Literal['approved', 'declined']) -
amount(int | None) -
expires_at(datetime | None) -
reason(CreditRequestDeclineReason | None) -
decided_at(datetime)
CreditRequestOut
pydantic-model
¶
Bases: BaseModel
A request for research credits, as its organization sees it.
Config:
frozen:True
Fields:
-
id(UUID) -
org_id(UUID) -
kind(CreditRequestKind) -
status(CreditRequestStatus) -
grant_id(UUID | None) -
requested_by(UUID | None) -
requested_by_name(str | None) -
plan(CreditPlan | None) -
computed_credits(NonNegativeInt | None) -
buffer_pct(int | None) -
requested_credits(NonNegativeInt | None) -
term_months(int) -
text(str) -
created_at(datetime) -
decision(CreditRequestDecision | None)
computed_credits = None
pydantic-field
¶
The plan's cost when it was submitted.
grant_id = None
pydantic-field
¶
The grant an extension is for.
plan = None
pydantic-field
¶
A grant request's plan; null for an extension.
requested_by = None
pydantic-field
¶
Who asked; null once their account is gone.
text
pydantic-field
¶
The purpose of a grant, or the reason for an extension.
CreditRequestPage
pydantic-model
¶
Bases: BaseModel
One page of requests, newest first.
Config:
frozen:True
Fields:
-
requests(list[CreditRequestOut]) -
total(int)
CreditedAnalysis
pydantic-model
¶
Bases: BaseModel
An analysis a report's results came from, with the credit they carry.
Fields:
-
analysis_config_id(str) -
name(str) -
credit(AnalysisCredit)
DeleteAnalysesRequest
pydantic-model
¶
Bases: _DeleteBySelectorRequest
Delete the selected analyses (e.g. clear failed runs by status).
Fields:
-
expected_count(int | None) -
selector(AnalysisSelector)
Validators:
-
_guard
DeleteRecordingsRequest
pydantic-model
¶
Bases: _DeleteBySelectorRequest
Delete the selected recordings.
Fields:
-
expected_count(int | None) -
selector(RecordingSelector)
Validators:
-
_guard
DeleteStudiesRequest
pydantic-model
¶
Bases: _DeleteBySelectorRequest
Delete the selected studies (cascade: recordings, analyses, events).
Fields:
-
expected_count(int | None) -
selector(StudySelector)
Validators:
-
_guard
DemoDatasetDescription
pydantic-model
¶
Bases: BaseModel
Description of a demo dataset (user-facing list endpoint).
Fields:
-
name(str) -
full_name(str) -
description(str) -
version(str) -
source_name(str) -
source_url(HttpUrl) -
licence_name(str) -
licence_url(HttpUrl) -
recording_count(int)
DemoDatasetRegisterRequest
pydantic-model
¶
Bases: BaseModel
Request body for POST /projects/public/demo.
Fields:
-
dataset(str) -
project_name(str)
DemoRecordingCreate
pydantic-model
¶
Bases: BaseModel
A single recording within a demo study (admin create).
Fields:
-
s3_key(str)
Validators:
DemoStudyCreate
pydantic-model
¶
Bases: StudyMetadata
A study within a demo dataset (admin create).
Inherits the optional subject-metadata fields (age, bmi, sex) so a
demo dataset can ship pre-filled demographics — registered projects
then support metadata-stratified reports out of the box. The
lights_off_clock marker seeds the study's lights-off event the
same way at registration time.
Fields:
-
age(NonNegativeInt | None) -
bmi(PositiveFloat | None) -
sex(Sex | None) -
subject_key(SubjectKey | None) -
session_index(PositiveInt | None) -
name(str) -
tags(list[TagString]) -
recordings(list[DemoRecordingCreate]) -
lights_off_clock(ClockTimeStr | None) -
lights_on_clock(ClockTimeStr | None)
lights_off_clock = None
pydantic-field
¶
Wall clock "HH:MM" or "HH:MM:SS" in the recording's own frame, resolved against the study's recordings with overnight wrap — the same clock spelling as the lights import.
lights_on_clock = None
pydantic-field
¶
Same spelling and frame as lights_off_clock. Set only when the source data records it.
DistributionStats
pydantic-model
¶
Bases: BaseModel
Distribution statistics for a single metric across multiple observations.
Fields:
-
support(int) -
support_non_zero(int) -
mean(float) -
median(float) -
min(float) -
max(float) -
std(float) -
iqr(float) -
p5(float) -
p25(float) -
p75(float) -
p95(float)
iqr
pydantic-field
¶
Interquartile range (p75 - p25)
max
pydantic-field
¶
Maximum value
mean
pydantic-field
¶
Arithmetic mean
median
pydantic-field
¶
Median (50th percentile)
min
pydantic-field
¶
Minimum value
p25
pydantic-field
¶
25th percentile
p5
pydantic-field
¶
5th percentile
p75
pydantic-field
¶
75th percentile
p95
pydantic-field
¶
95th percentile
std
pydantic-field
¶
Standard deviation
support
pydantic-field
¶
Number of observations
support_non_zero
pydantic-field
¶
Number of non-zero observations
DockerSettings
pydantic-model
¶
Bases: BaseModel
Docker settings for building the analysis image.
Fields:
-
image(str) -
tag(str) -
digest(str | None) -
base_command(str) -
relative_build_path(str | Path) -
remote_https_url(HttpUrl | None) -
ssh_key(str | None)
Validators:
base_command = ''
pydantic-field
¶
The base command without parameters to run the analysis in the Docker container. Defaults to an empty string assuming an entry is set in the Dockerfile.
digest = None
pydantic-field
¶
Optional content digest of the Docker image, e.g. 'sha256:abc…'. When set, the image reference used to run the analysis pins these exact bytes ('image:tag@sha256:…'): the tag remains the human-readable version label, while the digest is what the container runtime resolves — a re-pushed tag can no longer change what runs. When unset, the tag alone selects the image.
full_image_name
property
¶
Return the tag form of the image name ('image:tag').
Deliberately digest-free: registry APIs and humans address images by
tag. Use :attr:pinned_image_reference for the reference a container
runtime should run.
image
pydantic-field
¶
The name of the Docker image.
pinned_image_reference
property
¶
Return the reference to run, digest-pinned when a digest is declared.
'image:tag@digest' with a digest, else 'image:tag'. 'NAME:TAG@DIGEST' is valid for every mainstream runtime; the runtime resolves the digest and the tag rides along as documentation.
relative_build_path = '.'
pydantic-field
¶
The relative path to the Docker build context. This path is relative to the root of the repository. Default is the root of the repository.
remote_https_url = None
pydantic-field
¶
The HTTPS URL of the remote repository. This URL is used to clone the repository and build the Docker image. If the repository is private, the an SSH equivalent URL is used instead for which a valid SSH key must be registered with the ssh-agent.
ssh_key = None
pydantic-field
¶
The SSH key to use to clone the repository if the repository is private. The SSH key must be a valid private key in the OpenSSH format. If the repository is public, this field can be left empty.
ssh_url
property
¶
Return the SSH URL of the source repository, or None when none is declared.
tag
pydantic-field
¶
The tag of the Docker image, e.g. 'latest' or '1.0'.
validate_remote_https_url(v)
pydantic-validator
¶
Validate the remote, when one is declared, as a HTTPS URL.
The field is optional; an explicit null (which is what a stored or
author-facing configuration without a source repository carries) passes
through untouched.
DockerVolumeDict
pydantic-model
¶
EditStudyTagsRequest
pydantic-model
¶
Bases: BaseModel
Edit tags across the selected studies.
Two forms, mutually exclusive: incremental (add/remove, applied
where missing/present) or replace — set every selected study's tags
to exactly this list. replace: [] is the deliberate clear-all form.
Fields:
-
selector(StudySelector) -
add(list[str]) -
remove(list[str]) -
replace(list[str] | None) -
expected_count(int | None)
Validators:
-
_guard
add
pydantic-field
¶
Tags to add where missing.
expected_count = None
pydantic-field
¶
Required for filter/all selectors: the resolved count the caller saw. The server re-resolves and rejects on a mismatch.
remove
pydantic-field
¶
Tags to remove where present.
replace = None
pydantic-field
¶
Set the selected studies' tags to exactly this list (an empty list clears all tags). Mutually exclusive with add/remove.
EditStudyTagsResponse
pydantic-model
¶
EnrolmentTokenOut
pydantic-model
¶
Bases: BaseModel
A new enrolment token. The token is shown here once and never again.
With it come the storage addresses the runner reaches, which the
installer takes each with --storage-origin, and the runner image to
install. The platform's root key is not among them: the runner's release
carries it and the install pins it, as a key served here could be changed
by a proxy between the site and the platform, which pinning guards
against.
Fields:
-
pool_id(UUID7) -
token(str) -
expires_at(datetime) -
storage_origins(list[str]) -
runner_image(str | None)
storage_origins
pydantic-field
¶
The storage the runner downloads its jobs' inputs from and uploads their results to, as origins (scheme, host and port). Empty from a server that predates it.
ErrorResponse
pydantic-model
¶
Bases: BaseModel
Structured error body returned by the API for handled errors.
Fields:
code
pydantic-field
¶
Stable machine-readable error code; branch on this, not on the detail text.
context = None
pydantic-field
¶
Optional error-specific structured fields. Values may be scalars (e.g. usage_limit_exceeded: resource, limit, current) or nested JSON (e.g. consent_required: pending = [{document, current_version}, ...]). Backward-compatible: scalar contexts are unchanged.
detail
pydantic-field
¶
Human-readable description of the error.
Event
pydantic-model
¶
Bases: BaseModel
Event data type.
start_time_ms: Start time of the event in milliseconds relative to the recording start. end_time_ms: End time of the event in milliseconds relative to the recording start. Must be greater than or equal to start_time. If equal, the event is considered instantaneous. label: Label of the event (e.g., "Sleep stage W"). confidence: Optional confidence in [0, 1] of the event. value: Optional value associated to the event. channels: List of channels where the event was detected. If empty, the event should be considered global.
Fields:
-
start_time_ms(NonNegativeInt) -
end_time_ms(NonNegativeInt) -
label(EventLabel) -
probability(float | None) -
value(float | None) -
channels(list[str])
Validators:
EventBlock
pydantic-model
¶
Bases: BaseModel
N consecutive equal-duration event slots beginning at an exact origin.
Slot i spans [origin_ms + i * period_ms, origin_ms + (i + 1) *
period_ms). A period_ms of 0 marks instantaneous events, where every
slot collapses onto origin_ms.
Fields:
-
origin_ms(NonNegativeInt) -
period_ms(NonNegativeInt) -
labels(list[EventLabel]) -
probability(list[float | None] | None) -
value(list[float | None] | None) -
channels(list[str])
Validators:
channels
pydantic-field
¶
List of channels the block's events were detected on, shared by every slot. If empty, the events should be considered global.
end_ms
property
¶
Return the end of the final slot.
labels
pydantic-field
¶
One label per slot. Labels may vary from slot to slot.
origin_ms
pydantic-field
¶
Start time of the first slot in milliseconds relative to the recording start.
period_ms
pydantic-field
¶
Duration of every slot in milliseconds. 0 marks instantaneous events.
probability = None
pydantic-field
¶
Optional probability/confidence in [0, 1] per slot. None when no slot in the block carries a probability; individual entries may still be None.
slot_count
property
¶
Return the number of slots.
value = None
pydantic-field
¶
Optional value per slot. None when no slot in the block carries a value; individual entries may still be None.
validate_parallel_arrays()
pydantic-validator
¶
Validate that the optional per-slot arrays match the slot count.
EventBlocksDocument
pydantic-model
¶
Bases: BaseModel
The events output document an analysis container writes.
A versioned envelope around a list of blocks. Block order is meaningful and must be preserved: it is the canonical order the encoding produces, and consumers rely on it being stable.
Fields:
-
format_version(Literal[1]) -
blocks(list[EventBlock]) -
device(dict[str, Any] | None)
blocks
pydantic-field
¶
The event blocks, in canonical order.
device = None
pydantic-field
¶
Optional provenance recorded by the producing analysis: software and model identity, versions, an input content hash, and any further descriptive fields the producer chooses. Opaque to the platform — carried with the document, never interpreted.
event_count
property
¶
Return the total number of events across all blocks.
format_version = 1
pydantic-field
¶
Version of the events document format.
EventListResponse
pydantic-model
¶
EventStats
pydantic-model
¶
Bases: BaseModel
A model for statistics computed over a list of events of similar type.
Fields:
-
event_type(EventType) -
stats(dict[str, float | int])
EventType
pydantic-model
¶
Bases: BaseModel
Model for the type of an event.
Represents an event label with a type, where types are e.g., 'instant-probabilistic' or 'interval-discrete'.
Fields:
-
label(EventLabel) -
channels(list[str]) -
instant(bool) -
probabilistic(bool) -
valued(bool)
channels
pydantic-field
¶
List of channels where the event was detected. If empty, the event should be considered global.
instant = False
pydantic-field
¶
Whether the event is instantaneous or not.
label
pydantic-field
¶
The label of the event, e.g., 'sleep-stage'.
probabilistic = False
pydantic-field
¶
Whether the event has an associated 'probability' value in [0, 1] or not.
valued = False
pydantic-field
¶
Whether the event has an associated 'value' or not.
infer_from_concrete_event(event)
classmethod
¶
Infer the type of the event from a concrete event.
EventsExportParams
pydantic-model
¶
Bases: BaseModel
Cohort selection for an events-zip export.
The archive bundles the events file of every completed analysis in the
cohort, one file per analysis, each byte-identical to the single
analysis download. The cohort is the project, narrowed by whichever
selectors are given: study_ids keeps the named studies,
analysis_ids keeps the named analyses; both together keep the
analyses that satisfy both. Ids outside the project are ignored.
Fields:
-
study_ids(list[UUID] | None) -
analysis_ids(list[UUID] | None)
EventsFilter
pydantic-model
¶
Bases: SignalWindow
Filter parameters for querying events.
This is a data container for filter criteria. Actual filtering is performed at the database layer for performance. Two independent filters are applied:
-
Time window filter: Restricts events to a time range. Events outside the window are excluded. Controlled by window_start_time_ms, window_end_time_ms, and window_mode. Most modes only select whole events; CLIP additionally truncates the ones that straddle a boundary.
-
Label filter: Filters by event labels/types. Controlled by labels and match_mode:
- INCLUDE mode: Only events matching the labels are returned.
- EXCLUDE mode: Events matching the labels are removed.
Both filters are independent - the time window acts as a "crop" operation, while match_mode only affects label filtering.
Fields:
-
window_start_time_ms(NonNegativeInt | None) -
window_end_time_ms(NonNegativeInt | None) -
labels(list[EventLabel] | None) -
match_mode(MatchModes) -
window_mode(WindowFilterModes)
Validators:
labels = None
pydantic-field
¶
Filter events by labels. If set, only events with labels in this list are considered for inclusion/exclusion based on match_mode. If None, label filtering is disabled.
match_mode = MatchModes.INCLUDE
pydantic-field
¶
Controls how label filtering works. INCLUDE: only include events matching the labels list. EXCLUDE: exclude events matching the labels list. Note: This only affects label filtering, not window filtering.
window_mode = WindowFilterModes.START
pydantic-field
¶
Controls how the time window filter matches events. START: match events starting within the window. END: match events ending within the window. CONTAIN: match events fully contained in the window. CLIP: match events overlapping the window and truncate them to it, so returned durations sum to at most the window's width. Events outside the window are always excluded regardless of match_mode.
validate_window_mode()
pydantic-validator
¶
Validate that required window times are provided for the selected window mode.
EventsOutputLimits
pydantic-model
¶
Bases: BaseModel
Bounds on an events document read from an analysis container.
The document is written by the container, so its size is chosen by whoever built the image. Every reader applies these bounds before the content is decoded or expanded: a small gzip payload can decompress to gigabytes, and a small block document can describe millions of events. The defaults leave ample room for a full night scored every second with every class's probability, which is well under a million events.
Config:
extra:forbidfrozen:True
Fields:
-
max_file_bytes(int) -
max_decompressed_bytes(int) -
max_events(int)
max_decompressed_bytes = 128 * 1024 * 1024
pydantic-field
¶
Largest document accepted after gzip decompression.
max_events = 2000000
pydantic-field
¶
Most events a document may describe across its blocks.
max_file_bytes = 64 * 1024 * 1024
pydantic-field
¶
Largest document accepted as stored, compressed or not.
ExactChannelRequirement
pydantic-model
¶
Bases: ChannelRequirement
An exact channel (a montage such as C3-M2) that the analysis expects.
Matched by identity, not by string: the platform reads every recording
label into a canonical form, so C3-M2 here matches C3-A2, C3M2
and EEG C3-M2 in a file. any_of lists acceptable alternatives in
order of preference. A montage the file does not carry is prepared before
upload; the platform does not derive channels.
Fields:
-
type(ChannelType) -
requirements(ChannelRequirements) -
name(ChannelName) -
any_of(list[ChannelName])
Validators:
-
_alternatives_are_distinct
any_of
pydantic-field
¶
Alternatives accepted in place of name, in order of preference; the first one present in the recording is used, e.g. ['C4-M1'] for a requirement named 'C3-M2'.
name
pydantic-field
¶
The canonical name of the channel the analysis expects, e.g. 'C3-M2'. Matched against each recording channel's canonical identity.
ExtensionRequestCreate
pydantic-model
¶
FileInput
pydantic-model
¶
Bases: BaseModel
A file the manifest points at inside the container.
Config:
extra:forbidfrozen:True
Fields:
-
path(str)
Validators:
-
_inside_the_container→path
GrantRequestCreate
pydantic-model
¶
Bases: BaseModel
A request for a new research grant.
Fields:
-
plan(CreditPlan) -
buffer_pct(int) -
requested_credits(int) -
term_months(int) -
purpose(str)
HeaderRule
pydantic-model
¶
Bases: BaseModel
The pseudonymisation rule a runner applies to a recording's EDF header.
The runner hashes the recording as fetched, then rewrites the header of
its local copy before the container starts: the identification fields are
blanked, and the start date is replaced by EDF+'s unknown date unless
keep_dates. The container reads only that copy.
Config:
extra:forbidfrozen:True
Fields:
-
keep_dates(bool)
keep_dates
pydantic-field
¶
Keep the start date, or replace it with EDF+'s unknown date.
HeartbeatLease
pydantic-model
¶
Bases: BaseModel
One held lease, as its runner reports it.
Config:
extra:forbid
Fields:
-
lease_id(UUID7) -
attempt(int) -
phase(LeasePhase)
HeartbeatRequest
pydantic-model
¶
Bases: BaseModel
A runner reports the leases it holds.
Config:
extra:forbid
Fields:
-
leases(list[HeartbeatLease])
HeartbeatResponse
pydantic-model
¶
Bases: BaseModel
An answer for each reported lease.
Fields:
-
answers(list[LeaseAnswer]) -
lease_seconds(int)
HistoryResponse
pydantic-model
¶
Bases: PaginatedResponse
Response model for the analysis history endpoint.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
history(list[AnalysisOut]) -
count(NonNegativeInt)
count
pydantic-field
¶
Total analyses matching the query. Deprecated duplicate of total; read total instead.
HypnogramModel
pydantic-model
¶
Bases: BaseModel
A staging hypnogram: stage lanes + step segments over the recording.
Fields:
-
duration_ms(int) -
lanes(list[str]) -
segments(list[HypnogramSegment]) -
ticks(list[AxisTick]) -
lights_off_fraction(float | None) -
lights_on_fraction(float | None) -
svg(str | None)
duration_ms
pydantic-field
¶
Recording length the fractions map over.
lanes
pydantic-field
¶
Stage labels, top lane first.
segments
pydantic-field
¶
Runs in time order.
svg = None
pydantic-field
¶
Server-rendered inline SVG of this hypnogram — same contract as BoxplotModel.svg: CSS-variable colors, stable classes,
ticks
pydantic-field
¶
Time-axis ticks (value in ms).
HypnogramSegment
pydantic-model
¶
Bases: BaseModel
One constant-stage run of the hypnogram step curve.
Fields:
Identification
pydantic-model
¶
Bases: BaseModel
Analysis identification information.
Config:
frozen:True
Fields:
-
name(AnalysisConfigNameStr) -
id(AnalysisConfigIdStr) -
family(str | None)
Validators:
-
_derive_id_from_name
family = None
pydantic-field
¶
The family the analysis belongs to: the versions and variants of one method share it (e.g. 'U-Sleep'), so clients can group and filter by it. Unset, the analysis is a family of its own, named by its name.
family_name
property
¶
The family to group the analysis under: its own name when it sets none.
id
pydantic-field
¶
The machine-readable identifier: one lineage of comparable results, never changed once registered. Derived from the name when omitted (lower case, spaces as hyphens); set it explicitly only to keep an existing id when the name changes.
InputCoverage
pydantic-model
¶
Bases: BaseModel
How many of a step's recordings have one input its analysis declares.
Fields:
-
name(str) -
kind(Literal['channel_type', 'channel', 'subject_value']) -
required(bool) -
present(NonNegativeInt)
name
pydantic-field
¶
As the configuration declares it: a channel type (EEG), an exact channel (C3-M2), or a subject value (age).
present
pydantic-field
¶
Recordings that have it: at least the declared minimum of channels, or a recorded value.
required
pydantic-field
¶
Whether a recording without it is refused. An optional input is used when the recording has it.
Inputs
pydantic-model
¶
Bases: BaseModel
Represents the inputs of the analysis.
Fields:
-
recording(RecordingInput | None) -
events(list[EventType] | None) -
metadata(list[MetadataType] | None)
Validators:
events = None
pydantic-field
¶
The list of typed event that the analysis requires in the input.
metadata = None
pydantic-field
¶
Optional list of metadata type input for the analysis, e.g., 'age'.Can be None if the analysis does not require metadata.
recording
pydantic-field
¶
The recording input for the analysis. Can be None if the analysis does not require a recording input.
validate_at_least_one_input(data)
pydantic-validator
¶
Validate that at least one of 'recording', 'events' and 'metadata' is set.
InvitationCreate
pydantic-model
¶
Bases: BaseModel
Invite an email address into a team organization.
The invitee receives a link that is valid for a limited time and can be accepted once, by an account whose verified email matches the address.
Fields:
-
email(EmailStr) -
role(MembershipRole)
Validators:
InvitationOut
pydantic-model
¶
Bases: BaseModel
An invitation as listed to the organization's admins. Never carries the token.
Config:
frozen:True
Fields:
-
id(UUID) -
org_id(UUID) -
email(str) -
role(MembershipRole) -
invited_by_name(str | None) -
status(InvitationStatus) -
created_at(datetime) -
expires_at(datetime)
created_at
pydantic-field
¶
When it was sent.
email
pydantic-field
¶
The invited address.
expires_at
pydantic-field
¶
When it stops being acceptable.
id
pydantic-field
¶
Unique identifier of the invitation.
invited_by_name = None
pydantic-field
¶
Display name of the member who sent it, if set.
org_id
pydantic-field
¶
The organization the invitation is for.
role
pydantic-field
¶
The role the invitee joins with.
status
pydantic-field
¶
Where the invitation stands.
InvitationPreview
pydantic-model
¶
Bases: BaseModel
What an invitation link is for, shown before accepting it.
Returned to whoever holds the link; it names the organization, the inviter and the invited address so the holder can sign in with the right account or register it.
Config:
frozen:True
Fields:
-
organization_name(str) -
inviter_name(str | None) -
email(str) -
role(MembershipRole) -
expires_at(datetime)
email
pydantic-field
¶
The invited address.
expires_at
pydantic-field
¶
When the link stops working.
inviter_name = None
pydantic-field
¶
Display name of the member who sent it, if set.
organization_name
pydantic-field
¶
The organization inviting.
role
pydantic-field
¶
The role the invitee joins with.
InvitationToken
pydantic-model
¶
JobClaim
pydantic-model
¶
Bases: BaseModel
The resources a leased job may use, as the runner enforces them.
Config:
extra:forbid
Fields:
-
cores(float) -
memory_mib(int) -
wall_clock_seconds(int) -
gpus(int)
memory_mib
pydantic-field
¶
A hard limit with no swap. Never 0, which a container runtime reads as no limit.
KeyCertificate
pydantic-model
¶
Bases: BaseModel
A root key's statement that public_key signs as kid until not_after.
Config:
frozen:Trueextra:forbid
Fields:
-
kid(str) -
serial(int) -
public_key(str) -
not_after(AwareDatetime) -
signature(str)
Lease
pydantic-model
¶
Bases: BaseModel
One job a runner now holds, until expires_at unless heartbeated.
Exactly the field of its kind is set; the platform leaves the others out of the answer, so a runner that does not know a kind never meets its field.
Fields:
-
lease_id(UUID7) -
attempt(int) -
kind(LeaseKind) -
expires_at(datetime) -
analysis(LeasedAnalysis | None) -
ingest(LeasedIngest | None) -
delete(LeasedDelete | None)
Validators:
-
_its_job_alone
attempt
pydantic-field
¶
Sent back with every report on it.
LeaseAnswer
pydantic-model
¶
Bases: BaseModel
What to do with one reported lease.
Fields:
-
lease_id(UUID7) -
answer(HeartbeatAnswer)
LeaseFile
pydantic-model
¶
Bases: BaseModel
A file the container reads or writes, and the URL that moves it.
Fields:
-
container_path(str) -
url(str) -
header_rule(HeaderRule | None)
header_rule = None
pydantic-field
¶
On the recording among a job's inputs: the rule its local copy's header is rewritten by before the container reads it. Absent on every other file.
url
pydantic-field
¶
A presigned URL: GET for an input, PUT for an output. Used exactly as given: normalising it would break its signature.
LeaseRequest
pydantic-model
¶
Bases: BaseModel
A runner asks for work that fits its free room and its local policy.
Config:
extra:forbid
Fields:
-
free(RunnerCapacity) -
capacity(RunnerCapacity | None) -
largest_job(RunnerCapacity) -
kinds(list[LeaseKind]) -
wait_seconds(int)
capacity = None
pydantic-field
¶
The runner's total room, as its configuration offers it now. The platform keeps it as the runner's capacity, so a change made after enrolment reaches the platform with the runner's next request for work. Unset, the capacity last reported, or the one the runner enrolled with, stands.
kinds
pydantic-field
¶
The kinds of job the runner takes.
largest_job
pydantic-field
¶
The largest single job the runner's local policy allows.
wait_seconds = 30
pydantic-field
¶
How long the platform may hold the request open for work.
LeaseResponse
pydantic-model
¶
Bases: BaseModel
The jobs leased to the runner; empty when none came in time.
Fields:
-
leases(list[Lease]) -
lease_seconds(int)
lease_seconds
pydantic-field
¶
How long a lease lasts without a heartbeat. The runner reports every :func:heartbeat_seconds of it.
LeaseResultRequest
pydantic-model
¶
Bases: BaseModel
How a leased job ended.
Config:
extra:forbid
Fields:
-
attempt(int) -
ended(JobEnd) -
exit_code(int | None) -
return_reason(ReturnReason | None) -
stdout_tail(str | None) -
stderr_tail(str | None) -
outputs(list[UploadedFile]) -
attestations(ResultAttestations | None) -
peak_memory_mib(int | None) -
duration_seconds(float | None) -
header_changed(bool | None)
Validators:
-
_one_way_to_end
exit_code = None
pydantic-field
¶
Set exactly when the job ended exited.
header_changed = None
pydantic-field
¶
For an ingest that fetched its recording: whether the header rule changed the copy's header. The platform refuses an uploaded copy the rule changed.
peak_memory_mib = None
pydantic-field
¶
The container's peak memory, as it recorded it on exit.
return_reason = None
pydantic-field
¶
Set exactly when the job ended returned.
succeeded
property
¶
Whether the container exited 0 by itself.
LeaseResultResponse
pydantic-model
¶
LeasedAnalysis
pydantic-model
¶
Bases: BaseModel
Everything a runner needs to run one analysis, and nothing more.
Fields:
-
analysis_id(UUID7) -
image(str) -
manifest(AnalysisManifest) -
manifest_path(str) -
inputs(list[LeaseFile]) -
outputs(list[LeaseFile]) -
claim(JobClaim)
LegalDocument
pydantic-model
¶
Bases: LegalDocumentShort
Response model for terms and conditions, privacy policies, and licences.
Fields:
-
category(Literal['terms-and-conditions', 'privacy-policy', 'licence', 'site-agreement']) -
type(Literal['standard', 'non-commercial', 'commercial']) -
version(PositiveInt) -
name(str) -
valid_from(datetime) -
valid_until(datetime | None) -
summary(str | None) -
content(str)
content
pydantic-field
¶
The content of the document.
LegalDocumentIdentifier
pydantic-model
¶
Bases: BaseModel
A model to uniquely identify a legal document.
Fields:
-
category(Literal['terms-and-conditions', 'privacy-policy', 'licence', 'site-agreement']) -
type(Literal['standard', 'non-commercial', 'commercial']) -
version(PositiveInt)
category
pydantic-field
¶
The category of the document. The site agreement is what an organisation's owner accepts before it may run analyses or keep recordings on its own hardware.
type
pydantic-field
¶
The type of the document within its category: 'standard' for terms, privacy and site documents, 'non-commercial' or 'commercial' for licences.
version
pydantic-field
¶
The version of the document as a posive integer.
LegalDocumentShort
pydantic-model
¶
Bases: LegalDocumentIdentifier
Response model for legal documents.
Does not contain the content itself. See LegalDocument for the full response.
Fields:
-
category(Literal['terms-and-conditions', 'privacy-policy', 'licence', 'site-agreement']) -
type(Literal['standard', 'non-commercial', 'commercial']) -
version(PositiveInt) -
name(str) -
valid_from(datetime) -
valid_until(datetime | None) -
summary(str | None)
Licence
pydantic-model
¶
Bases: LegalDocumentIdentifier
Licence information for an analysis.
Similar to LegalDocumentIdentifier but with type fixed to 'licence' and version defaulting to 'latest' version.
Fields:
LightsInstant
pydantic-model
¶
Bases: BaseModel
One lights marker in exactly one spelling.
clock is primary: wall clock in the recording's own frame, resolved
per study with overnight wrap (a 23:30 recording start with
lights_off 00:15 lands the next calendar day). datetime is an
absolute wall-clock datetime in the same frame; elapsed_ms counts
from recording start.
Fields:
-
clock(ClockTimeStr | None) -
datetime(str | None) -
elapsed_ms(NonNegativeInt | None)
Validators:
-
_exactly_one_spelling
clock = None
pydantic-field
¶
Wall clock "HH:MM" or "HH:MM:SS". Only resolvable while the study's recording span is ≤ 24 h; longer spans error per item (use datetime or elapsed_ms).
datetime = None
pydantic-field
¶
ISO datetime in the recording's wall-clock frame (any timezone suffix is ignored; times are read in the recording's own wall-clock frame).
LineChartModel
pydantic-model
¶
Bases: BaseModel
Lines over a shared value axis and a shared, ordered time axis.
Fields:
-
domain_min(float) -
domain_max(float) -
unit_label(str) -
value_format(Literal['duration-hours', 'decimal']) -
decimals(int) -
ticks(list[AxisTick]) -
x_ticks(list[AxisTick]) -
series(list[LineSeries]) -
svg(str | None)
decimals = 1
pydantic-field
¶
Decimal places for 'decimal' formatting.
domain_max
pydantic-field
¶
Value-axis maximum, in the axis unit.
domain_min
pydantic-field
¶
Value-axis minimum, in the axis unit.
series
pydantic-field
¶
The lines, in legend order.
svg = None
pydantic-field
¶
Server-rendered inline SVG of this chart, the same renderer behind live pages and document exports. None for producers predating the field.
ticks
pydantic-field
¶
Value-axis ticks at nice intervals.
unit_label
pydantic-field
¶
Value-axis caption including the unit, e.g. 'TST (min)'.
value_format = 'decimal'
pydantic-field
¶
How a consumer renders one of this chart's VALUES as text, the same rule the axis ticks already follow.
x_ticks
pydantic-field
¶
Time-axis ticks: one per bin, in order, labelled as the bins are. value is the bin's index.
LinePoint
pydantic-model
¶
Bases: BaseModel
One observation on a line: where it sits on both axes.
Fields:
-
value(float) -
fraction(float) -
x_fraction(float) -
label(str)
LineSeries
pydantic-model
¶
Bases: BaseModel
One line: a subject's observations in time order.
Fields:
color_token = None
pydantic-field
¶
Brand color token NAME the line uses; consumers resolve it (CSS variable live, tokens.yaml literal in PDFs).
dash = None
pydantic-field
¶
SVG dash pattern, e.g. '5 3'. Set when lines share a colour because colour carries something else — a group, say — so the stroke still tells them apart on paper, where no tooltip can. None draws a solid line.
key
pydantic-field
¶
Stable series identity within the chart (a CSS class hook and a client selection key), not display text.
label
pydantic-field
¶
Legend text, e.g. the subject's key.
points
pydantic-field
¶
The observations in time order. A bin the series has no study in carries no point, so the line breaks rather than interpolating a night that was never recorded.
ListedPublication
pydantic-model
¶
Bases: BaseModel
One publication on the listing.
Fields:
-
publication(Publication) -
authorship(Literal['yousleep', 'developer', 'independent']) -
analyses(list[PublicationAnalysis]) -
families(list[str]) -
note(str | None)
analyses
pydantic-field
¶
The analyses whose evidence includes it: those it evaluated as published, or describes. Empty when it is listed for another reason, which note gives.
authorship
pydantic-field
¶
Who wrote it, for the listing as a whole: 'yousleep' for work by the youSleep team, 'developer' for work by the developer of an analysis youSleep packages, 'independent' for anyone else's. A publication's own by is relative to one analysis's developer.
families
pydantic-field
¶
The analysis families it concerns: those of the analyses it is evidence for, or those it is about when it is evidence for none.
note = None
pydantic-field
¶
How the publication relates to the analyses when it belongs to none of them, e.g. that it retrained the architecture rather than evaluating the published model.
publication
pydantic-field
¶
The publication.
LongitudinalBin
pydantic-model
¶
Bases: BaseModel
One time bin: a row slot every chart in the section shares.
Fields:
-
key(str) -
label(str) -
n(int) -
subject_count(int | None)
key
pydantic-field
¶
Stable bin identity within the section, e.g. '3' for night 3 or '2026-W12' for a calendar week.
label
pydantic-field
¶
Row label as drawn, e.g. 'Night 3' or 'Mar 2026'.
n
pydantic-field
¶
Studies observed in this bin, across every group.
subject_count = None
pydantic-field
¶
Distinct subjects behind n when any study in scope carries a subject key; None otherwise. Drawn beside n so attrition is readable in the figure.
LongitudinalChart
pydantic-model
¶
Bases: BaseModel
One metric from one analysis configuration, across the bins.
A metric several configurations produced yields one chart per configuration — the same shape the flat report gives a metric several configurations produced. A picker still lists the metric once; the charts under it are that metric from each source, each headed by the configuration that produced it, so no reader has to tell four pipelines apart inside one crowded figure.
Fields:
-
key(str) -
metric(str) -
label(str) -
unit_label(str | None) -
analysis_config_id(str) -
analysis_parameters(list[tuple[str, str | int | float | bool]]) -
config_label(str) -
research_parameters(list[str] | None) -
series(list[LongitudinalSeriesInfo]) -
chart(BoxplotModel) -
comparisons(list[LongitudinalComparison])
analysis_config_id
pydantic-field
¶
The analysis configuration whose output this chart draws.
analysis_parameters
pydantic-field
¶
The analysis parameters used in computation.
chart
pydantic-field
¶
The geometry: rows are bins in time order, one row per (bin, series), labelled with the bin and keyed with the series. A row below the section's min_box_n carries points instead of a box, and each row carries the studies and subjects behind it.
comparisons
pydantic-field
¶
Descriptive comparisons between the chart's groups, per bin: each group against the first in legend order. Empty when the chart is not split, or where a bin holds too few observations on either side for a comparison to describe anything.
config_label
pydantic-field
¶
Display name of the configuration, as the chart's heading — the parameters ride it when one configuration ran with more than one parameterisation.
key
pydantic-field
¶
Stable chart identity within the section (safe as a render/caching key), one per metric and configuration.
label
pydantic-field
¶
Display name of the metric, e.g. 'N1 (%)'.
metric
pydantic-field
¶
The metric drawn: a biomarker key or a stats dict key such as 'total-duration-ms'. Charts sharing a metric are the same quantity from different configurations.
research_parameters = None
pydantic-field
¶
Parameters outside the validated regime (exploratory output), same semantics as StatsOrigin.research_parameters.
series
pydantic-field
¶
The groups the chart's rows are split into, in legend order. Empty when the chart is not split — its rows then carry no series key, exactly as an ungrouped flat chart's rows do.
unit_label = None
pydantic-field
¶
Display unit, e.g. 'min' or '%'.
LongitudinalComparison
pydantic-model
¶
Bases: BaseModel
How one group's values in one bin sit against the reference group's.
Descriptive only: a difference and an effect size, never a test, a p-value, or a verdict. Two groups measured in the same bin differ by some amount and overlap to some degree; what that means for a decision is the reader's to judge, with the study design in front of them.
Fields:
-
bin_key(str) -
bin_label(str) -
reference(str) -
group(str) -
reference_n(int) -
group_n(int) -
median_difference(float) -
cliffs_delta(float)
bin_key
pydantic-field
¶
The bin compared, keyed as the section's bins are.
bin_label
pydantic-field
¶
Display label of that bin.
cliffs_delta
pydantic-field
¶
Cliff's delta over all pairs: how often a value from the group exceeds one from the reference, minus how often it falls below. 0 when the groups overlap evenly, 1 when every value is higher, -1 when every value is lower. Distribution-free, and no more than a description of the overlap.
group
pydantic-field
¶
The group being compared.
group_n
pydantic-field
¶
Observations behind the compared group in this bin.
median_difference
pydantic-field
¶
Group median minus reference median, in the chart's drawn unit — the axis unit, so it reads directly off the figure.
reference
pydantic-field
¶
The group compared AGAINST — the first in legend order, the same one for every bin of the chart.
reference_n
pydantic-field
¶
Observations behind the reference group in this bin.
LongitudinalExclusion
pydantic-model
¶
Bases: BaseModel
A subject or study the requested bins could not place, and why.
Fields:
-
subject_key(str | None) -
study_name(str | None) -
reason(str)
Validators:
-
_names_something
reason
pydantic-field
¶
Human-readable reason, ready to print.
study_name = None
pydantic-field
¶
The excluded study, when a single study is left out: a keyless study under declared positions, or a study whose recording carries no known start date under calendar bins.
subject_key = None
pydantic-field
¶
The excluded subject, when a whole subject is left out: one that declares no session index while others do, one that declares it on only some of its studies, or one whose recording order cannot be derived.
LongitudinalSection
pydantic-model
¶
Bases: BaseModel
The longitudinal half of a project report.
Fields:
-
basis(LongitudinalBasis) -
regime(LongitudinalRegime | None) -
granularity(CalendarGranularity | None) -
min_box_n(int) -
bins(list[LongitudinalBin]) -
charts(list[LongitudinalChart]) -
excluded(list[LongitudinalExclusion]) -
subject_view(LongitudinalSubjectView | None)
basis
pydantic-field
¶
What the bins are.
bins
pydantic-field
¶
The bins in time order; every chart's rows follow them.
charts
pydantic-field
¶
One chart per rendered metric and analysis configuration, in display order: metrics in their display order, and within a metric the configurations in the order the report lists them.
excluded
pydantic-field
¶
Subjects and studies the bins could not place — named explicitly, mirrored in the report's warnings.
granularity = None
pydantic-field
¶
On a calendar section: the span of one bin. None on a session-index section.
min_box_n
pydantic-field
¶
A row with fewer observations than this is drawn as points, not a box — configured on the server.
regime = None
pydantic-field
¶
On a session-index section: 'declared' when any subject in scope declares a session index (only fully declared subjects are drawn), 'derived' otherwise (positions follow recording order; a keyless study is its own single-session subject in bin 1). None on a calendar section.
subject_view = None
pydantic-field
¶
Set when the request selected subjects: the same metrics and configurations drawn as one line per person, over the same bins. None when none were selected.
LongitudinalSeriesInfo
pydantic-model
¶
Bases: BaseModel
One legended series in a longitudinal chart: a group, or the whole cohort.
Fields:
-
key(str) -
label(str) -
group(str | None) -
color_token(str | None)
color_token = None
pydantic-field
¶
Brand color token NAME the series' boxes use, matching the rows' color_token.
group = None
pydantic-field
¶
The tag group or stratum this series draws; None on an unsplit chart, whose single series is the whole cohort.
key
pydantic-field
¶
The value stamped on the chart's rows as series_key; a client selection key, not display text.
label
pydantic-field
¶
Legend text: the group's name, or the cohort's when the chart is not split.
LongitudinalSubjectChart
pydantic-model
¶
Bases: BaseModel
One metric from one analysis configuration, per subject over time.
Fields:
-
key(str) -
metric(str) -
label(str) -
unit_label(str | None) -
analysis_config_id(str) -
config_label(str) -
research_parameters(list[str] | None) -
chart(LineChartModel)
analysis_config_id
pydantic-field
¶
The analysis configuration whose output this chart draws.
chart
pydantic-field
¶
The geometry: one line per selected subject over the section's bins.
config_label
pydantic-field
¶
Display name of the configuration, as the chart's heading.
key
pydantic-field
¶
Stable chart identity within the view, one per metric and configuration.
label
pydantic-field
¶
Display name of the metric, e.g. 'TST'.
metric
pydantic-field
¶
The metric drawn.
research_parameters = None
pydantic-field
¶
Parameters outside the validated regime (exploratory output), same semantics as StatsOrigin.research_parameters.
unit_label = None
pydantic-field
¶
Display unit, e.g. 'min' or '%'.
LongitudinalSubjectView
pydantic-model
¶
Bases: BaseModel
The selected subjects, drawn one line each.
Boxes answer what a cohort did; a line answers what one person did. Selection is explicit and capped, because a figure with more lines than distinguishable colours shows nothing: past the cap the view comes back empty and the report says how many were asked for.
Fields:
-
subjects(list[str]) -
max_subjects(int) -
charts(list[LongitudinalSubjectChart]) -
excluded(list[LongitudinalExclusion])
charts
pydantic-field
¶
One chart per metric and analysis configuration, in the same order as the section's boxplots.
excluded
pydantic-field
¶
Selected subjects the view could not draw — a key that matches no study in scope, or one whose studies the bins exclude.
max_subjects
pydantic-field
¶
The most lines one figure draws — the number of distinguishable series colours the design system has.
subjects
pydantic-field
¶
The subject keys drawn, in legend order, as entered.
ManifestAnalysis
pydantic-model
¶
Bases: BaseModel
Which analysis and configuration this run is, for provenance.
Config:
extra:forbidfrozen:True
Fields:
-
id(str | None) -
config_id(str) -
config_sha1(str | None)
ManifestInputs
pydantic-model
¶
Bases: BaseModel
Everything the container reads.
Config:
extra:forbidfrozen:True
Fields:
-
recording(ManifestRecording) -
events(FileInput | None) -
metadata(ManifestMetadata | None)
events = None
pydantic-field
¶
Upstream events document, when the configuration declares event inputs.
ManifestMetadata
pydantic-model
¶
Bases: BaseModel
Inline context an analysis may use; absent when the configuration declares no metadata input.
Config:
extra:forbidfrozen:True
Fields:
-
subject(ManifestSubject | None) -
study(ManifestStudy | None)
ManifestOutputs
pydantic-model
¶
ManifestRecording
pydantic-model
¶
Bases: BaseModel
The recording the analysis reads, with the channels selected for it.
Config:
extra:forbidfrozen:True
Fields:
-
path(str) -
format(Literal['edf']) -
start(datetime | None) -
duration_ms(NonNegativeInt | None) -
channels(list[ChannelRef])
Validators:
ManifestResources
pydantic-model
¶
Bases: BaseModel
What the run has been given. The cgroup enforces the memory; the container sizes its pools to the cores.
Config:
extra:forbidfrozen:True
Fields:
-
cpus(PositiveInt) -
memory_mib(PositiveInt) -
gpus(NonNegativeInt) -
gpu_devices(list[str]) -
gpu_memory_mib(list[PositiveInt])
ManifestStudy
pydantic-model
¶
Bases: BaseModel
Study-level markers, as milliseconds from the recording start.
Config:
extra:forbidfrozen:True
Fields:
-
lights_off_ms(int | None) -
lights_on_ms(int | None)
ManifestSubject
pydantic-model
¶
Bases: BaseModel
What the platform knows about the subject, for analyses that use it.
Config:
extra:forbidfrozen:True
Fields:
-
age(NonNegativeInt | None) -
sex(Sex | None) -
bmi(PositiveFloat | None)
MemberOut
pydantic-model
¶
Bases: BaseModel
A member of an organization, as listed to its other members.
Config:
frozen:True
Fields:
-
id(UUID) -
user_id(UUID) -
email(str) -
name(str | None) -
role(MembershipRole) -
created_at(datetime)
created_at
pydantic-field
¶
When the member joined.
email
pydantic-field
¶
The member's email address.
id
pydantic-field
¶
The membership id; the id to address for role changes and removal.
name = None
pydantic-field
¶
The member's display name, if set.
role
pydantic-field
¶
The member's role in the organization.
user_id
pydantic-field
¶
The member's user id.
MemberRoleUpdate
pydantic-model
¶
MemberUsageOut
pydantic-model
¶
Bases: BaseModel
One member's share of the organization's usage.
Read by the organization's owner and admins, who pay for what every member holds but cannot open a colleague's private projects: the figures say where the space and the credits go without naming what is in them.
Config:
frozen:True
Fields:
-
user_id(UUID) -
email(str) -
name(str | None) -
role(MembershipRole) -
storage_bytes(int) -
private_storage_bytes(int) -
project_count(int) -
analysis_count(int) -
credits_used(float)
analysis_count
pydantic-field
¶
The member's analyses that are neither deleted nor failed, cancelled or rejected.
credits_used
pydantic-field
¶
Credits the organization has spent or reserved on those analyses.
email
pydantic-field
¶
The member's email address.
name = None
pydantic-field
¶
The member's display name, if set.
private_storage_bytes
pydantic-field
¶
The part of storage_bytes inside the member's private projects, which only they can open or free.
project_count
pydantic-field
¶
Projects the member owns in the organization, private ones included.
role
pydantic-field
¶
The member's role in the organization.
storage_bytes
pydantic-field
¶
Bytes the member's recordings, results and exports hold against the organization's storage ceiling, private projects included.
user_id
pydantic-field
¶
The member's user id.
Membership
pydantic-model
¶
Bases: BaseModel
Canonical Membership model — a user's role within an organization.
Config:
from_attributes:Truefrozen:True
Fields:
-
id(UUID) -
org_id(UUID) -
user_id(UUID) -
role(MembershipRole) -
created_at(datetime)
MessageResponse
pydantic-model
¶
Bases: BaseModel
Response model for a generic, str message response.
Fields:
-
message(str)
NamedEntityCreate
pydantic-model
¶
Bases: _NamedEntityFields
Create payload for named entities.
name is required. tags and description default to None.
Fields:
-
tags(TagsSet | None) -
description(DescriptionStr | None) -
name(NameString)
name
pydantic-field
¶
The name of the entity.
NamedEntityUpdate
pydantic-model
¶
Bases: _NamedEntityFields
PATCH payload for named entities.
Universal field semantics:
- Omit a field to leave it unchanged.
- Include a field with a value to update it.
- Include a field with
nullto clear it (where the field is nullable in storage — e.g.description,tags).
name is the exception: it is required in storage and cannot be
cleared. Sending {"name": null} is rejected with 422 — omit the
field if you don't want to change it.
Fields:
-
tags(TagsSet | None) -
description(DescriptionStr | None) -
name(NameString | None)
name = None
pydantic-field
¶
New name for the entity. Omit to leave unchanged. Cannot be null.
name_cannot_be_explicit_null()
¶
Reject {"name": null} while still allowing name to be omitted.
Sending an explicit null is rejected because name is required
in storage; clearing it would leave the entity in an invalid state.
Omit the field if you don't want to change it.
OrgCredits
pydantic-model
¶
Bases: BaseModel
An organization's credits: research grants and purchased credits.
The two never mix. Research analyses are paid from grants; commercial
analyses and storage above the free ceiling from purchased.
Config:
from_attributes:Truefrozen:True
Fields:
Organization
pydantic-model
¶
Bases: BaseModel
Canonical Organization model — the billing/quota/tenancy boundary.
Config:
from_attributes:Truefrozen:True
Fields:
-
id(UUID) -
name(str) -
storage_ceiling_gb(int | None) -
seat_limit(int | None) -
study_limit(int | None) -
project_limit(int | None) -
storage_insolvent_since(datetime | None) -
platform_operated(bool) -
analyses_at_site(bool) -
recordings_at_site(bool) -
site_compute_factor(float | None) -
created_at(datetime) -
deleted_at(datetime | None)
analyses_at_site = False
pydantic-field
¶
Whether the organisation's analyses run at its site, on its own runners, instead of on the platform. Set by a platform administrator while the organisation holds site compute.
created_at
pydantic-field
¶
Creation timestamp
deleted_at = None
pydantic-field
¶
Soft-delete timestamp, if deleted
id
pydantic-field
¶
Unique identifier of the organization
name
pydantic-field
¶
Display name of the organization
platform_operated = False
pydantic-field
¶
Whether the platform operates the organisation itself, as for a demonstration site.
project_limit = None
pydantic-field
¶
Per-org override of how many projects the organization may hold. Null = the configured default. Admin-set.
recordings_at_site = False
pydantic-field
¶
Whether the organisation's new projects keep their recordings in its own bucket. Set by a platform administrator while the organisation holds site storage; a project keeps where it is stored.
seat_limit = None
pydantic-field
¶
Per-org override of how many members plus pending invitations the organization may hold. Null = the configured default. Admin-set.
site_compute_factor = None
pydantic-field
¶
The organisation's own factor on the platform price for analyses run at its site. Null = the platform's factor. Admin-set.
storage_ceiling_gb = None
pydantic-field
¶
Per-org storage-ceiling override (GB). Null = the configured default ceiling. Admin-set.
storage_insolvent_since = None
pydantic-field
¶
When the org's balance stopped covering its daily storage debit (start of the grace window). Null = solvent. Stored data is purged after the configured grace period.
study_limit = None
pydantic-field
¶
Per-org override of how many studies one project may hold. Null = the configured default.
OrganizationCapabilities
pydantic-model
¶
Bases: BaseModel
An organisation's capabilities on its own hardware, and the agreement they rest on.
Fields:
-
platform_operated(bool) -
site_agreement_version(int | None) -
acceptance(SiteAgreementAcceptance | None) -
capabilities(list[CapabilityStatus])
acceptance = None
pydantic-field
¶
The organisation's latest acceptance of the site agreement.
capabilities
pydantic-field
¶
Each capability's state, one entry per capability.
platform_operated
pydantic-field
¶
Whether the platform operates the organisation itself; such an organisation needs no acceptance of the site agreement.
site_agreement_version
pydantic-field
¶
The latest published version of the site agreement; None while none is published, when nothing can be accepted.
OrganizationUpdate
pydantic-model
¶
OrganizationUsageOut
pydantic-model
¶
Bases: BaseModel
The organization's usage against its ceilings, member by member.
The owner's and admins' answer to "what fills the storage": the same totals every member sees on the account page, then one row per member, largest holder first. Private projects count, because the organization pays for them; their names and contents do not appear here.
Config:
frozen:True
Fields:
-
storage_bytes(int) -
storage_ceiling_bytes(int) -
project_count(int) -
project_cap(int | None) -
members(list[MemberUsageOut])
members
pydantic-field
¶
One row per member, the largest storage holder first; ties keep the members' order (owner, admins, then by joining date).
project_cap = None
pydantic-field
¶
Projects the organization may hold; null when uncapped.
project_count
pydantic-field
¶
Projects in the organization.
storage_bytes
pydantic-field
¶
Bytes the organization holds against its storage ceiling.
storage_ceiling_bytes
pydantic-field
¶
The organization's storage ceiling, in bytes.
Outputs
pydantic-model
¶
Bases: BaseModel
Defines the output of the analysis.
Fields:
-
supports_full_probabilistic_output(bool) -
events(list[EventType])
Validators:
events
pydantic-field
¶
The list of typed event that the analysis outputs.
supports_full_probabilistic_output = False
pydantic-field
¶
Whether the analysis supports outputting full probabilistic distributions (all class probabilities per prediction, not just argmax). When true, users can request overlapping events with probability scores for all classes.
validate_probabilistic_consistency()
pydantic-validator
¶
Validate probabilistic output consistency.
If supports_full_probabilistic_output is True, all event types must be probabilistic.
OwnershipTransfer
pydantic-model
¶
Bases: BaseModel
Hand the organization to another member (owner only).
The current owner becomes an admin. The password is re-entered because the transfer hands over every project, member and credit of the organization in one step.
Fields:
PaginatedRecordingsResponse
pydantic-model
¶
Bases: PaginatedResponse
Paginated list of recordings.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
recordings(list[RecordingOut])
PaginatedResponse
pydantic-model
¶
Bases: BaseModel
Base fields for a paginated listing response.
Fields:
Parameters
pydantic-model
¶
Bases: BaseModel
The analysis-specific parameters a configuration declares.
Every parameter reaches the container through the analysis manifest, keyed
by its key and typed as declared here; the platform passes nothing else.
Fields:
-
custom(list[AnalysisParameter])
Validators:
custom
pydantic-field
¶
Parameters the analysis accepts. Empty when it takes none.
research_parameters(submitted)
¶
Return the API names of parameters whose effective value is research mode.
The effective value of each custom parameter is the submitted value
(matched on :attr:AnalysisParameter.api_name) or, when absent, the
parameter's default — a default can itself lie outside the validated
regime. Parameters of configurations that declare no validated regime
never appear.
Raises:
| Type | Description |
|---|---|
ValueError
|
A submitted value does not resolve against this configuration (wrong type, not a choice, out of range). The caller decides whether that means "invalid submission" or, when classifying a historical analysis against a configuration that has since changed, "unknown". |
validate_unique_keys(custom)
pydantic-validator
¶
Keys and names are unique within one configuration.
PasswordPolicy
pydantic-model
¶
Bases: BaseModel
The server's password length policy for registration.
Exposed so the client validates and hints against the SAME bounds the server enforces, instead of hardcoding them (a tuned policy must never make the sign-up hint lie).
Fields:
-
min_length(int) -
max_length(int)
PasswordResetEmailRequest
pydantic-model
¶
PendingConsent
pydantic-model
¶
Bases: BaseModel
A document the user must still accept, and the version to accept.
Fields:
-
document(ConsentDocument) -
current_version(PositiveInt)
PermissionInfo
pydantic-model
¶
Bases: BaseModel
One permission as the server knows it.
The vocabulary is served so that a client renders it instead of keeping a copy: an admin's permission editor lists exactly what the server can grant, and an API key dialog offers exactly what a key may carry.
Fields:
-
value(Permission) -
resource(str) -
action(str) -
key_scopeable(bool)
action
pydantic-field
¶
The part after the colon.
key_scopeable
pydantic-field
¶
Whether an API key may be scoped to this permission. Account and key management never are; the server decides the rest.
resource
pydantic-field
¶
The part before the colon.
value
pydantic-field
¶
The permission, resource:action.
PlatformControlOut
pydantic-model
¶
Bases: BaseModel
One control: configured default, override if any, and what is in force.
Fields:
-
name(PlatformControlName) -
configured(bool) -
override(PlatformControlOverride | None) -
effective(bool)
PlatformControlOverride
pydantic-model
¶
Bases: BaseModel
An operator's override of a control, while it lasts.
Config:
from_attributes:True
Fields:
-
enabled(bool) -
reason(str) -
set_by(UUID) -
set_at(datetime) -
expires_at(datetime)
PlatformControlUpdate
pydantic-model
¶
Bases: BaseModel
Set a control's override.
Every override expires; the server bounds how far ahead expires_at may
lie. Setting a control that already has an override replaces it, which is
also how an override is extended.
Fields:
-
enabled(bool) -
reason(str) -
expires_at(AwareDatetime)
enabled
pydantic-field
¶
The value to apply until expiry.
expires_at
pydantic-field
¶
When the override ends and the configured value returns. Must lie in the future, within the server's maximum override length.
reason
pydantic-field
¶
Why. Recorded with the change and shown to other administrators.
PlatformControlsOut
pydantic-model
¶
PlatformStats
pydantic-model
¶
Bases: BaseModel
Platform-wide statistics.
Fields:
-
total_users(int) -
active_users(int) -
disabled_users(int) -
recently_active_users(int) -
recently_active_days(int) -
users_by_role(dict[str, int]) -
total_projects(int) -
total_studies(int) -
total_recordings(int) -
total_analyses(int) -
storage_bytes_total(int) -
storage_bytes_stored(int) -
analyses_by_status(dict[AnalysisStatus, int]) -
pending_approvals(int) -
registrations_24h(int)
active_users
pydantic-field
¶
Users that are NOT DISABLED. This counts accounts in good standing, not accounts in use — an account that has never been signed into is counted here. For actual usage read recently_active_users, which is what 'active' normally means to a reader.
analyses_by_status
pydantic-field
¶
Live analyses that have not yet settled, by status — the queue as it stands at the time of the request. Statuses with no live analyses are absent rather than zero.
pending_approvals
pydantic-field
¶
Accounts that registered and await an administrator's approval before they can sign in.
recently_active_days
pydantic-field
¶
The window recently_active_users counts over, in days. Reported alongside the count so a reader never has to guess what 'recently' meant, and so the window can change without silently changing what the number means.
recently_active_users
pydantic-field
¶
Users who signed in within recently_active_days. The honest activity figure: derived from each account's last sign-in, so it falls when people stop using the platform, which active_users does not.
registrations_24h
pydantic-field
¶
Accounts created in the last 24 hours, whatever their approval state. A burst here is what the registration control answers.
storage_bytes_stored
pydantic-field
¶
Bytes actually held across the platform, regardless of whether they count toward an allowance — the 'how much data do we hold' figure, which answers capacity and cost rather than billing. The gap against storage_bytes_total is the storage the platform pays for and does not charge for. Live resources only.
storage_bytes_total
pydantic-field
¶
Bytes counting toward storage ALLOWANCES across the platform — what the platform bills for. Excludes resource types configured not to count toward quota and anything external, so it is not the amount of data held; read storage_bytes_stored for that. Live resources only; soft-deleted ones are excluded, matching how per-org quota is measured.
PoolImage
pydantic-model
¶
Bases: BaseModel
An image the runners of a pool may be asked to run.
Fields:
-
reference(str) -
kind(LeaseKind) -
smallest_job(RunnerCapacity) -
analyses(list[str])
analyses
pydantic-field
¶
The analyses that run this image, by configuration id. Empty for a runner an administrator has not yet approved.
kind = LeaseKind.ANALYSIS
pydantic-field
¶
The kind of job that runs the image.
reference
pydantic-field
¶
The image as a runner is asked to run it: its name and tag, and its digest when the analysis declares one.
smallest_job
pydantic-field
¶
The least room a job on this image claims: the fewest cores any of its analyses claims, and the least memory any claims for the shortest recording. A runner whose largest job is smaller is never asked to run it.
PoolImagesResponse
pydantic-model
¶
Bases: BaseModel
The images a runner's pool may be asked to run.
A runner pulls them ahead of its first job, so a missing registry login or permission shows when the host is set up, not when an analysis waits.
Fields:
-
images(list[PoolImage])
PreRegistrationResponse
pydantic-model
¶
Bases: MessageResponse
Response for recording pre-registration including presigned PUT URL.
Fields:
-
message(str) -
recording(RecordingOut) -
presigned_upload(PreSignedUploadUrl)
PreSignedDownloadUrl
pydantic-model
¶
Bases: BaseModel
Pre-signed GET URL for direct S3 download.
Fields:
-
url(AnyUrl) -
filename(str) -
expires(timedelta) -
etag(str | None)
etag = None
pydantic-field
¶
The object's ETag when it was accepted. A reader that sends it as If-Match is refused with 412 if the object has changed since; null for a recording accepted before ETags were recorded.
PreSignedUploadUrl
pydantic-model
¶
Bases: BaseModel
Pre-signed PUT URL for direct S3 upload.
Fields:
-
url(AnyUrl) -
expires(timedelta) -
headers(dict[str, str])
headers
pydantic-field
¶
Headers the PUT must send, as they are signed into the URL. If-None-Match: * makes the URL create the object once: a second PUT with it is refused with 412 and changes nothing.
Priority
pydantic-model
¶
ProjectAnalysisConfig
pydantic-model
¶
Bases: BaseModel
One analysis configuration a project has completed results from.
Fields:
-
analysis_config_id(str) -
name(str) -
analysis_count(int) -
study_count(int)
analysis_config_id
pydantic-field
¶
The configuration's stable identifier, as reports and analysis requests name it.
analysis_count
pydantic-field
¶
Completed analyses this configuration produced in the project.
name
pydantic-field
¶
Display name of the configuration.
study_count
pydantic-field
¶
Studies with at least one completed analysis from it.
ProjectCreate
pydantic-model
¶
Bases: NamedEntityCreate
Create payload for a project. name is required.
Fields:
-
tags(TagsSet | None) -
description(DescriptionStr | None) -
name(NameString) -
pseudonymisation(Pseudonymisation) -
visibility(Visibility)
pseudonymisation
pydantic-field
¶
The project's pseudonymisation policy. Fixed when the project is created.
visibility = Visibility.PRIVATE
pydantic-field
¶
Who can access the project: private (its owner only), org (every member of the organization) or shared (its owner plus the members it is explicitly shared with). Defaults to private.
ProjectListResponse
pydantic-model
¶
Bases: PaginatedResponse
A page of the projects you can open.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
projects(list[ProjectOut])
ProjectOut
pydantic-model
¶
Bases: ProjectCreate
Project information available to user.
Fields:
-
tags(TagsSet | None) -
description(DescriptionStr | None) -
name(NameString) -
pseudonymisation(Pseudonymisation) -
visibility(Visibility) -
id(UUID) -
created_at(datetime) -
owner_id(UUID | None) -
created_by(UUID | None) -
recordings_at_site(bool) -
study_count(int) -
recording_count(int) -
analyzed_count(int) -
analyses_count(int) -
total_duration_ms(int) -
lights_complete_count(int) -
subject_count(int) -
demographics_count(int)
analyses_count = 0
pydantic-field
¶
Total number of analyses
analyzed_count = 0
pydantic-field
¶
Recordings with >= 1 completed analysis
created_at
pydantic-field
¶
Creation timestamp of the project
created_by = None
pydantic-field
¶
The user who created the project (null if that user was deleted). Provenance only; it does not change when ownership does.
demographics_count = 0
pydantic-field
¶
Subjects with at least one subject-metadata field (age/sex/BMI) set — counted per subject, so a person characterised on thirty nights counts once.
id
pydantic-field
¶
Unique identifier of the project
lights_complete_count = 0
pydantic-field
¶
Studies with BOTH lights markers set (the statistics window is fully defined). The completeness headline pairs this with study_count.
owner_id = None
pydantic-field
¶
The member who owns the project: the only one who can change its visibility, share it or delete it. Ownership passes to the organization's owner when a member leaves.
recording_count = 0
pydantic-field
¶
Number of recordings
recordings_at_site = False
pydantic-field
¶
Whether the project's recordings live in its organisation's bucket rather than on the platform. Fixed when the project is created; its analyses then run only on the organisation's own runners.
study_count = 0
pydantic-field
¶
Number of studies
subject_count = 0
pydantic-field
¶
Distinct subjects among the project's studies. A study with no subject key is its own subject, so a project where nobody set a key reads the same as study_count; where keys are set, this is how many people the studies belong to.
total_duration_ms = 0
pydantic-field
¶
Total recording duration in ms
ProjectReportChart
pydantic-model
¶
Bases: BaseModel
One server-computed chart for a project report stats card.
A chart spans every row sharing one value axis — multiple
SummaryStats entries — so it attaches to the report envelope, not to
an individual stats entry. The identity fields mirror the card grouping
(analysis type + config + parameters) so consumers can place each chart
on its card without re-deriving geometry.
Fields:
-
key(str) -
title(str) -
metric(str) -
analysis_type(AnalysisType | None) -
analysis_config_id(str) -
analysis_parameters(list[tuple[str, str | int | float | bool]]) -
event_label(str | None) -
chart(BoxplotModel)
analysis_config_id
pydantic-field
¶
Analysis configuration the card groups by.
analysis_parameters
pydantic-field
¶
Analysis parameters the card groups by.
analysis_type = None
pydantic-field
¶
Analysis type of the stats card this chart belongs to (None for non-event charts, e.g. future biomarker summaries).
chart
pydantic-field
¶
The chart geometry.
event_label = None
pydantic-field
¶
Set on by-group comparison charts: the event type this chart compares across study groups. None on single-group charts (rows are the event types).
key
pydantic-field
¶
Stable chart identity within the report (safe as a render/caching key).
metric
pydantic-field
¶
Metric the value axis plots (a stats dict key, e.g. 'total-duration-ms').
title
pydantic-field
¶
Human-readable chart heading.
ProjectReportResponse
pydantic-model
¶
Bases: BaseModel
Envelope for project-level report data.
Wraps aggregated event summary statistics with optional biomarker summary statistics computed across all studies in the project.
Fields:
-
event_stats(list[SummaryStats]) -
statistics_window(StatisticsWindow | None) -
window_summary(ProjectWindowSummary | None) -
biomarker_summary(list[BiomarkerSummaryStats] | None) -
origins_sets(dict[str, list[StatsOrigin]] | None) -
warnings(list[str]) -
charts(list[ProjectReportChart] | None) -
tables(list[TableModel] | None) -
stratification(ReportStratification | None) -
longitudinal(LongitudinalSection | None) -
credits(list[CreditedAnalysis]) -
sections(list[ReportSection])
biomarker_summary = None
pydantic-field
¶
Aggregated biomarker distribution stats grouped by analysis config (None if not requested)
charts = None
pydantic-field
¶
Server-computed chart models for the report's stats cards. None for producers predating the field.
event_stats
pydantic-field
¶
Aggregated event summary statistics
longitudinal = None
pydantic-field
¶
Set when the report was requested longitudinally: ordered per-metric series with explicit exclusions. The aggregate fields above still describe the whole cohort flat.
origins_sets = None
pydantic-field
¶
Shared origins lists, keyed by the origins_ref values carried on event_stats / biomarker_summary entries. On large projects every event family of one analysis configuration shares the same contributing studies, so each distinct list is carried once here instead of repeated per entry. None when all entries carry their origins inline. Use resolve_origins to read an entry's effective origins regardless of representation.
statistics_window = None
pydantic-field
¶
Deprecated for project reports: the FIRST study's window, kept for older consumers. A project's windows generally differ per study; use window_summary.
stratification = None
pydantic-field
¶
Set when the report was requested with stratify_by: the factor, the resolved bin edges and per-stratum study counts. None on unstratified reports.
tables = None
pydantic-field
¶
Server-defined tables: per-config distribution and biomarker-summary tables. None for producers predating the field.
warnings
pydantic-field
¶
Warnings about statistics computation
window_summary = None
pydantic-field
¶
How the studies' statistics windows were resolved — source counts and the length range. None for producers predating the field.
resolve_origins(entry)
¶
Return the effective origins of a stats entry.
Entries carry their origins inline, or reference a shared list on
this envelope via origins_ref. Consumers should always read
origins through this method rather than entry.origins directly.
ProjectShareCreate
pydantic-model
¶
ProjectShareOut
pydantic-model
¶
Bases: BaseModel
One member a shared project is open to.
Config:
frozen:True
Fields:
-
id(UUID) -
project_id(UUID) -
user_id(UUID) -
email(str) -
name(str | None) -
created_at(datetime)
created_at
pydantic-field
¶
When the share was granted.
email
pydantic-field
¶
That member's email address.
id
pydantic-field
¶
Unique identifier of the share.
name = None
pydantic-field
¶
That member's display name, if set.
project_id
pydantic-field
¶
The shared project.
user_id
pydantic-field
¶
The member the project is shared with.
ProjectUpdate
pydantic-model
¶
Bases: NamedEntityUpdate
PATCH payload for a project — all fields are optional.
See NamedEntityUpdate for the universal PATCH semantics
(omit-to-skip, include-to-set, null-to-clear).
Fields:
-
tags(TagsSet | None) -
description(DescriptionStr | None) -
name(NameString | None) -
visibility(Visibility | None)
visibility = None
pydantic-field
¶
If set, change who can access the project.
ProjectWindowSummary
pydantic-model
¶
Bases: BaseModel
How the statistics windows across a project's studies were resolved.
A project-level report aggregates studies whose windows generally differ — in source and in length — so a single window cannot describe it. This summarises: how many studies resolved their window from each source, and the range of window lengths. A study counts as lights-based when its window came from lights events, including one-ended windows where only lights-off or only lights-on was set.
Fields:
-
lights_based(int) -
client_set(int) -
full_recording(int) -
windowless(int) -
min_length_ms(int | None) -
max_length_ms(int | None)
client_set
pydantic-field
¶
Studies whose window was pinned by a client override.
full_recording
pydantic-field
¶
Studies that fell back to the full recording.
lights_based
pydantic-field
¶
Studies whose window came from lights events (including one-ended lights windows).
max_length_ms = None
pydantic-field
¶
Longest resolved window, in ms. None when no study has a window.
min_length_ms = None
pydantic-field
¶
Shortest resolved window, in ms. None when no study has a window.
windowless
pydantic-field
¶
Studies with no resolvable window at all.
Pseudonymisation
pydantic-model
¶
Bases: BaseModel
A project's pseudonymisation policy: chosen when it is created, never changed.
The EDF patient and recording identification fields are blanked in every project, whatever its policy.
Config:
frozen:Trueextra:forbid
Fields:
dates = RecordingDates.REAL
pydantic-field
¶
Whether recordings keep their start dates (real) or have them replaced by EDF+'s unknown date before upload (removed); the time of day stays either way.
file_names = FileNames.ORIGINAL
pydantic-field
¶
Whether recordings keep their file names (original) or carry a code instead (coded).
PublicationAnalysis
pydantic-model
¶
Bases: BaseModel
An analysis whose evidence includes a publication.
Fields:
-
analysis_config_id(str) -
name(str)
PublicationFamily
pydantic-model
¶
Bases: BaseModel
A family of analyses the listing can be narrowed to.
Fields:
-
name(str) -
shown_by_default(bool)
PublicationListing
pydantic-model
¶
Bases: BaseModel
Every publication the platform lists.
A citation list, not a census: there may be further work that is not listed. Present a count as a floor.
Fields:
-
families(list[PublicationFamily]) -
publications(list[ListedPublication])
Purpose
pydantic-model
¶
Bases: BaseModel
Describes the analysis' type/outputs and purpose.
Fields:
-
analysis_types(list[AnalysisType]) -
description(DescriptionStr) -
tags(list[str])
analysis_types
pydantic-field
¶
The type(s) of analysis/anlyses (e.g., 'STAGING') that the analysis supports.
description
pydantic-field
¶
A brief description of the analysis.
tags
pydantic-field
¶
Optional free-form tags for categorising/sorting the analysis in clients (e.g. 'example' to mark demo configs, which clients sort last and badge).
QCMetrics
pydantic-model
¶
Bases: BaseModel
Quality metrics for a sleep analysis.
Confidence-dependent fields are None when events lack probability (non-probabilistic analysis configs).
Fields:
-
total_epochs(int) -
valid_epochs(int) -
artifact_epochs(int) -
artifact_pct(float) -
recording_completeness_pct(float) -
confidence_mean(float | None) -
confidence_min(float | None) -
confidence_p5(float | None) -
entropy(float | None) -
transition_confidence(float | None)
artifact_epochs
pydantic-field
¶
Number of artifact-flagged epochs
artifact_pct
pydantic-field
¶
Percentage of epochs flagged as artifact
confidence_mean = None
pydantic-field
¶
Mean confidence across all epochs
confidence_min = None
pydantic-field
¶
Minimum confidence across all epochs
confidence_p5 = None
pydantic-field
¶
5th percentile confidence
entropy = None
pydantic-field
¶
Staging entropy — true Shannon entropy from full 5-class softmax when available, argmax-based proxy otherwise
recording_completeness_pct
pydantic-field
¶
Percentage of recording length covered by events
total_epochs
pydantic-field
¶
Total number of epochs
transition_confidence = None
pydantic-field
¶
Mean confidence at epochs where the sleep stage changes
valid_epochs
pydantic-field
¶
Number of non-artifact epochs
QualityRequirement
pydantic-model
¶
Bases: BaseModel
Data quality requirements for a channel.
Fields:
method
pydantic-field
¶
The method used to calculate the quality metric. These methods are implemented by the platform and not by the individual analyses.
mode
pydantic-field
¶
The mode in which the quality metric is calculated and used. Modes can be 'global' or 'per_epoch'. If global, the channel cannot be passed to the analysis if the whole-recording quality is below the min_quality. If per_epoch, the channel can be passed to the analysis. If 'per_epoch', the analysis will receive the channel but the platform will indicate that any events within epochs with quality below min_quality should be considered uncertain.
score
pydantic-field
¶
The range of acceptable values for the quality metric.
Range
¶
Bases: RootModel
Represents a range between a minimum and maximum value.
Both values are inclusive and the minimum value is less than or equal to the maximum value. A maximum value of None indicates that there is no upper limit (+inf). A minimum value of None indicates that there is no lower limit (-inf). String literals "+inf" and "-inf" are also allowed.
__contains__(item)
¶
Check if the item is within the range.
__getitem__(item)
¶
Return the value at the given index.
__iter__()
¶
Return an iterator over the range values.
serialize_range()
¶
Convert float(+/-inf) to string (+/-inf) for JSON serialization.
validate_range(values)
classmethod
¶
Validate the range values.
Validate the range values and handles conversion of string inf literals to floats and specification as root or 'range' key in the dictionary.
RecordingAnalysisSummary
pydantic-model
¶
Bases: BaseModel
Compact per-recording analysis summary (id + status + config name).
Fields:
-
id(UUID) -
status(AnalysisStatus) -
analysis_config_name(str)
RecordingHeader
pydantic-model
¶
Bases: BaseModel
Model with information that header reading functions should return.
Fields:
-
channels(list[ChannelOut]) -
length_ms(PositiveInt) -
recording_start(datetime)
RecordingInput
pydantic-model
¶
Bases: BaseModel
Defines a recording type input for the analysis.
Fields:
-
format(FileFormat) -
allow_multiple(bool) -
description(DescriptionStr | None) -
minimum_duration_seconds(PositiveInt) -
channels(list[ExactChannelRequirement] | None) -
channel_types(list[ChannelTypeRequirement] | None)
Validators:
allow_multiple = False
pydantic-field
¶
Whether the analysis supports multiple input files passed as a list of paths to 'argument' (see default parameters). Default is False, in which case a single path is passed.
channel_types = []
pydantic-field
¶
The list of channel types that the analysis expects and their requirements. Can be None if the analysis does not support general channels by types but requires exact channel deriviations only (see channels).
channels = []
pydantic-field
¶
The list of exact channels deriviations that the analysis expects and their requirements. Can be None if the analysis does not require any specific channels but any channels of certain types (see channel_types).
description = None
pydantic-field
¶
A brief description of the input.
format = FileFormat.EDF
pydantic-field
¶
The format of the input file, e.g., 'edf'.
minimum_duration_seconds = 1
pydantic-field
¶
The minimum duration of the input in seconds. Must be greater than 0.
validate_channels(data)
pydantic-validator
¶
Validate that at least one of 'channels' and 'channel_types' is set.
RecordingOut
pydantic-model
¶
Bases: RecordingUpdate, RecordingHeader
Recording information available to user.
Fields:
-
channels(list[ChannelOut]) -
length_ms(PositiveInt) -
recording_start(datetime) -
owner_id(UUID | None) -
id(UUID) -
created_at(datetime) -
original_filename(str) -
file_size_bytes(NonNegativeInt) -
format(FileFormat) -
state(FileUploadState) -
checksum(None | str) -
study_id(UUID | None) -
study_name(str | None) -
analyses(list[RecordingAnalysisSummary]) -
missing_since(datetime | None)
analyses
pydantic-field
¶
Per-recording analysis summaries (id, status, config name).
checksum = None
pydantic-field
¶
The SHA1/MD5 hash of the file. May be None. May contain a '-{number of parts}' of up to 4 digits of parts suffix. E.g., {checksum}-4 or {checksum}-0001
created_at
pydantic-field
¶
The date and time when the recording was created.
file_size_bytes
pydantic-field
¶
Size of the file in bytes
format
pydantic-field
¶
The format of the file, e.g., 'edf'.
id
pydantic-field
¶
The unique identifier of the recording.
missing_since = None
pydantic-field
¶
When a look for new files found the bucket file it was registered from gone from its key, or changed there; null while it is there. New analyses of a missing recording are refused.
owner_id = None
pydantic-field
¶
The member who added it. Only they, or the project's owner, may change or remove it; it passes to the project's owner when they leave the organization.
state
pydantic-field
¶
The state of the file, e.g., 'registered'.
study_id = None
pydantic-field
¶
ID of the parent study. Populated in flat project-level listings.
study_name = None
pydantic-field
¶
Name of the parent study. Populated in flat project-level listings.
RecordingSelector
pydantic-model
¶
Bases: _SelectorBase
Address a set of recordings: exactly one of ids | all.
Recordings carry no filterable attributes of their own yet, so this selector has no filter mode; it exists so every batch write speaks the same addressing language.
Fields:
-
ids(list[UUID] | None) -
all(bool)
Validators:
-
_exactly_one_mode
RecordingUpdate
pydantic-model
¶
Bases: BaseModel
Updatable file fields.
RemoteFileMapping
pydantic-model
¶
Bases: BaseModel
Represents a remote file mapping for the analysis submission.
A remote file mapping is used to map how a remotely located input or output file should be mapped to/from the local file system of the analysis container by a controller.
For instance, an input file may be stored in s3 and should be downloaded to the local file system of the analysis container before the analysis is run. The output file of an analysis may similarly be requested to be stored in s3 after the analysis is run.
Fields:
-
remote_url(AnyUrl) -
container_path(str) -
type(Literal['input', 'output']) -
size_bytes(int | None)
Validators:
container_path
pydantic-field
¶
The path in the container where the file should be mounted. This is the path where the file will be available in the analysis container. Can be absolute or relative.
remote_url
pydantic-field
¶
The URL to the original file location. Must be an https, s3 bucket or file URL.
size_bytes = None
pydantic-field
¶
Size of the remote file in bytes, when known at submission build time. Lets consumers (disk-space planning, runners) skip a per-file storage lookup. None when unknown — e.g. output files that do not exist yet.
type
pydantic-field
¶
The type of the file mapping. Can be either 'input' or 'output'. Input files must be downloaded before the analysis is run and mounted in the container. Output files must be uploaded after the analysis is run.
validate_remote_url(url)
pydantic-validator
¶
Validate the remote URL to ensure it is a s3 URL (currently only supported scheme).
ReportAnalysisInfo
pydantic-model
¶
Bases: BaseModel
Analysis metadata for reports.
Fields:
-
analysis_id(str) -
analysis_types(list[AnalysisType]) -
analysis_config_id(str) -
analysis_config_name(str) -
status(AnalysisStatus) -
parameters(list[tuple[str, str | int | float | bool]]) -
analysis_config_version(str | None) -
completed_at(datetime | None) -
channels(list[str] | None) -
research_parameters(list[str] | None)
analysis_config_id
pydantic-field
¶
Analysis config identifier
analysis_config_name
pydantic-field
¶
Analysis config name
analysis_config_version = None
pydantic-field
¶
Version of the analysis configuration that produced the results — provenance for the report audit appendix. None for producers predating the field.
analysis_id
pydantic-field
¶
Short analysis identifier
analysis_types
pydantic-field
¶
Types of analysis
channels = None
pydantic-field
¶
Channel names the analysis ran on — provenance for reports. None for producers predating the field.
completed_at = None
pydantic-field
¶
When the analysis completed — provenance for the report audit appendix. None for producers predating the field.
parameters
pydantic-field
¶
Analysis parameters
research_parameters = None
pydantic-field
¶
Parameters (by API name) whose value lay outside the analysis's validated regime, marking this analysis's outputs as exploratory. Empty when every parameter was within the regime. None when not derived (producers predating the field, or a configuration change made the submitted values unresolvable).
status
pydantic-field
¶
Analysis status
ReportAnnotatedEvents
pydantic-model
¶
Bases: BaseModel
Events with associated analysis metadata for reports.
Fields:
-
events(list[Event]) -
analysis(ReportAnalysisInfo) -
recording_length_ms(int | None)
recording_length_ms = None
pydantic-field
¶
Length of the source recording in milliseconds, used for coverage % computation
ReportExportCreate
pydantic-model
¶
Bases: BaseModel
Request body for creating a report export.
Fields:
-
format(ReportExportFormat) -
events_params(EventsExportParams | None) -
layout(list[SectionLayoutEntry] | None) -
project_params(ReportExportProjectParams | None) -
email_copy(bool)
email_copy = False
pydantic-field
¶
Also email the artifact link to the requesting user's verified address once the export completes. NOT YET HONORED: the server rejects true until the email delivery path ships.
events_params = None
pydantic-field
¶
events-zip exports only: which studies to bundle. Rejected for document formats.
format
pydantic-field
¶
Artifact format to render.
layout = None
pydantic-field
¶
Section selection/order to apply; omitted = every section in natural order. Snapshotted on the export.
project_params = None
pydantic-field
¶
Project exports only: which report mode to render. None = by-group over every tag.
ReportExportListResponse
pydantic-model
¶
Bases: PaginatedResponse
A page of the user's report exports, newest first.
Paginated like the other listings: total is the whole collection, not
the page, so a client can show how many exports exist and page through
them rather than treating one capped read as the whole history.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
exports(list[ReportExportOut])
exports
pydantic-field
¶
The exports on this page.
ReportExportOut
pydantic-model
¶
Bases: BaseModel
One report export and its lifecycle state.
Fields:
-
owner_id(UUID | None) -
id(UUID) -
kind(ReportExportKind) -
project_id(UUID) -
study_id(UUID | None) -
project_name(str | None) -
study_name(str | None) -
format(ReportExportFormat) -
status(ReportExportStatus) -
error(str | None) -
size_bytes(int | None) -
created_at(datetime) -
completed_at(datetime | None) -
expires_at(datetime | None) -
download_url(str | None) -
appendix_download_url(str | None)
appendix_download_url = None
pydantic-field
¶
Short-lived download URL for the export's audit-appendix CSV snapshot, for formats that keep the appendix out of the main artifact (PDF). Present only while completed and not expired; None for formats that embed the appendix and for rows predating the field.
completed_at = None
pydantic-field
¶
When rendering finished (success or failure).
created_at
pydantic-field
¶
When the export was requested.
download_url = None
pydantic-field
¶
Short-lived download URL; present only while completed and not expired.
error = None
pydantic-field
¶
Failure reason when status is failed.
expires_at = None
pydantic-field
¶
When the artifact is deleted; absent until completed.
format
pydantic-field
¶
Artifact format.
id
pydantic-field
¶
Export identifier.
kind
pydantic-field
¶
Study or project report.
owner_id = None
pydantic-field
¶
The member who added it. Only they, or the project's owner, may change or remove it; it passes to the project's owner when they leave the organization.
project_id
pydantic-field
¶
The project the report belongs to.
project_name = None
pydantic-field
¶
Display name of the project at export time. None for rows predating the field.
size_bytes = None
pydantic-field
¶
Artifact size once completed.
status
pydantic-field
¶
Lifecycle state.
study_id = None
pydantic-field
¶
The study, for study-report exports.
study_name = None
pydantic-field
¶
Display name of the study at export time, for study-report exports. None otherwise or predating.
ReportExportProjectParams
pydantic-model
¶
Bases: BaseModel
Project-report mode selection for an export.
The field NAMES mirror the report GET's query parameters; by_group's
DEFAULT does not. Exporting a project report is grouped unless you ask for
flat, while reading one is flat unless you ask for grouped. Pass
by_group explicitly and the two agree.
Fields:
-
by_group(bool) -
groups(list[str] | None) -
analysis_configs(list[str] | None) -
stratify_by(MetadataType | None) -
stratify_edges(list[float] | None) -
longitudinal(bool) -
longitudinal_basis(LongitudinalBasis | None) -
subjects(list[str] | None) -
calendar_granularity(CalendarGranularity)
Validators:
-
_validate_stratification
analysis_configs = None
pydantic-field
¶
Only these analysis configurations contribute to the report; None includes every completed analysis. A report over one pipeline is the same report with the others left out — every count, card, figure and table follows the selection.
by_group = True
pydantic-field
¶
Group statistics by study tags. Defaults to ON — the opposite of the by_group query parameter on GET /projects/{project}/report, which defaults to OFF. An export that omits this renders by-group over every tag; pass it explicitly rather than relying on either default.
calendar_granularity = 'month'
pydantic-field
¶
The span of one bin on a 'calendar' basis; ignored otherwise.
groups = None
pydantic-field
¶
Tags forming the comparison groups; None = every tag.
longitudinal = False
pydantic-field
¶
Compute the longitudinal section (the flat boxplot with time bins as rows, one chart per metric) alongside the flat aggregates. Documents render it as an "Over time" block: the bins table and one figure per metric.
longitudinal_basis = None
pydantic-field
¶
What the bins are; only meaningful with longitudinal. None lets the server choose: 'session-index' when any study in scope carries a subject key, else 'calendar'.
stratify_by = None
pydantic-field
¶
Stratify statistics by a subject-metadata factor instead of tags. When set, tag grouping is not applied (by_group is ignored) and groups must be omitted. Studies missing the factor form their own 'Not set' stratum.
stratify_edges = None
pydantic-field
¶
Bin edges overriding the server's configured defaults; numeric factors (age, bmi) only. Strictly increasing; bins are half-open intervals [a, b).
subjects = None
pydantic-field
¶
Draw these subjects as lines beside the bins, one series each; only meaningful with longitudinal. Keys are compared case- and whitespace-insensitively, as grouping does.
ReportSection
pydantic-model
¶
Bases: BaseModel
One section of a report, in the order the report shows it.
The report's composition is served with its content: the live page renders
these sections and every export is built from the same list, so the two
show the same sections, in the same order, with the same defaults. A
section points at its content (a table in tables, a figure by its key
and source) rather than repeating it.
Fields:
-
key(str) -
kind(ReportSectionKind) -
title(str) -
text(str | None) -
parent(str | None) -
default_visible(bool) -
table(str | None) -
figure(str | None) -
figure_source(ReportFigureSource | None)
default_visible = True
pydantic-field
¶
Whether the section shows when the reader has not chosen. A per-analysis section a comparison already covers starts hidden.
figure = None
pydantic-field
¶
For a 'figure' section: the key of its figure in the collection figure_source names.
figure_source = None
pydantic-field
¶
Where the figure is: 'hypnogram' (hypnograms, keyed by analysis id), 'chart' (charts), 'longitudinal' (longitudinal.charts) or 'subject' (longitudinal.subject_view.charts).
key
pydantic-field
¶
Stable section identity, in the section-key vocabulary; what a layout entry names.
kind
pydantic-field
¶
'text' (a sentence or two), 'heading' (groups the sections that name it as parent), 'table' or 'figure'.
parent = None
pydantic-field
¶
The key of the 'heading' section this one is grouped under; null at the top level.
table = None
pydantic-field
¶
For a 'table' section: the key of its table in the response's tables.
text = None
pydantic-field
¶
The prose of a 'text' section, or the line under a heading's title; formatted.
title = ''
pydantic-field
¶
The section's heading text.
ReportStratification
pydantic-model
¶
Bases: BaseModel
The stratification a report was computed with.
Present on stratified reports only. Echoes the factor, the resolved bin edges and the per-stratum study counts, so consumers can caption the grouping instead of inferring it from labels.
Fields:
-
factor(MetadataType) -
edges(list[float] | None) -
unit(str | None) -
strata(list[StratumCount])
edges = None
pydantic-field
¶
Resolved bin edges for numeric factors. Bins are half-open intervals [a, b): a value equal to an edge belongs to the bin above it. None for categorical factors (sex).
factor
pydantic-field
¶
The subject-metadata factor the report is stratified by.
strata
pydantic-field
¶
Every stratum in display order — edge order for numeric factors, enum order for sex — with the 'Not set' stratum last when present. Strata with zero studies are included.
unit = None
pydantic-field
¶
Unit the edges are expressed in (e.g. 'years'); None for categorical factors.
ResetPasswordRequest
pydantic-model
¶
ResolvedResourceClaim
pydantic-model
¶
Bases: BaseModel
The resources one submission claims, resolved once, in canonical MiB.
:class:ResourceRequirements carries the coefficients; this carries the
numbers those coefficients produce for a particular submission's hours,
channel count and native sample rate. Every field is a resolved quantity,
not a rate.
The claim is consumed twice, in different units: the container is told
what to budget for itself (in MiB, in the manifest's resources), while
the orchestrator enforces a ceiling (a cgroup, in MB). Both are rendered
from this one resolved claim.
The disk figure is kept only here, because the container is never given one.
Fields:
-
cpu_cores(PositiveInt | None) -
cpu_mhz(NonNegativeInt | None) -
gpus(NonNegativeInt) -
system_memory_mib(NonNegativeInt) -
gpu_memory_mib(NonNegativeInt) -
wall_clock_seconds(PositiveInt | None) -
disk_mib(NonNegativeInt)
Validators:
-
_one_cpu_unit
cpu_cores = None
pydantic-field
¶
Whole CPU cores reserved for the run; rendered to the container as --cpus and the thread-count environment variables, and to the orchestrator as its CPU reservation. None only on claims persisted before the unit changed from MHz, which carry cpu_mhz.
cpu_mhz = None
pydantic-field
¶
Legacy CPU floor in MHz on claims persisted before cores became the unit. Not written by current versions; read only to re-dispatch an old submission.
disk_mib
pydantic-field
¶
Resolved disk in MiB — output artifacts plus the input files that must be materialised into the runtime. Never passed to the container, which is why this model exists.
gpu_memory_mib = 0
pydantic-field
¶
Resolved peak GPU memory in MiB. 0 when no GPU is claimed.
gpus = 0
pydantic-field
¶
Number of GPUs claimed. 0 when the analysis runs on CPU.
system_memory_mib
pydantic-field
¶
Resolved peak system memory in MiB. Rendered to the container as its memory hint and to the orchestrator as the cgroup ceiling; under-claiming this is what gets an analysis OOM-killed.
wall_clock_seconds = None
pydantic-field
¶
How long this run may take before the platform stops it, resolved at submission from the platform's default for the recording's length and the configuration's ceiling, whichever is higher. None on a submission that predates the bound.
ResourceRequirements
pydantic-model
¶
Bases: BaseModel
Resource requirements for an analysis.
Memory needs are a sum of optional linear terms (all but base
default to 0, so each analysis opts into the terms matching how it loads
and holds signal data — no analysis is forced into another's shape):
peak_memory_mib =
base
+ per_hour * hours
+ per_hour_per_khz * hours * (max_sample_rate_hz / 1000)
+ per_hour_per_channel * hours * n_channels
+ per_hour_per_channel_per_khz
* hours * n_channels * (max_sample_rate_hz / 1000)
The per-channel term captures data at the analysis's fixed working rate
(one float32 full-signal copy at 128 Hz ~= 1.76 MiB/hour/channel); the
per-kHz term captures data held at the recording's native rate (one
float32 copy ~= 13.7 MiB/hour/channel/kHz) — e.g. the raw signal before an
analysis downsamples it. per_hour is for channel-independent buffers;
per_hour_per_khz for a channel-independent buffer at the native rate,
such as the working memory of resampling one channel at a time, which
every channel reuses.
The api-server uses :meth:estimate_peak_system_memory_mib /
:meth:estimate_peak_gpu_memory_mib at submission time to project the
expected memory consumption and passes it to the orchestrator as the
resource claim.
CPU is claimed in whole cores: cpu_cores is the parallelism the
analysis is written for. The platform reserves that many cores for the
run, passes the same number to the container as --cpus and as the
thread-count environment variables, and the container sizes its thread
pools to it. Thread pools do not look at cgroups, so a container that
starts more threads than it has cores is slower, not faster; the number
here is what keeps a full queue from over-subscribing the host. There is
no failure mode for too few cores, only a longer wall time, so no formula
or per-tier cap is needed.
Fields:
-
cpu_cores(PositiveInt) -
base_system_memory_mib(NonNegativeInt) -
per_hour_system_memory_mib(NonNegativeInt) -
per_hour_per_khz_system_memory_mib(NonNegativeInt) -
per_hour_per_channel_system_memory_mib(NonNegativeInt) -
per_hour_per_channel_per_khz_system_memory_mib(NonNegativeInt) -
base_gpu_memory_mib(NonNegativeInt) -
per_hour_gpu_memory_mib(NonNegativeInt) -
per_hour_per_channel_gpu_memory_mib(NonNegativeInt) -
per_hour_per_channel_per_khz_gpu_memory_mib(NonNegativeInt) -
artifacts_memory_mib(NonNegativeInt) -
per_hour_artifacts_memory_mib(NonNegativeInt) -
gpus(NonNegativeInt) -
wall_clock(WallClockCeiling | None) -
gpu_required(bool)
Validators:
-
_legacy_cpu_mhz
artifacts_memory_mib = 0
pydantic-field
¶
Disk space (in MiB) reserved for output artifacts. Added to the size of any input recording files to determine the total disk requirement.
base_gpu_memory_mib = 0
pydantic-field
¶
Constant term of the GPU-memory formula. Set to 0 if the analysis does not require a GPU.
base_system_memory_mib
pydantic-field
¶
Constant term of the system-memory formula: covers fixed overhead (model weights, ONNX runtime, Python, preprocessing libraries) before any signal data is loaded.
cpu_cores
pydantic-field
¶
Whole CPU cores the analysis is written to use in parallel. Reserved for the run and passed to the container as --cpus and as the thread-count environment variables; size thread pools to it.
gpu_required = False
pydantic-field
¶
Whether GPUs are mandatory or optional for the analysis.
gpus = 0
pydantic-field
¶
The number of GPUs required for the analysis. Set to 0 if the analysis does not require a GPU.
per_hour_artifacts_memory_mib = 0
pydantic-field
¶
Disk space (in MiB) added per signal hour for output artifacts.
per_hour_gpu_memory_mib = 0
pydantic-field
¶
GPU MiB per signal hour, independent of channel count. 0 if N/A.
per_hour_per_channel_gpu_memory_mib = 0
pydantic-field
¶
GPU MiB per signal hour per selected channel (at the working rate). 0 if the analysis needs no GPU or its GPU memory doesn't scale with length x channels.
per_hour_per_channel_per_khz_gpu_memory_mib = 0
pydantic-field
¶
GPU MiB per signal hour per channel per kHz of the native sample rate. 0 if the analysis doesn't hold native-rate signal on the GPU.
per_hour_per_channel_per_khz_system_memory_mib = 0
pydantic-field
¶
System MiB per signal hour per channel per kHz of the recording's NATIVE sample rate — data held at native rate before downsampling (a float32 copy is ~13.7 MiB/h/ch/kHz). 0 if the analysis doesn't hold native-rate signal.
per_hour_per_channel_system_memory_mib = 0
pydantic-field
¶
System MiB per signal hour per selected channel, at the analysis's fixed WORKING sample rate (a float32 full-signal copy at 128 Hz is ~1.76 MiB/h/ch). 0 if system memory does not scale with length x channels.
per_hour_per_khz_system_memory_mib = 0
pydantic-field
¶
System MiB per signal hour per kHz of the recording's NATIVE sample rate, independent of channel count: a buffer at native rate that the channels use one at a time, such as the working memory of resampling. 0 if not applicable.
per_hour_system_memory_mib = 0
pydantic-field
¶
System MiB per signal hour, independent of channel count (e.g. a channel-independent results/accumulator buffer). 0 if not applicable.
wall_clock = None
pydantic-field
¶
A wall-clock ceiling raised above the platform's default, with the reason. A platform decision made at registration; an author leaves it out.
estimate_peak_artifacts_memory_mib(hours)
¶
Project disk space (in MiB) for output artifacts.
estimate_peak_gpu_memory_mib(hours, n_channels, max_sample_rate_hz)
¶
Project peak GPU memory in MiB for an analysis of the given size.
Same optional-term structure as :meth:estimate_peak_system_memory_mib.
estimate_peak_system_memory_mib(hours, n_channels, max_sample_rate_hz)
¶
Project peak system memory in MiB for an analysis of the given size.
Sum of the optional linear terms (see the class docstring):
base + per_hour*h + per_hour_per_khz*h*(max_sample_rate_hz/1000)
+ per_hour_per_channel*h*c
+ per_hour_per_channel_per_khz*h*c*(max_sample_rate_hz/1000).
max_sample_rate_hz is the maximum native sample rate across the
selected channels (it only feeds the per-kHz terms). Rounded up so the
orchestrator never gets a value below the projection.
max_hours_within_system_memory(memory_mib, n_channels, max_sample_rate_hz)
¶
Return the longest recording whose projected peak fits memory_mib.
The inverse of :meth:estimate_peak_system_memory_mib for a given channel
count and native rate: (memory - base) / (the formula's per-hour
slope). None when nothing scales with length, so any length fits
once the base does; 0.0 when even the base does not fit.
ResourceUsage
pydantic-model
¶
Bases: BaseModel
Response model for the get_usage_stats endpoint.
Fields:
-
projects(UsageCount) -
studies(UsageCount) -
recordings(UsageCount) -
analyses(UsageCount) -
reports(UsageCount) -
analysis_hours(UsageHours) -
storage(UsageBytes)
analyses
pydantic-field
¶
The total number of analyses created by the user.
analysis_hours
pydantic-field
¶
Analysis hours usage information.
projects
pydantic-field
¶
The total number of projects created by the user.
recordings
pydantic-field
¶
The total number of recordings created by the user.
reports
pydantic-field
¶
The total number of reports created by the user.
storage
pydantic-field
¶
Storage usage information.
studies
pydantic-field
¶
The total number of studies created by the user.
is_within_limit(limit)
¶
Check if the usage represented by this model is within a set of usage limits.
Calls the is_within_limit method on each of the UsageBase fields in this model and returns True if all of them return True and False otherwise. Also returns a list of field names indicating which limits are exceeded if any.
ResultAttestations
pydantic-model
¶
Bases: BaseModel
What ran, on what, as the runner states it.
Config:
extra:forbid
Fields:
-
image_digest(str) -
input_sha256(list[Annotated[str, Field(pattern=_SHA256_HEX)]]) -
runner_version(str) -
input_sizes(list[Annotated[int, Field(ge=0)]] | None) -
input_etags(list[Annotated[str, Field(max_length=256)] | None] | None)
input_etags = None
pydantic-field
¶
Each input's ETag as its storage answered the fetch, in the order of input_sha256, or null where it gave none. Older runners leave it out.
input_sizes = None
pydantic-field
¶
Each input's size in bytes as fetched, in the order of input_sha256. Older runners leave it out.
RunPlacement
pydantic-model
¶
Bases: BaseModel
Where a submission would run, and what that does to its price.
Every analysis of an organisation runs in one place, set for the organisation: on the platform, or at its site.
Config:
frozen:True
Fields:
-
place(RunPlace) -
site_factor(float | None) -
runner_seen(bool)
Validators:
-
_a_factor_only_at_a_site
place
pydantic-field
¶
On the platform, or at the organisation's own site.
runner_seen
pydantic-field
¶
Whether a runner of the place's pool asked for work in the last three minutes. While none has, a submission waits in the queue, and is withdrawn after the queue timeout.
site_factor = None
pydantic-field
¶
The factor on the platform price the quoted credits include, for a run at the site; null on the platform.
RunRecordListResponse
pydantic-model
¶
Bases: PaginatedResponse
A page of run records, newest first.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
items(list[RunRecordOut])
RunRecordOut
pydantic-model
¶
Bases: BaseModel
Where a job ran and on what, as its runner attested it.
One per accepted result, of every kind of job. It names the job's subject as its lease did: the analysis an analysis ran, the recording an ingest read, or the object a delete removed from an organisation's bucket, and that bucket's storage location.
Fields:
-
kind(LeaseKind) -
analysis_id(UUID7 | None) -
recording_id(UUID | None) -
object_url(str | None) -
storage_location_id(UUID | None) -
lease_id(UUID7) -
pool_id(UUID7) -
runner_id(UUID7) -
runner_version(str) -
image_digest(str | None) -
input_sha256(list[str]) -
output_sha256(str | None) -
peak_memory_mib(int | None) -
duration_seconds(float | None) -
recorded_at(datetime)
analysis_id = None
pydantic-field
¶
An analysis's.
image_digest
pydantic-field
¶
The digest of the image that ran, as the runner pulled it.
input_sha256
pydantic-field
¶
The inputs, as the runner read them.
object_url = None
pydantic-field
¶
A delete's.
output_sha256
pydantic-field
¶
The document the job uploaded, as the platform read it: an analysis's events, an ingest's reading.
peak_memory_mib
pydantic-field
¶
The container's peak memory, as it recorded it on exit.
recording_id = None
pydantic-field
¶
An ingest's.
storage_location_id = None
pydantic-field
¶
A delete's.
RunnerApproveRequest
pydantic-model
¶
Bases: BaseModel
Approve a pending runner.
The fingerprint is the one the administrator compared with the runner's host. The platform refuses the approval when it differs from the enrolled key's, so an approval cannot land on another runner by mistake.
Config:
extra:forbid
Fields:
-
fingerprint(str)
RunnerCapacity
pydantic-model
¶
Bases: BaseModel
Room on a runner: cores and memory.
Config:
extra:forbid
Fields:
-
cores(float) -
memory_mib(int)
RunnerEnrolRequest
pydantic-model
¶
Bases: BaseModel
What a runner sends to enrol. The request is signed with the new key.
Config:
extra:forbid
Fields:
-
token(str) -
name(str) -
public_key(str) -
version(str) -
capacity(RunnerCapacity)
Validators:
-
_is_an_ed25519_key→public_key
RunnerEnrolResponse
pydantic-model
¶
Bases: BaseModel
The enrolled runner, as it asks after itself.
Fields:
-
runner_id(UUID7) -
state(RunnerState) -
fingerprint(str)
fingerprint
pydantic-field
¶
The runner key's fingerprint, as the platform computed it.
RunnerListResponse
pydantic-model
¶
Bases: PaginatedResponse
A page of runners, and what applies to every runner.
The page answers before a pool has its first runner, so it carries the runner image a new runner installs: an install command can be shown before any enrolment token exists.
Fields:
-
total(NonNegativeInt) -
offset(NonNegativeInt) -
limit(PositiveInt) -
items(list[RunnerOut]) -
quarantine_after_failures(PositiveInt) -
runner_image(str | None)
quarantine_after_failures
pydantic-field
¶
Failures in a row that quarantine a runner.
RunnerOut
pydantic-model
¶
Bases: BaseModel
A runner as administrators see it.
Fields:
-
id(UUID7) -
pool_id(UUID7) -
name(str) -
state(RunnerState) -
fingerprint_hint(str) -
version(str) -
capacity(RunnerCapacity) -
held(NonNegativeInt) -
booked_cores(NonNegativeFloat) -
booked_memory_mib(NonNegativeInt) -
failures_in_a_row(NonNegativeInt) -
quarantined_at(datetime | None) -
last_seen_at(datetime | None) -
taking_work(bool) -
created_at(datetime) -
approved_at(datetime | None) -
revoked_at(datetime | None)
booked_cores
pydantic-field
¶
Cores its held jobs book, out of its capacity's cores.
booked_memory_mib
pydantic-field
¶
Memory its held jobs book, out of its capacity's memory.
failures_in_a_row
pydantic-field
¶
Jobs given back in a row, on their first try, for a fault that points at the runner's host: an image that would not pull or verify, an input that would not download, or an error from the container runtime. A job given back for another reason, such as an image the registry says it does not have, leaves it as it is; any other result resets it. At the limit in the list's quarantine_after_failures the runner is quarantined.
fingerprint_hint
pydantic-field
¶
The last characters of the key's fingerprint. Approval needs the whole fingerprint, read on the runner's host.
held
pydantic-field
¶
Jobs the runner holds now, starting or running.
taking_work = False
pydantic-field
¶
Whether the platform counts the runner as taking work: it is approved, not quarantined, and asked for work in the last three minutes. False from a server that predates it.
SectionLayoutEntry
pydantic-model
¶
Bases: BaseModel
One section of the user-configurable report layout.
Fields:
columns = None
pydantic-field
¶
The stored selection for this entry: COLUMN keys for event/project stats tables, ROW (metric) keys for biomarker and biomarker-summary tables (their curated set is rows), and row/series names for chart entries. None = the curated default set. Carried in the layout document, so exports honor the page's selection.
key
pydantic-field
¶
The layout document holds two entry kinds. SECTION entries name a key of the report's served sections (the SECTION_KEY_/SECTION_PREFIX_ vocabulary in this module), such as 'statistics-window', 'hypnogram:{analysis_id}', 'event-stats:{analysis_id}', 'family-comparison:{family}' or 'stats-card:{config_id}'. A figure section ('chart:{chart_key}') also carries which of its rows show. PRESENTATION entries carry a selection but name no section: 'chart-groups' (the group-legend series filter). Keys a renderer does not know are ignored; a section the layout does not mention takes its served default visibility.
visible
pydantic-field
¶
Whether the section appears in the report.
ServerApiKeyLimits
pydantic-model
¶
Bases: BaseModel
The API-key policy a deployment enforces, for clients that create keys.
All zero means the server did not report it (older API).
Fields:
-
max_ttl_days(int) -
default_ttl_days(int) -
max_active_per_user(int)
ServerBatchLimits
pydantic-model
¶
Bases: BaseModel
Maximum item counts accepted by the batch endpoints, per request.
The same numbers the request schemas state as maxItems, served so a
client can read them at runtime without parsing the schema; the server
enforces exactly these.
Fields:
-
max_analysis_submissions(int) -
max_studies(int) -
max_event_analysis_ids(int) -
max_cancel_analysis_ids(int) -
max_analysis_status_ids(int) -
max_recording_detail_ids(int) -
max_recordings_by_study_ids(int) -
max_study_ids(int) -
max_channel_patches(int)
max_analysis_status_ids
pydantic-field
¶
Max analysis IDs in one batch status poll
max_analysis_submissions
pydantic-field
¶
Max targets × pipeline steps in one batch analysis submission
max_cancel_analysis_ids
pydantic-field
¶
Max analysis IDs in one batch cancellation
max_channel_patches
pydantic-field
¶
Max patches in one bulk channel patch
max_event_analysis_ids
pydantic-field
¶
Max analysis IDs in one batch event retrieval
max_recording_detail_ids
pydantic-field
¶
Max recording IDs in one batch details retrieval
max_recordings_by_study_ids
pydantic-field
¶
Max study IDs in one batch recordings-by-study retrieval
max_studies
pydantic-field
¶
Max studies in one batch study creation
max_study_ids
pydantic-field
¶
Max study IDs in one batch studies-by-id retrieval
contract()
classmethod
¶
Return the caps as the request schemas state them.
ServerFeaturesEnabled
pydantic-model
¶
Bases: BaseModel
Global server features that are enabled or disabled.
Fields:
-
login(bool) -
registration(bool) -
require_approval(bool) -
selectable_usage_types(list[UsageType]) -
assignable_usage_types(list[UsageType]) -
email_verification(bool) -
demo_datasets(bool) -
uploads(bool) -
submissions(bool) -
password_policy(PasswordPolicy)
assignable_usage_types
pydantic-field
¶
Usage types that may be held by a user AT ALL, admins included — a superset of selectable_usage_types. Derived, not configured: a usage type is assignable only if a LICENCE DOCUMENT exists for it, because holding one means being gated onto that licence. CLINICAL is absent until a clinical licence is published. Admin UIs should offer exactly this list.
demo_datasets
pydantic-field
¶
Whether demo dataset registration is available (requires local storage backend)
email_verification
pydantic-field
¶
Whether email verification is enabled
login
pydantic-field
¶
Whether user login is enabled
password_policy
pydantic-field
¶
The password length policy the server enforces at registration — clients should validate/hint against these bounds rather than hardcoding them.
registration
pydantic-field
¶
Whether user registration is enabled
require_approval
pydantic-field
¶
Whether self-registrations require admin approval before login (request-access mode). When true, the client should frame sign-up as 'request access' and tell the user their account is pending after registering.
selectable_usage_types
pydantic-field
¶
Usage types a REGISTRANT may currently choose. A policy list — narrower than what may exist at all (see assignable_usage_types), e.g. COMMERCIAL is withheld from sign-up while it is offered by arrangement only. The client should grey out any UsageType not in this list; the server also rejects them.
submissions = True
pydantic-field
¶
Whether analyses may be submitted right now. As for uploads: a bounded, operator-set suspension, reported here so the submit surfaces can say so.
uploads = True
pydantic-field
¶
Whether recordings may be registered right now. An operator may suspend uploads platform-wide for a bounded time; a client that reads false should say so instead of offering the upload and expecting a refusal.
ServerLimits
pydantic-model
¶
Bases: BaseModel
Server request limits relevant to clients.
The batch caps are contract constants (the request schemas' maxItems);
the upload ceilings are deployment configuration. Both are distinct from
per-user usage quotas, which are exposed via /history/usage/limits.
Fields:
-
batch(ServerBatchLimits) -
max_upload_bytes(int) -
api_keys(ServerApiKeyLimits) -
recording_formats(list[FileFormat])
api_keys
pydantic-field
¶
The API-key lifetime and count policy in force.
batch
pydantic-field
¶
Per-request item caps for the batch endpoints
max_upload_bytes
pydantic-field
¶
Maximum size (bytes) of a single recording (register -> presigned PUT -> finalize). Clients should validate against this rather than hardcoding a cap a config change could invalidate.
recording_formats
pydantic-field
¶
The formats a recording may be uploaded in, matched on the file extension (the format's value, e.g. edf). Filter a file picker and validate against this rather than hardcoding a list; the server refuses any other format at registration.
ServerVersionInfo
pydantic-model
¶
Bases: BaseModel
Server version information.
Contains version information for the API server and common module.
Fields:
-
api_version(str) -
common_version(str)
SignalWindow
pydantic-model
¶
Bases: BaseModel
Signal window model.
Represents a window of time in a signal with an offset start and end time relative to the beginning of the recording. Can be used to specify a subset of a signal or events in a signal.
Fields:
-
window_start_time_ms(NonNegativeInt | None) -
window_end_time_ms(NonNegativeInt | None)
Validators:
duration_ms
property
¶
Calculate the duration of the signal in milliseconds.
window_end_time_ms = None
pydantic-field
¶
End of the signal in milliseconds relative to the beggining of the recording. Defaults None indicating to the end of the recording if not specified.
window_start_time_ms = 0
pydantic-field
¶
Start of the signal in milliseconds relative to the beggining of the recording. Defaults to 0 if not specified.
__hash__()
¶
Hash by JSON serialisation (:func:_json_hash).
validate_time_order()
pydantic-validator
¶
Validate that start time is less than end time.
SiteAgreementAccept
pydantic-model
¶
SiteAgreementAcceptance
pydantic-model
¶
Bases: BaseModel
An acceptance of the site agreement, as recorded.
Fields:
-
org_id(UUID) -
version(int) -
accepted_by(UUID | None) -
accepted_by_name(str | None) -
accepted_at(datetime)
SiteAllowance
pydantic-model
¶
Bases: BaseModel
Where the caller's organisation may run an analysis.
The platform runs every analysis. An organisation's own site runs one whose configuration allows a site, or one that an exception in force covers for the organisation. The quote and the submission apply the same rule; this says what it gives before either is asked.
Config:
frozen:True
Fields:
-
place(RunPlace) -
runs_there(bool) -
allowed_at_site(bool) -
by_exception(bool)
allowed_at_site
pydantic-field
¶
Whether the organisation may run the analysis at its own site: its configuration allows a site, or an exception in force covers it for the organisation.
by_exception
pydantic-field
¶
Whether only an exception in force allows it at the site: the configuration itself keeps the analysis on the platform.
place
pydantic-field
¶
Where the organisation's analyses run now: on the platform, or at its own site.
runs_there
pydantic-field
¶
Whether the analysis may run there. On the platform it always may; at the site, when allowed_at_site is true. Where it may not, the quote and the submission refuse it.
SiteExceptionCreate
pydantic-model
¶
Bases: BaseModel
A platform administrator's record that an organisation may run a platform-only analysis at its site.
It covers every version of the analysis until it expires or is revoked.
Fields:
-
analysis_config_id(AnalysisConfigIdStr) -
agreement_reference(str) -
expires_at(datetime)
SiteExceptionOut
pydantic-model
¶
Bases: BaseModel
One record of an exception: recorded, or revoked.
Records only grow. The latest for an organisation and an analysis is its state: in force while it is recorded, not revoked, and unexpired.
Fields:
-
id(UUID) -
org_id(UUID) -
analysis_config_id(str) -
revoked(bool) -
agreement_reference(str | None) -
expires_at(datetime | None) -
reason(str | None) -
recorded_by(UUID) -
recorded_at(datetime) -
in_force(bool)
agreement_reference = None
pydantic-field
¶
The agreement it rests on; None on a revocation.
expires_at = None
pydantic-field
¶
When it ends; None on a revocation.
in_force
pydantic-field
¶
Whether this record is the latest for its analysis, is not a revocation, and has not expired.
reason = None
pydantic-field
¶
Why it was revoked; None when recorded.
recorded_by
pydantic-field
¶
The administrator who recorded it.
revoked
pydantic-field
¶
Whether this record revokes the exception.
SiteExceptionPage
pydantic-model
¶
Bases: BaseModel
A page of an organisation's exception records, newest first.
Fields:
-
exceptions(list[SiteExceptionOut]) -
total(int)
SiteExceptionRevoke
pydantic-model
¶
SlotDefinition
pydantic-model
¶
Bases: BaseModel
An ordered, labelled input position of the analysis and the channel that fills it.
Config:
extra:forbidfrozen:True
Fields:
-
label(str) -
laterality(ChannelLaterality | None) -
channel_index(NonNegativeInt)
Validators:
-
_drop_legacy_derivation
StagePercentages
pydantic-model
¶
Bases: BaseModel
Stage percentages of total sleep time (N1–N3, REM) and time in bed (Wake).
Each description is the metric's definition as the platform computes it, served as its help text; the sleep stages are empty (None) when no sleep is scored, since a share of zero sleep is undefined rather than 0%.
Fields:
-
n1_pct(float | None) -
n2_pct(float | None) -
n3_pct(float | None) -
rem_pct(float | None) -
wake_pct(float)
n1_pct = None
pydantic-field
¶
N1 time as a percentage of total sleep time (TST). Empty when no sleep is scored.
n2_pct = None
pydantic-field
¶
N2 time as a percentage of total sleep time (TST). Empty when no sleep is scored.
n3_pct = None
pydantic-field
¶
N3 time as a percentage of total sleep time (TST); Rechtschaffen & Kales stages 3 and 4 both count as N3. Empty when no sleep is scored.
rem_pct = None
pydantic-field
¶
REM time as a percentage of total sleep time (TST). Empty when no sleep is scored.
wake_pct
pydantic-field
¶
Wake time as a percentage of time in bed (TIB), not of TST as for the sleep stages. Epochs scored as no stage (unscored, movement time) count toward TIB only, so wake and the sleep stages' share of TIB need not add up to 100%.
StatisticsWindow
pydantic-model
¶
Bases: BaseModel
The time window used for TIB-based statistics computation.
Resolved from study events (lights off/on), client override, or full recording. The source field tells the frontend how the window was determined.
Fields:
-
start_time_ms(int) -
end_time_ms(int) -
source(WindowSource)
StepInputCoverage
pydantic-model
¶
Bases: BaseModel
What one step's recordings offer of the inputs its analysis declares.
Fields:
-
step_id(str) -
recordings(NonNegativeInt) -
complete(NonNegativeInt) -
inputs(list[InputCoverage])
StorageBucketReconciliation
pydantic-model
¶
Bases: BaseModel
One bucket's objects compared with the storage records that reference them.
Fields:
-
objects(int) -
tracked_live(int) -
missing(int) -
missing_sample(list[str]) -
untracked(int) -
untracked_sample(list[str]) -
awaiting_reap(int)
awaiting_reap
pydantic-field
¶
Objects referenced only by deleted records, still waiting to be removed.
missing
pydantic-field
¶
Live records whose object is gone. Anything above zero means stored data is lost and warrants immediate attention.
missing_sample
pydantic-field
¶
Some of the missing object keys, capped by the server.
objects
pydantic-field
¶
Objects in the bucket.
tracked_live
pydantic-field
¶
Live records that reference an object in the bucket. Records with a scheduled expiry are not counted.
untracked
pydantic-field
¶
Objects that no record references.
untracked_sample
pydantic-field
¶
Some of the untracked object keys, capped by the server.
StorageReconciliationNeverRun
pydantic-model
¶
Bases: BaseModel
The answer when no reconciliation report is stored.
Either none has run yet, or the last report has expired.
Fields:
-
status(Literal['never_run'])
StorageReconciliationReport
pydantic-model
¶
Bases: BaseModel
The last storage reconciliation.
Each data bucket's objects compared with the storage records, both ways. The report names drift and changes nothing; what to do about it is an operator's decision.
Fields:
-
timestamp(datetime) -
buckets(dict[str, StorageBucketReconciliation]) -
missing_total(int) -
untracked_total(int) -
duration_seconds(float)
buckets
pydantic-field
¶
The comparison for each bucket, by bucket name.
duration_seconds
pydantic-field
¶
How long the reconciliation took.
missing_total
pydantic-field
¶
Missing objects across all buckets.
timestamp
pydantic-field
¶
When the reconciliation ran.
untracked_total
pydantic-field
¶
Untracked objects across all buckets.
StratumCount
pydantic-model
¶
Bases: BaseModel
Cohort count for one stratum of a stratified report.
Fields:
-
label(str) -
study_count(int)
label
pydantic-field
¶
The stratum's group label, exactly as it appears on the report's stats entries and chart rows.
study_count
pydantic-field
¶
How many of the cohort fall in this stratum: distinct subjects when any study in scope carries a subject key, else studies — the same unit the report's demographics table counts.
StripeCheckoutSession
pydantic-model
¶
Bases: BaseModel
Represents minimal information on a stripe checkout session.
Fields:
fulfilled = False
pydantic-field
¶
Whether the session has been fulfilled by the API server, i.e., if the user made the purchase whether the product/credits has been assigned to the user's account yet
id
pydantic-field
¶
Unique ID of the stripe checkout session.
url
pydantic-field
¶
The URL the user is redirected to in order to complete the stripe session.
StripeCheckoutSessionCreate
pydantic-model
¶
Bases: BaseModel
Request a Stripe checkout session for one or more credit packages.
The redirect URLs are optional. When the server has a list of allowed application origins, each URL given must point to one of them.
Fields:
-
price_ids(list[str]) -
success_url(HttpUrl | None) -
cancel_url(HttpUrl | None)
cancel_url = None
pydantic-field
¶
Where Stripe returns the buyer when they cancel.
price_ids
pydantic-field
¶
Stripe price ids to purchase, one per package: the price_id of each credit package.
success_url = None
pydantic-field
¶
Where Stripe returns the buyer after payment. Required when the server has no configured application URL to fall back on.
StripePortalSession
pydantic-model
¶
StripePortalSessionCreate
pydantic-model
¶
Bases: BaseModel
Request a Stripe customer-portal session: purchase history and invoices.
Every field is optional; an empty body is a valid request.
Fields:
-
return_url(HttpUrl | None)
return_url = None
pydantic-field
¶
Where Stripe sends the user when they leave the portal. When the server has a list of allowed application origins, it must point to one of them.
StudyCreate
pydantic-model
¶
Bases: NamedEntityCreate, StudyMetadata
Create payload for a study. name is required.
Fields:
-
age(NonNegativeInt | None) -
bmi(PositiveFloat | None) -
sex(Sex | None) -
subject_key(SubjectKey | None) -
session_index(PositiveInt | None) -
tags(TagsSet | None) -
description(DescriptionStr | None) -
name(NameString)
StudyEvent
pydantic-model
¶
Bases: BaseModel
A study-level event (e.g. lights off/on).
Study events are definitionally certain — no probability or value fields. Times are milliseconds relative to the earliest recording start in the study.
Fields:
-
id(UUID) -
study_id(UUID) -
start_time_ms(NonNegativeInt) -
end_time_ms(NonNegativeInt) -
label(EventLabel) -
origin(StudyEventOrigin)
Validators:
validate_time_order()
pydantic-validator
¶
Validate that start time is less than or equal to end time.
StudyEventInput
pydantic-model
¶
Bases: BaseModel
Input for creating or upserting a study event.
Supports two input formats:
- Relative: provide start_time_ms and end_time_ms directly.
- Absolute: provide a datetime timestamp (converted to relative ms on
ingestion; aware datetimes resolve as instants, naive datetimes are
read in the recording's wall-clock frame — see timestamp).
Fields:
-
start_time_ms(NonNegativeInt | None) -
end_time_ms(NonNegativeInt | None) -
timestamp(datetime | None) -
label(EventLabel)
Validators:
timestamp = None
pydantic-field
¶
Absolute event time, converted to relative ms against the study's earliest recording start. Timezone-aware datetimes are resolved as instants; naive datetimes are interpreted in the recording's own wall-clock frame (recording starts carry a nominal UTC offset).
validate_input_format()
pydantic-validator
¶
Validate that exactly one input format is used.
StudyFilter
pydantic-model
¶
Bases: _FilterBase
Predicate over a project's studies; at least one field must be set.
Mirrors the study list endpoint's filter query parameters.
Fields:
-
tags_any(list[str] | None) -
name_contains(str | None) -
subject_key(str | None) -
missing_metadata_any(list[MetadataType] | None)
Validators:
-
_at_least_one_predicate
missing_metadata_any = None
pydantic-field
¶
Match studies that do not record at least one of these subject values.
name_contains = None
pydantic-field
¶
Match studies whose name contains this text (case-insensitive).
subject_key = None
pydantic-field
¶
Match every study of one subject — the key is compared case- and whitespace-insensitively. Deleting by this filter is how a subject's data is erased: the studies are the subject.
tags_any = None
pydantic-field
¶
Match studies carrying at least one of these tags.
StudyGroupSummary
pydantic-model
¶
StudyImportColumn
pydantic-model
¶
Bases: BaseModel
One column the import understands — drives auto-mapping and docs.
Fields:
-
key(str) -
kind(ColumnKind) -
aliases(list[str]) -
unit(str | None) -
description(str)
aliases
pydantic-field
¶
Lower-cased header spellings that auto-map to this column.
description
pydantic-field
¶
What the column sets.
key
pydantic-field
¶
Canonical column key (the API field name).
kind
pydantic-field
¶
Value shape, for parsing/validation.
unit = None
pydantic-field
¶
Display unit, if any.
StudyLightsAssignment
pydantic-model
¶
Bases: BaseModel
One study's lights markers.
Presence semantics as everywhere in this module: an absent marker is left unchanged, an explicit null DELETES the marker. At least one of the two must be present.
Fields:
-
study(str) -
lights_off(LightsInstant | None) -
lights_on(LightsInstant | None)
Validators:
-
_something_to_do
StudyLightsResult
pydantic-model
¶
Bases: BaseModel
Outcome for one lights row.
Fields:
-
study(str) -
study_id(UUID | None) -
status(Literal['updated', 'error']) -
lights_off_ms(int | None) -
lights_on_ms(int | None) -
error(BatchItemError | None)
StudyListResponse
pydantic-model
¶
StudyMetadata
pydantic-model
¶
Bases: BaseModel
A collection of optional metadata fields on a Study.
Fields:
-
age(NonNegativeInt | None) -
bmi(PositiveFloat | None) -
sex(Sex | None) -
subject_key(SubjectKey | None) -
session_index(PositiveInt | None)
age = None
pydantic-field
¶
Age of the subject in years
bmi = None
pydantic-field
¶
Body mass index of the subject
session_index = None
pydantic-field
¶
Declared position of this study in its subject's series, 1 = first. Set only by the user; never allocated by the server. Null means the position is derived from the order of recording starts within the subject; a study whose recording start is unknown cannot be placed that way and needs a declared index.
sex = None
pydantic-field
¶
Biological sex of the subject
subject_key = None
pydantic-field
¶
The person this study belongs to. Studies in one project sharing a key form that subject's series; the key is compared case- and whitespace-insensitively and is unique to nothing — it groups, it does not identify. Null for a study that stands alone, which is every study until a key is set.
StudyMetadataPatch
pydantic-model
¶
Bases: BaseModel
One study's metadata changes.
Field PRESENCE is the semantics: absent = unchanged, explicit null =
clear. Serialize with exclude_unset. Bounds match the canonical StudyMetadata (the batch-creation item is
harmonised to the same).
Fields:
-
study(str) -
age(NonNegativeInt | None) -
sex(Sex | None) -
bmi(PositiveFloat | None) -
subject_key(SubjectKey | None) -
session_index(PositiveInt | None)
Validators:
-
_something_to_do
session_index = None
pydantic-field
¶
Declared position in the subject's series; null derives it.
study
pydantic-field
¶
Study name or id. Names resolve within the project: 0 matches → not_found, >1 → conflict (rename or use ids).
subject_key = None
pydantic-field
¶
The subject this study belongs to; null detaches it.
StudyMetadataResult
pydantic-model
¶
Bases: BaseModel
Outcome for one metadata patch row.
Fields:
-
study(str) -
study_id(UUID | None) -
status(Literal['updated', 'error']) -
error(BatchItemError | None)
StudyOut
pydantic-model
¶
Bases: StudyCreate
Study information available to user.
Fields:
-
age(NonNegativeInt | None) -
bmi(PositiveFloat | None) -
sex(Sex | None) -
subject_key(SubjectKey | None) -
session_index(PositiveInt | None) -
tags(TagsSet | None) -
description(DescriptionStr | None) -
name(NameString) -
owner_id(UUID | None) -
id(UUID) -
project_id(UUID | None) -
created_at(datetime) -
recording_count(int) -
analyzed_count(int) -
analyses_count(int) -
total_duration_ms(int) -
first_recording_date(datetime | None) -
has_lights(bool | None) -
lights_off_ms(int | None) -
lights_on_ms(int | None)
analyses_count = 0
pydantic-field
¶
Total number of analyses
analyzed_count = 0
pydantic-field
¶
Recordings with >= 1 completed analysis
created_at
pydantic-field
¶
Creation timestamp of the study
first_recording_date = None
pydantic-field
¶
Earliest recording start across the study's recordings — when the night was recorded, as opposed to when it was uploaded (created_at). None when no recording carries a start time.
has_lights = None
pydantic-field
¶
Whether the study has lights off/on markers, i.e. its statistics will be lights-windowed. None when the producer did not compute it. Derivable from lights_off_ms/lights_on_ms where those are populated (kept for compatibility).
id
pydantic-field
¶
Unique identifier of the study
lights_off_ms = None
pydantic-field
¶
The lights-off marker, ms from the earliest recording start (first_recording_date is the clock frame). None = not set or not computed by the producer.
lights_on_ms = None
pydantic-field
¶
The lights-on marker, ms from the earliest recording start. None = not set or not computed by the producer.
owner_id = None
pydantic-field
¶
The member who added it. Only they, or the project's owner, may change or remove it; it passes to the project's owner when they leave the organization.
project_id = None
pydantic-field
¶
The project the study belongs to.
recording_count = 0
pydantic-field
¶
Number of recordings
total_duration_ms = 0
pydantic-field
¶
Total recording duration in ms
StudyRef
pydantic-model
¶
StudyReportResponse
pydantic-model
¶
Bases: BaseModel
Envelope for study-level report data.
Wraps event statistics with optional biomarkers and the statistics window used for TIB-based metric computation.
Fields:
-
event_stats(list[AnnotatedEventStats]) -
statistics_window(StatisticsWindow | None) -
biomarkers(list[BiomarkerResult] | None) -
warnings(list[str]) -
hypnograms(dict[str, HypnogramModel] | None) -
tables(list[TableModel] | None) -
credits(list[CreditedAnalysis]) -
sections(list[ReportSection])
biomarkers = None
pydantic-field
¶
Per-analysis biomarker results (None if not requested)
event_stats
pydantic-field
¶
Per-analysis event statistics
hypnograms = None
pydantic-field
¶
Server-computed hypnogram chart models keyed by analysis_id. None for producers predating the field.
statistics_window = None
pydantic-field
¶
The time window used for statistics (None if no window available)
tables = None
pydantic-field
¶
Server-defined tables: biomarker and event-metrics tables with formatting and semantic status computed once. None for producers predating the field.
warnings
pydantic-field
¶
Warnings about statistics computation
StudySelector
pydantic-model
¶
Bases: _SelectorBase
Address a set of studies: exactly one of ids | filter | all.
Fields:
-
ids(list[UUID] | None) -
all(bool) -
filter(StudyFilter | None)
Validators:
-
_exactly_one_mode
filter = None
pydantic-field
¶
Server-resolved predicate (live set).
StudySummary
pydantic-model
¶
Bases: BaseModel
What a project's studies hold, without listing them.
Tag and subject vocabularies with their counts, and the first studies of each set, so a picker or a breakdown needs one small answer at any project size.
Fields:
-
total(NonNegativeInt) -
tags(list[TagSummary]) -
untagged(StudyGroupSummary) -
excluded(StudyGroupSummary | None) -
subjects(list[SubjectSummary])
excluded = None
pydantic-field
¶
The studies carrying none of the requested tags_any; absent when none were requested.
subjects
pydantic-field
¶
Every subject in the project, by normalised key.
tags
pydantic-field
¶
Every tag in the project, the most studies first, then by tag.
total
pydantic-field
¶
How many studies the project holds.
untagged
pydantic-field
¶
The studies carrying no tag.
StudyUpdate
pydantic-model
¶
Bases: NamedEntityUpdate, StudyMetadata
PATCH payload for a study — all fields are optional.
See NamedEntityUpdate for the universal PATCH semantics
(omit-to-skip, include-to-set, null-to-clear).
Fields:
-
age(NonNegativeInt | None) -
bmi(PositiveFloat | None) -
sex(Sex | None) -
subject_key(SubjectKey | None) -
session_index(PositiveInt | None) -
tags(TagsSet | None) -
description(DescriptionStr | None) -
name(NameString | None)
SubjectSummary
pydantic-model
¶
SummaryStats
pydantic-model
¶
Bases: BaseSummaryStats
Summary statistics computed across a list of comparable events.
Extends BaseSummaryStats with event-specific fields (analysis type, event type).
Fields:
-
analysis_config_id(str) -
analysis_parameters(list[tuple[str, str | int | float | bool]]) -
stats(dict[str, DistributionStats]) -
origins(list[StatsOrigin]) -
origins_ref(str | None) -
origins_summary(OriginsSummary | None) -
analysis_type(AnalysisType) -
event_type(EventType)
TableCell
pydantic-model
¶
Bases: BaseModel
One cell: raw value for machines, formatted text for humans.
Fields:
detail = None
pydantic-field
¶
The value at full precision with its unit, for hover text, where text rounds it (e.g. '1h 35m 12s' behind '1h 35m'). None where text is exact.
status = None
pydantic-field
¶
Semantic status token ('caution'/'danger'); None = neutral. Consumers resolve to brand colors; unknown tokens render neutral.
text
pydantic-field
¶
The display string, formatted server-side.
value = None
pydantic-field
¶
Raw value (tooltips, sorting, data-*).
TableColumn
pydantic-model
¶
Bases: BaseModel
One column: identity, labeling, and the curated-default flag.
Fields:
align = 'right'
pydantic-field
¶
Cell alignment: 'left' for text, 'right' for numerals.
description = None
pydantic-field
¶
Optional plain-language definition of the column's metric, for hover/tooltip text.
key
pydantic-field
¶
Stable column identity (e.g. a metric key).
label
pydantic-field
¶
Header text.
summary = True
pydantic-field
¶
Whether this column belongs to the curated default set — a HINT; every column always ships and the user's client-side selection always wins.
unit = None
pydantic-field
¶
Unit suffix (e.g. 'min', '%'); None = unitless.
TableModel
pydantic-model
¶
Bases: BaseModel
A fully server-defined table.
key uses the report section-key vocabulary (report_export module),
so layout documents and exports address tables the same way pages do.
Fields:
-
key(str) -
title(str) -
subtitle(str) -
columns(list[TableColumn]) -
rows(list[TableRow]) -
total_rows(int | None)
columns
pydantic-field
¶
Column order is display order.
key
pydantic-field
¶
Stable table identity (section-key grammar).
rows
pydantic-field
¶
Row order is display order.
subtitle = ''
pydantic-field
¶
Optional subheading.
title
pydantic-field
¶
Human-readable table heading.
total_rows = None
pydantic-field
¶
Total rows in the underlying data when rows is a server-capped excerpt; renderers should show 'rows of total_rows' and offer the full download the producing endpoint documents. None when rows is complete.
TableRow
pydantic-model
¶
Bases: BaseModel
One row: a label plus cells keyed by column key.
Fields:
-
key(str) -
label(str) -
description(str | None) -
cells(dict[str, TableCell]) -
summary(bool) -
selection_key(str | None) -
selection_label(str | None)
cells
pydantic-field
¶
Cells keyed by TableColumn.key; a missing key renders as an em dash.
description = None
pydantic-field
¶
Optional plain-language definition of the row's metric, for hover/tooltip text (row-axis twin of TableColumn.description).
key
pydantic-field
¶
Stable row identity within the table.
label
pydantic-field
¶
Row header (e.g. an event type or metric).
selection_key = None
pydantic-field
¶
The key a row selection names, when it is not the row's own key: rows that repeat one metric per group or per event share it, so choosing the metric keeps it in every group.
selection_label = None
pydantic-field
¶
What a row picker calls selection_key: the metric's or event's name, listed once for every row that shares the key.
summary = True
pydantic-field
¶
Row-axis twin of TableColumn.summary, for tables whose curated set is rows (e.g. biomarker headline metrics).
TagSummary
pydantic-model
¶
TokenPair
pydantic-model
¶
Bases: AccessToken
Full token pair returned by login: access token plus refresh token.
(user_id and the access-token fields are inherited from AccessToken.)
Fields:
-
access_token(str) -
access_token_expires_utc_seconds(int) -
user_id(UUID7) -
refresh_token(str) -
refresh_token_expires_utc_seconds(int) -
consent_required(bool) -
pending_consents(list[PendingConsent])
UniqueChannel
pydantic-model
¶
Bases: BaseModel
A unique channel with its locations across recordings.
Fields:
-
channel_name(str) -
type(ChannelType | str) -
unit(PhysicalDimension | str) -
records(list[ChannelLocation]) -
identity(ChannelIdentitySummary | None)
channel_name
pydantic-field
¶
Name of the channel
identity = None
pydantic-field
¶
What these channels are, as stored on their rows (canonical name, side, and whether a person corrected any). None from a server that predates channel identity.
records
pydantic-field
¶
Locations where this channel appears
type
pydantic-field
¶
Type of the channel
unit
pydantic-field
¶
Physical unit of the channel
UploadedFile
pydantic-model
¶
Bases: BaseModel
An output the runner uploaded to its presigned URL.
Config:
extra:forbid
Fields:
-
container_path(str) -
sha256(str) -
size(int)
UsageBase
pydantic-model
¶
Bases: BaseModel
Base model for the UsageCount, UsageHours, and UsageBytes models.
The all_time field represents the total number of items counted over the lifetime of the account. The active field represents the total number of items actively in use by the user.
The fields can be non-negative integers or floats. The special case of None is also allowed to represent an unlimited resource when the UsageBase class is used to represent a set of limits on a resource instead of usage statistics. The increment and decrement methods cannot be used when the fields are None.
Fields:
-
all_time(NonNegativeFloat | NonNegativeInt | None) -
active(NonNegativeFloat | NonNegativeInt | None)
active
pydantic-field
¶
Total number of items actively in use by the user.
all_time
pydantic-field
¶
Total number of items counted over the lifetime of the account.
is_within_limit(limit)
¶
Check if the usage represented by this model is within a set of usage limits.
Check if the usage represented by this model is within a set of usage limits represented by the 'limit' model. The usage is satisfied if the all_time and active values in this model are less than or equal to the corresponding values in the 'limit' model or if the corresponding value in the limit model is None.
Examples:
- if the all_time value in this model is 10 and the all_time value in the 'limit' model is 20, then this method will return True.
- If the active value in this model is 10 and the active value in the 'limit' model is None, then this method will return True.
- If the active value in this model is 10 and the active value in the 'limit' model is 5, then this method will return False.
UsageBytes
pydantic-model
¶
UsageCount
pydantic-model
¶
UsageHours
pydantic-model
¶
Bases: UsageBase
Represents the number of hours of signal data processed by an analysis for a given user.
Fields:
UserAuthentication
pydantic-model
¶
UserFriendlyNamedValue
pydantic-model
¶
Bases: BaseModel
Value with a user friendly name.
This is used to represent a value that can be presented to the user in a user-friendly way with a description of the value.
Fields:
-
value(str | int | float) -
description(str)
UserInformation
pydantic-model
¶
Bases: BaseModel
Profile/vetting fields for a user.
All optional at this level so response models (UserOut/AdminUserOut)
can be built from existing accounts that predate these fields.
UserRegistration overrides the request-access fields as required.
Fields:
-
name(None | str) -
organization(None | str) -
position(None | str) -
usage_type(UsageType | None) -
purpose(None | str)
name = None
pydantic-field
¶
The user's name, as they wish to be addressed.
organization = None
pydantic-field
¶
The organization, lab, or company the user is affiliated with (or 'Independent').
position = None
pydantic-field
¶
The user's position/role in their organization.
purpose = None
pydantic-field
¶
What the user plans to use the platform for — the basis for request-access review.
usage_type = None
pydantic-field
¶
The user's primary intended use of the platform.
UserOrganizationOut
pydantic-model
¶
Bases: BaseModel
The caller's organization, as the caller sees it.
A member-level view: identity, the caller's own role and membership, and
the seat picture. Admin-only organization details (overrides, insolvency
state) stay on :class:Organization behind the admin endpoints.
Every account belongs to exactly one organization: the one created for it at sign-up, or the one it joined by invitation. Projects, credits and storage all belong to it.
Config:
frozen:True
Fields:
-
id(UUID) -
name(str) -
role(MembershipRole) -
membership_id(UUID | None) -
member_count(int) -
seat_limit(int | None) -
study_limit(int | None) -
project_limit(int | None) -
storage_ceiling_gb(float | None) -
analyses_at_site(bool) -
recordings_at_site(bool) -
created_at(datetime) -
project_count(int)
analyses_at_site = False
pydantic-field
¶
Whether the organization's analyses run at its site, on its own runners, instead of on the platform.
created_at
pydantic-field
¶
When the organization was created
id
pydantic-field
¶
Unique identifier of the organization
member_count = 1
pydantic-field
¶
Members of the organization, the caller included.
membership_id = None
pydantic-field
¶
The caller's membership in this organization; the id to address when leaving it.
name
pydantic-field
¶
Display name of the organization
project_count = 0
pydantic-field
¶
Projects in the organization. On accepting an invitation elsewhere they come along, private.
project_limit = None
pydantic-field
¶
Projects the organization may hold; null when unlimited.
recordings_at_site = False
pydantic-field
¶
Whether the organization's new projects keep their recordings in its own bucket.
role
pydantic-field
¶
The caller's role in this organization.
seat_limit = None
pydantic-field
¶
Members plus pending invitations the organization may hold; null when unlimited.
storage_ceiling_gb = None
pydantic-field
¶
The storage the organization may use, in GB. The ceiling in force, not an override.
study_limit = None
pydantic-field
¶
Studies one of the organization's projects may hold.
UserOut
pydantic-model
¶
Bases: UserInformation
User output/response model.
Extends :class:UserInformation so users can see their own profile
(name/organization/position/usage_type/purpose — e.g. the account page
shows which licence their usage type requires). All profile fields stay
optional (accounts may predate them).
Config:
from_attributes:True
Fields:
-
name(None | str) -
organization(None | str) -
position(None | str) -
usage_type(UsageType | None) -
purpose(None | str) -
id(UUID7) -
permissions(list[Permission]) -
role(Role) -
email(EmailStr) -
email_confirmed_at(datetime | None) -
approved_at(datetime | None) -
consent_required(bool) -
pending_consents(list[PendingConsent]) -
has_billing_account(bool) -
organization_id(UUID | None) -
organization_name(str | None) -
organization_role(MembershipRole | None)
approved_at = None
pydantic-field
¶
Timestamp when an admin approved the account (request-access flow). Null means the registration is still pending approval and login is blocked; distinct from disabled, which bans an already-approved account.
consent_required = False
pydantic-field
¶
True if the user must accept one or more legal documents before protected endpoints will authorize.
email
pydantic-field
¶
Email address of the user.
email_confirmed_at = None
pydantic-field
¶
Timestamp when the user's email was confirmed.
has_billing_account = False
pydantic-field
¶
Whether the user has a billing account with the payment provider, made when they first bought credits. Their purchase history and receipts can be opened only then; buying for an organization does not give its other members one.
id
pydantic-field
¶
Unique identifier of the user
organization_id = None
pydantic-field
¶
The organization the account belongs to (every account belongs to exactly one). Distinct from organization, the free-text affiliation on the profile.
organization_name = None
pydantic-field
¶
The display name of the organization the account belongs to.
organization_role = None
pydantic-field
¶
The account's role in that organization: owner, admin or member.
pending_consents
pydantic-field
¶
Documents (and versions) the user must still accept.
permissions = []
pydantic-field
¶
List of permissions assigned to the user.
role = Role.USER
pydantic-field
¶
The user's authorization role (user or admin). Distinct from billing; governs what the user may do.
UserProfileUpdate
pydantic-model
¶
Bases: BaseModel
Self-service profile update (account page).
Omitted (None) fields are left unchanged. name cannot be blanked —
accounts that have a name keep one; position may be cleared by sending
an empty string. Email/password changes go through their dedicated,
verified flows, and usage_type changes are admin-mediated (they switch
the licence the user must consent to).
Fields:
-
name(Annotated[str, Field(max_length=100), StripAndRequire] | None) -
position(str | None)
UserRegistration
pydantic-model
¶
Bases: UserAuthentication, UserInformation
Model for self-registration (request access).
Overrides the vetting fields inherited from UserInformation as required:
a request-access application must identify who is asking and why. position
stays optional. Whether usage_type values are currently selectable (e.g.
CLINICAL is not) is enforced by the api-server, not this schema.
Fields:
-
position(None | str) -
email(EmailStr) -
password(NewPasswordStr) -
name(str) -
organization(str) -
usage_type(UsageType) -
purpose(str) -
accepts(list[ConsentAcceptItem])
accepts
pydantic-field
¶
Legal documents accepted at registration (document + version). The server records these and validates the versions.
name
pydantic-field
¶
The user's name, as they wish to be addressed. A single name is fine — no first/last split is required.
organization
pydantic-field
¶
The organization, lab, or company the user is affiliated with. Use 'Independent' if none. The part before the first comma also names the organization created for the account, cut to 64 characters at a word boundary when longer; the full text stays on the profile.
password
pydantic-field
¶
The password of the user. Must be at least 8 characters long and at most 72 bytes (bcrypt's limit). Other requirements are enforced by the backend.
purpose
pydantic-field
¶
What the user plans to use the platform for — the basis for request-access review.
usage_type
pydantic-field
¶
The user's primary intended use of the platform.
VerificationEmailRequest
pydantic-model
¶
WalletBalance
pydantic-model
¶
Bases: BaseModel
One of an organization's two credit balances.
Config:
from_attributes:Truefrozen:True
Fields:
WalletQuote
pydantic-model
¶
Bases: BaseModel
What a quoted cost asks of one balance.
Research analyses are paid from grants, commercial ones from
purchased; blocked_reason is set when that balance cannot cover the
cost. The client should then point to applying for a research grant
(grants) or to buying credits (purchased) rather than submitting.
Config:
frozen:True
Fields:
-
wallet(CreditBucket) -
estimated_credits(NonNegativeInt) -
available_credits(NonNegativeInt) -
balance_after(int) -
blocked_reason(Literal['insufficient_credits'] | None)
available_credits
pydantic-field
¶
Credits this balance has for new analyses (balance − held).
balance_after
pydantic-field
¶
available_credits − estimated_credits. Negative iff the submission would be rejected for insufficient credits.
blocked_reason = None
pydantic-field
¶
Why the submission would be rejected, or null if this balance covers it.
estimated_credits
pydantic-field
¶
Credits the analyses will cost from this balance (== the settled charge for the same inputs).
wallet
pydantic-field
¶
The balance that pays: grants or purchased.