{"openapi":"3.1.0","info":{"title":"kernoid","description":"Administration API of kernoid.","license":{"name":"AGPL-3.0-or-later","identifier":"AGPL-3.0-or-later"},"version":"0.1.0"},"paths":{"/healthz":{"get":{"tags":["health"],"summary":"Liveness: the process runs. Says nothing about its dependencies, so an orchestrator does not restart every\nprocess when the database is away.","operationId":"live","responses":{"200":{"description":"the process runs","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/readyz":{"get":{"tags":["health"],"summary":"Readiness: PostgreSQL and object storage answer. Details of failures go to the log, not to the caller.","operationId":"ready","responses":{"200":{"description":"ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Readiness"}}}},"503":{"description":"a dependency does not answer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Readiness"}}}}}}},"/v1/account":{"patch":{"tags":["account"],"summary":"Changes the display name of one's own account.","operationId":"change_profile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}},"required":true},"responses":{"204":{},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/app-passwords":{"get":{"tags":["account"],"summary":"The app passwords of one's own account (never the passwords themselves).","operationId":"list","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AppPasswordView"}}}}}}},"post":{"tags":["account"],"summary":"Makes an app password for one's own account (needs a recent login); the answer holds it, this once.","operationId":"add","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppPasswordName"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppPasswordCreated"}}}},"401":{"description":"no recent login","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/app-passwords/{id}":{"delete":{"tags":["account"],"summary":"Removes an app password of one's own account: the program using it can no longer log in.","operationId":"remove","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"removed"},"404":{"description":"no such app password","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/collections":{"get":{"tags":["account"],"summary":"One's own calendars and address books, and those shared with one, with one's level on each.","operationId":"own_list","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CollectionView"}}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/collections/{owner}/{collection}/access":{"get":{"tags":["account"],"summary":"Who may use a calendar or address book one owns or administers (`admin`).","operationId":"own_access","parameters":[{"name":"owner","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CollectionGrantView"}}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"put":{"tags":["account"],"summary":"Shares a calendar or address book one owns or administers with an account or a group of one's tenant.","operationId":"share","parameters":[{"name":"owner","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnCollectionGrantChange"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["account"],"summary":"Stops sharing a calendar or address book with someone.","operationId":"unshare","parameters":[{"name":"grantee","in":"query","description":"An address of an account of the tenant, or `$` and a group's name.","required":true,"schema":{"type":"string"}},{"name":"owner","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/consents":{"get":{"tags":["account"],"summary":"The applications one's own account agreed to, with the scopes.","operationId":"own","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsentView"}}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/consents/{application}":{"delete":{"tags":["account"],"summary":"Withdraws one's own consent to an application, and the application's tokens – offline access included.","operationId":"revoke_own","parameters":[{"name":"application","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/factors":{"get":{"tags":["account"],"summary":"The second factors of one's own account – for the login UI to ask for one, or to have one set up.","operationId":"factors","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactorsView"}}}}}}},"/v1/account/idp-links":{"post":{"tags":["account"],"summary":"Starts linking another provider to one's own account (RFC 0003, 3); answers with where to send the browser.","operationId":"start_link","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartLink"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartedLogin"}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"no such identity provider","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/mail/access":{"get":{"tags":["account"],"summary":"Who may use one's own mail.","operationId":"own_access","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GrantView"}}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"put":{"tags":["account"],"summary":"Shares one's own mail – the whole store or one mailbox – with an account or a group of one's tenant.","operationId":"share_own","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnGrantChange"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["account"],"summary":"Stops sharing one's own mail with someone.","operationId":"unshare_own","parameters":[{"name":"grantee","in":"query","description":"An address of an account of the tenant, or `$` and a group's name.","required":true,"schema":{"type":"string"}},{"name":"mailbox","in":"query","description":"The mailbox of the grant; leave out for the grant on the whole store.","required":false,"schema":{"type":["string","null"]}}],"responses":{"204":{},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/mail/shared":{"get":{"tags":["account"],"summary":"The mail shared with one's own account: other accounts' stores one may use.","operationId":"own_shared","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SharedStoreView"}}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/passkeys":{"get":{"tags":["account"],"summary":"The passkeys of one's own account.","operationId":"passkeys","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PasskeyView"}}}}}}}},"/v1/account/passkeys/finish":{"post":{"tags":["account"],"summary":"Finishes registering a passkey.","operationId":"finish_registration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Answer"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}},"401":{"description":"the registration did not pass, or no recent session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/passkeys/start":{"post":{"tags":["account"],"summary":"Starts registering a passkey for one's own account (needs a recent session).","operationId":"start_registration","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeView"}}}}}}},"/v1/account/passkeys/{id}":{"delete":{"tags":["account"],"summary":"Removes a passkey of one's own account.","operationId":"remove_passkey","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"removed"},"404":{"description":"no such passkey","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/password":{"put":{"tags":["account"],"summary":"Changes the password of one's own account: needs a recent session and the current password. Every other session\nof the account ends.","operationId":"change_password","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordChange"}}},"required":true},"responses":{"204":{},"401":{"description":"wrong current password, or no recent session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/recovery-codes":{"post":{"tags":["account"],"summary":"Generates new recovery codes for one's own account (needs a recent session); earlier ones stop working.","operationId":"generate_recovery_codes","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecoveryCodes"}}}},"401":{"description":"no valid or no recent session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/account/totp":{"post":{"tags":["account"],"summary":"Proposes a TOTP secret for one's own account (needs a recent session).","operationId":"start_totp","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TotpSetupView"}}}},"401":{"description":"no valid or no recent session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"TOTP is already on","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["account"],"summary":"Removes TOTP from one's own account.","operationId":"remove_totp","responses":{"204":{"description":"removed"}}}},"/v1/account/totp/confirm":{"post":{"tags":["account"],"summary":"Confirms the proposed TOTP secret with a first code.","operationId":"confirm_totp","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Code"}}},"required":true},"responses":{"204":{"description":"TOTP is on"},"401":{"description":"wrong code, or no recent session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts":{"get":{"tags":["accounts"],"summary":"The tenant's accounts (needs `directory.read`).","operationId":"list","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AccountDetails"}}}}}}},"post":{"tags":["accounts"],"summary":"Creates an account (needs `accounts.manage`).","operationId":"add","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewAccount"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}},"409":{"description":"the address is taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}":{"get":{"tags":["accounts"],"summary":"One account (needs `directory.read`).","operationId":"get","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountDetails"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["accounts"],"summary":"Changes an account's display name, login name or active state (needs `accounts.manage`).","operationId":"change","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountChange"}}},"required":true},"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/aliases/{address}":{"put":{"tags":["accounts"],"summary":"Adds an alias on a verified domain of the tenant (needs `accounts.manage`).","operationId":"add_alias","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"address","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"409":{"description":"the address is taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["accounts"],"summary":"Removes an alias; the login name cannot be removed (needs `accounts.manage`).","operationId":"remove_alias","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"address","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/collections":{"get":{"tags":["calendars"],"summary":"An account's calendars and address books (needs `accounts.manage`).","operationId":"list","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CollectionView"}}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/collections/access":{"get":{"tags":["calendars"],"summary":"Who may use an account's calendars and address books (needs `accounts.manage`).","operationId":"access","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CollectionGrantView"}}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/collections/{collection}/access":{"put":{"tags":["calendars"],"summary":"Grants an account or a group of the tenant a level on a calendar or address book of an account, replacing an\nearlier grant (needs `accounts.manage`).","operationId":"set_access","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionGrantChange"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["calendars"],"summary":"Removes a grant on a calendar or address book (needs `accounts.manage`).","operationId":"remove_access","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"grantee_kind","in":"query","description":"`account` or `group`.","required":true,"schema":{"type":"string"}},{"name":"grantee_id","in":"query","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/collections/{collection}/export":{"get":{"tags":["calendars"],"summary":"A calendar as iCalendar or an address book as vCard, everything in one file (needs `accounts.manage`).","operationId":"export","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/calendar":{"schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/collections/{collection}/import":{"post":{"tags":["calendars"],"summary":"Stores the events of an iCalendar file in a calendar, or the contacts of a vCard file in an address book (the\nrequest body, up to 2 MiB); one with a UID that is there already is replaced (needs `accounts.manage`).","operationId":"import","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"text/calendar":{"schema":{"type":"string"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportedView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/consents":{"get":{"tags":["accounts"],"summary":"The applications an account agreed to (needs `accounts.manage`).","operationId":"list","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsentView"}}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/consents/{application}":{"delete":{"tags":["accounts"],"summary":"Withdraws an account's consent to an application and the application's tokens for it (needs `accounts.manage`\nand every permission the account holds).","operationId":"revoke","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"application","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/contact":{"put":{"tags":["accounts"],"summary":"Sets an account's contact address (needs `accounts.manage`).","operationId":"set_contact","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactChange"}}},"required":true},"responses":{"204":{},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/files":{"get":{"tags":["files"],"summary":"An account's files: usage and quota (needs `accounts.manage`).","operationId":"overview","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilesOverviewView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/files/access":{"get":{"tags":["files"],"summary":"Who may use an account's files or a drive (needs `accounts.manage`).","operationId":"access","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FileGrantView"}}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"put":{"tags":["files"],"summary":"Grants an account or a group of the tenant rights on an account's files or a drive – a directory and what lies\nbelow it, or the whole store – replacing an earlier grant there (needs `accounts.manage`).","operationId":"set_access","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileGrantChange"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["files"],"summary":"Removes a grant on an account's files or a drive (needs `accounts.manage`).","operationId":"remove_access","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"grantee_kind","in":"query","description":"`account` or `group`.","required":true,"schema":{"type":"string"}},{"name":"grantee_id","in":"query","required":true,"schema":{"type":"string"}},{"name":"node","in":"query","description":"The directory of the grant; leave out for the grant on the whole store.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/files/quota":{"put":{"tags":["files"],"summary":"Sets an account's files quota; null for the tenant's default (needs `accounts.manage`).","operationId":"set_quota","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilesQuota"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/links":{"get":{"tags":["accounts"],"summary":"The external identities linked to an account (needs `directory.read`).","operationId":"links","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LinkView"}}}}}}}},"/v1/accounts/{id}/links/{idp}/{subject}":{"delete":{"tags":["accounts"],"summary":"Unlinks an external identity from an account (needs `accounts.manage`).","operationId":"unlink","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"idp","in":"path","required":true,"schema":{"type":"string"}},{"name":"subject","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/mail":{"get":{"tags":["mail"],"summary":"An account's mail: usage, quota and mailboxes (needs `accounts.manage`).","operationId":"overview","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MailOverviewView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/mail/access":{"get":{"tags":["mail"],"summary":"Who may use an account's mail (needs `accounts.manage`).","operationId":"access","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GrantView"}}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"put":{"tags":["mail"],"summary":"Grants an account or a group of the tenant access to an account's mail, replacing an earlier grant there (needs\n`accounts.manage`).","operationId":"set_access","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantChange"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["mail"],"summary":"Removes a grant on an account's mail (needs `accounts.manage`).","operationId":"remove_access","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"grantee_kind","in":"query","description":"`account` or `group`.","required":true,"schema":{"type":"string"}},{"name":"grantee_id","in":"query","required":true,"schema":{"type":"string"}},{"name":"mailbox","in":"query","description":"The mailbox of the grant; leave out for the grant on the whole store.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/mail/import":{"post":{"tags":["mail"],"summary":"Stores a message (RFC 5322, the request body) in a mailbox of an account (needs `accounts.manage`).","operationId":"import","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"mailbox","in":"query","description":"A mailbox id or a role (`inbox`, `archive`, …); the inbox if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"message/rfc822":{"schema":{"type":"string"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/mail/mailboxes/{mailbox}/mbox":{"get":{"tags":["mail"],"summary":"A mailbox of an account (by id or role) as mbox, with its keywords (needs `accounts.manage`).","operationId":"export","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"mailbox","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/mbox":{"schema":{"type":"string"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["mail"],"summary":"Stores the messages of an mbox (the request body, up to 2 MiB; larger ones with the CLI) in a mailbox of an account\n(by id or role), with their keywords (needs `accounts.manage`).","operationId":"import_mbox","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"mailbox","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/mbox":{"schema":{"type":"string"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MboxImportView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/mail/quota":{"put":{"tags":["mail"],"summary":"Sets an account's mail quota; null for the tenant's default (needs `accounts.manage`).","operationId":"set_quota","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quota"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/mail/sieve":{"get":{"tags":["mail"],"summary":"An account's Sieve scripts (needs `accounts.manage`).","operationId":"sieve_scripts","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SieveScriptView"}}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/mail/sieve-active":{"put":{"tags":["mail"],"summary":"Chooses the Sieve script that runs; null for none (needs `accounts.manage`).","operationId":"activate_sieve_script","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActiveScript"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/mail/sieve/{name}":{"put":{"tags":["mail"],"summary":"Saves a Sieve script, checked first (needs `accounts.manage`).","operationId":"put_sieve_script","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewSieveScript"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["mail"],"summary":"Removes a Sieve script (needs `accounts.manage`).","operationId":"remove_sieve_script","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/password":{"put":{"tags":["accounts"],"summary":"Sets an account's password and ends its sessions (needs `accounts.manage` and every permission the account\nholds).","operationId":"set_password","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewPassword"}}},"required":true},"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/second-factors":{"delete":{"tags":["accounts"],"summary":"Removes all TOTP, passkeys and recovery codes of an account (needs `accounts.manage` and every permission the\naccount holds).","operationId":"reset_second_factors","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/services":{"get":{"tags":["accounts"],"summary":"The services of an account (needs `directory.read`).","operationId":"list_services","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ServiceView"}}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/services/{service}":{"put":{"tags":["accounts"],"summary":"Grants a service – also one an account requested (needs `accounts.manage`); `mail` only to an account with an\naddress of the tenant.","operationId":"grant_service","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"service","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["accounts"],"summary":"Takes a service away (needs `accounts.manage`); a mail store stays until the account is removed.","operationId":"revoke_service","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"service","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/sessions":{"get":{"tags":["accounts"],"summary":"The account's valid sessions (needs `accounts.manage`).","operationId":"sessions","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SessionSummaryView"}}}}}}}},"/v1/accounts/{id}/sessions/{session}":{"delete":{"tags":["accounts"],"summary":"Ends one session of the account (needs `accounts.manage` and every permission the account holds).","operationId":"terminate_session","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"session","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/accounts/{id}/username":{"put":{"tags":["accounts"],"summary":"Gives an account a username, or takes it away (needs `accounts.manage`; the tenant must use usernames).","operationId":"set_username","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsernameChange"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/applications":{"get":{"tags":["applications"],"summary":"The tenant's applications (needs `directory.read`).","operationId":"list","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApplicationView"}}}}}}},"post":{"tags":["applications"],"summary":"Registers an application in a project of the tenant (needs `applications.manage`).","operationId":"add","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewApplication"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationCreated"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/applications/{id}":{"get":{"tags":["applications"],"summary":"One application (needs `directory.read`).","operationId":"get","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["applications"],"summary":"Changes an application (needs `applications.manage`).","operationId":"change","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationChange"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/applications/{id}/options":{"put":{"tags":["applications"],"summary":"Sets the application's options: token format, offline access, consent, logout notifications (needs\n`applications.manage`).","operationId":"set_options","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptionsView"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationView"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/applications/{id}/policy":{"put":{"tags":["applications"],"summary":"Sets whether logins to the application need a second factor, on top of the tenant's policy (needs\n`applications.manage`).","operationId":"set_policy","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Policy"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/applications/{id}/secret":{"post":{"tags":["applications"],"summary":"Replaces the secret of a confidential application (needs `applications.manage`).","operationId":"new_secret","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientSecret"}}}},"400":{"description":"a public application","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/auth-requests/{id}":{"get":{"tags":["login"],"summary":"A pending auth request – for the login UI to show who is asking.","operationId":"auth_request","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthRequestView"}}}},"404":{"description":"unknown, expired or already finished","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["login"],"summary":"Finishes an auth request with the session of the bearer token; answers with the URL to send the browser to. If\nthe application needs consent, the answer is `403` with type `urn:kernoid:problem:consent-required`: show what it\nasks for, and finish again with `{\"consent\": true}`.","operationId":"finish","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Finish"},{"type":"null"}]}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Finished"}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"the account may not use this application, or consent is needed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"unknown, expired or already finished","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/auth-requests/{id}/decline":{"post":{"tags":["login"],"summary":"Ends an auth request without a login – no session for `prompt=none`, or the person declined; answers with the\nURL that tells the application.","operationId":"decline","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Decline"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Finished"}}}},"400":{"description":"unknown error code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"unknown, expired or already finished","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/drives":{"get":{"tags":["files"],"summary":"The tenant's drives: file stores that belong to the tenant, not to a person (needs `directory.read`).","operationId":"drives","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DriveView"}}}}}}},"post":{"tags":["files"],"summary":"Creates a drive of the tenant; people reach it through grants (needs `accounts.manage`).","operationId":"add_drive","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewDrive"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/external-accounts":{"post":{"tags":["accounts"],"summary":"Creates an account without an address of the tenant: for logins only – and files, if granted (needs\n`accounts.manage`).","operationId":"add_external","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewExternalAccount"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/granted-projects":{"get":{"tags":["projects"],"summary":"The projects other tenants have granted to this one, with the roles it may give (needs `directory.read`).","operationId":"granted","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GrantView"}}}}}}}},"/v1/groups":{"get":{"tags":["groups"],"summary":"The tenant's groups with their members (needs `directory.read`).","operationId":"groups","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GroupView"}}}}}}},"post":{"tags":["groups"],"summary":"Creates a group (needs `groups.manage`).","operationId":"add_group","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupName"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/groups/{id}":{"delete":{"tags":["groups"],"summary":"Removes a group; refused while it holds roles (needs `groups.manage`).","operationId":"remove_group","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"the group holds roles","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["groups"],"summary":"Renames a group (needs `groups.manage`).","operationId":"rename_group","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupName"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/groups/{id}/addresses/{address}":{"put":{"tags":["groups"],"summary":"Gives a group an address on a verified domain of the tenant; mail to it goes to every member (needs\n`groups.manage`).","operationId":"add_address","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"address","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"409":{"description":"the address is taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["groups"],"summary":"Removes an address of a group (needs `groups.manage`).","operationId":"remove_address","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"address","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/groups/{id}/members/{account}":{"put":{"tags":["groups"],"summary":"Adds an account to a group (needs `groups.manage`, and for a group holding roles the permission to assign them).","operationId":"add_member","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"account","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"403":{"description":"needs groups.manage, and roles.manage etc. for a group with roles","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["groups"],"summary":"Removes an account from a group (needs the same as adding one).","operationId":"remove_member","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"account","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{}}}},"/v1/identity-providers":{"get":{"tags":["identity providers"],"summary":"The tenant's identity providers, and those of the instance that serve every tenant (needs `directory.read`).","operationId":"list","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProviderView"}}}}}}},"post":{"tags":["identity providers"],"summary":"Connects an identity provider (needs `identity_providers.manage`; for the whole instance, `instance.manage`).\nRegister the `redirect_uri` from the answer of `GET /v1/identity-providers/{id}` at the provider.","operationId":"add","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewProvider"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/identity-providers/{id}":{"get":{"tags":["identity providers"],"summary":"One identity provider (needs `directory.read`).","operationId":"get","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["identity providers"],"summary":"Removes an identity provider, once no account is linked to it (needs `identity_providers.manage`).","operationId":"remove","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"accounts are linked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["identity providers"],"summary":"Changes an identity provider's settings, or switches it off and on (needs `identity_providers.manage`).","operationId":"change","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderChange"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/identity-providers/{id}/check":{"post":{"tags":["identity providers"],"summary":"Fetches the provider's discovery document and keys: whether kernoid reaches it as configured (needs\n`identity_providers.manage`).","operationId":"check","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"what went wrong","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/identity-providers/{id}/secret":{"put":{"tags":["identity providers"],"summary":"Sets the client secret (needs `identity_providers.manage`).","operationId":"set_secret","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Secret"}}},"required":true},"responses":{"204":{}}},"delete":{"tags":["identity providers"],"summary":"Removes the client secret – for providers that take PKCE alone (needs `identity_providers.manage`).","operationId":"remove_secret","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{}}}},"/v1/idp-logins":{"post":{"tags":["login"],"summary":"Starts a login at an identity provider; answers with where to send the browser.","operationId":"start","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartLogin"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartedLogin"}}}},"400":{"description":"the provider cannot be reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"no such identity provider","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/idp-logins/link":{"post":{"tags":["login"],"summary":"Links the provider login of a proposal to the account of the session – the person logged in to it to prove it is\ntheirs; from then on the provider logs in as that account.","operationId":"confirm_link","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Handoff"}}},"required":true},"responses":{"204":{},"400":{"description":"the session is not the proposed account's","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"no valid session, or the code is unknown, expired or used","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/idp-logins/proposal":{"post":{"tags":["login"],"summary":"What a provider login that found an account with its verified address proposes (RFC 0003, 3): log in to that\naccount to link it – or, where registration is open, create a separate one. Does not use the code up.","operationId":"proposal","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Handoff"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkProposalView"}}}},"401":{"description":"unknown, expired or used already","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/idp-logins/register":{"post":{"tags":["login"],"summary":"Creates a separate account for the provider login of a proposal instead of linking it, where registration is\nopen, and logs it in.","operationId":"register_instead","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeLogin"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangedLogin"}}}},"400":{"description":"registering is not possible here","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"unknown, expired or used already","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/idp-logins/session":{"post":{"tags":["login"],"summary":"Exchanges the result of a login at an identity provider for a session – once.","operationId":"exchange","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangeLogin"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExchangedLogin"}}}},"401":{"description":"unknown, expired or used already","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance":{"get":{"tags":["instance"],"summary":"The instance reached under the host of this request.","operationId":"current","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceView"}}}},"404":{"description":"no instance is reached under this host","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["instance"],"summary":"Renames the instance (needs `instance.manage`).","operationId":"rename","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Name"}}},"required":true},"responses":{"204":{}}}},"/v1/instance/details":{"get":{"tags":["instance"],"summary":"The instance with all its domains (needs `instance.read`).","operationId":"details","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceDetails"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/domains/{domain}":{"put":{"tags":["instance"],"summary":"Reaches the instance under another domain as well (needs `instance.manage`).","operationId":"add_domain","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"409":{"description":"in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["instance"],"summary":"Removes a domain; not the primary one (needs `instance.manage`).","operationId":"remove_domain","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"the primary domain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/login-ui":{"put":{"tags":["instance"],"summary":"Sends logins to a login UI of the instance's own, which may then call the API from its origin (needs\n`instance.manage`).","operationId":"set_login_ui","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginUi"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/mail-queue":{"get":{"tags":["mail"],"summary":"The queue of outgoing mail of the instance's tenants, newest first (needs `instance.read`).","operationId":"queue","parameters":[{"name":"limit","in":"query","description":"At most this many recipients (1–1000, default 100).","required":false,"schema":{"type":["integer","null"],"format":"int64"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QueuedView"}}}}}}}},"/v1/instance/passkey-rp-id":{"put":{"tags":["instance"],"summary":"Binds passkeys to another RP ID – one of the instance's domains or a parent domain of one (needs\n`instance.manage`). Passkeys registered under the former RP ID stop working.","operationId":"set_passkey_rp_id","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasskeyRpId"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/primary-domain":{"put":{"tags":["instance"],"summary":"Sets the domain the issuer and links use (needs `instance.manage`). Passkeys are bound to it.","operationId":"set_primary_domain","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrimaryDomain"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/registration-tenant":{"put":{"tags":["instance"],"summary":"Names the tenant where people without an address of a tenant register (needs `instance.manage`).","operationId":"set_registration_tenant","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationTenant"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/roles":{"get":{"tags":["instance"],"summary":"The instance roles and who holds them (needs `instance.read`).","operationId":"roles","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceRolesView"}}}}}}},"/v1/instance/roles/{role}":{"put":{"tags":["instance"],"summary":"Defines an instance role of the instance's own, or changes its permissions (needs `instance_roles.manage`).","operationId":"define_role","parameters":[{"name":"role","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceRoleDefinition"}}},"required":true},"responses":{"204":{},"400":{"description":"a built-in role, or no permission","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["instance"],"summary":"Deletes an instance role of the instance's own, once nobody holds it (needs `instance_roles.manage`).","operationId":"delete_role","parameters":[{"name":"role","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"still assigned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/roles/{role}/{kind}/{id}":{"put":{"tags":["instance"],"summary":"Assigns an instance role to an account or group of any tenant of the instance (needs `instance_roles.manage`).","operationId":"grant_role","parameters":[{"name":"role","in":"path","required":true,"schema":{"type":"string"}},{"name":"kind","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["instance"],"summary":"Takes an instance role back; the last `instance_admin` stays (needs `instance_roles.manage`).","operationId":"revoke_role","parameters":[{"name":"role","in":"path","required":true,"schema":{"type":"string"}},{"name":"kind","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/signing-keys":{"get":{"tags":["instance"],"summary":"The instance's signing keys (needs `instance.read`).","operationId":"signing_keys","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SigningKeyView"}}}}}}},"post":{"tags":["instance"],"summary":"Creates a signing key: published at once, signing once activated (needs `instance.manage`).","operationId":"add_signing_key","responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewKey"}}}}}}},"/v1/instance/signing-keys/{kid}":{"delete":{"tags":["instance"],"summary":"Removes an inactive key whose tokens have expired (needs `instance.manage`).","operationId":"remove_signing_key","parameters":[{"name":"kid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/signing-keys/{kid}/activate":{"post":{"tags":["instance"],"summary":"Signs with this key from now on (needs `instance.manage`).","operationId":"activate_signing_key","parameters":[{"name":"kid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/instance/tenants":{"get":{"tags":["instance"],"summary":"The instance's tenants (needs `instance.read`).","operationId":"tenants","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TenantSummary"}}}}}}},"post":{"tags":["instance"],"summary":"Creates a tenant (needs `tenants.manage`).","operationId":"add_tenant","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Name"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}}}}},"/v1/instance/tenants/{id}":{"patch":{"tags":["instance"],"summary":"Renames, deactivates or reactivates a tenant (needs `tenants.manage`); not one's own by deactivation.","operationId":"change_tenant","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantChange"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/login-options":{"get":{"tags":["login"],"summary":"Where an address logs in: at an identity provider its domain is routed to, or with kernoid's own login. Says\nnothing about whether the account exists.","operationId":"login_options","parameters":[{"name":"address","in":"query","description":"The address someone types in to log in.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginOptions"}}}}}}},"/v1/login-providers":{"get":{"tags":["login"],"summary":"The providers offered to everyone on the login page (\"Sign in with …\").","operationId":"open_providers","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProviderSummary"}}}}}}}},"/v1/projects":{"get":{"tags":["projects"],"summary":"The tenant's projects with their roles (needs `directory.read`).","operationId":"list","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProjectView"}}}}}}},"post":{"tags":["projects"],"summary":"Creates a project (needs `projects.manage`).","operationId":"add","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewProject"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}}}}},"/v1/projects/{id}":{"get":{"tags":["projects"],"summary":"One project (needs `directory.read`).","operationId":"get","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectView"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["projects"],"summary":"Removes a project – once it has no applications and nobody holds its roles (needs `projects.manage`).","operationId":"remove","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"applications or authorizations left","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["projects"],"summary":"Renames a project or changes its settings (needs `projects.manage`).","operationId":"change","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectChange"}}},"required":true},"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/projects/{id}/authorizations":{"get":{"tags":["projects"],"summary":"Who holds which role of the project – for a granted project only the tenant's own (needs `directory.read`).","operationId":"authorizations","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AuthorizationView"}}}}}}}},"/v1/projects/{id}/authorizations/{role}/{kind}/{principal}":{"put":{"tags":["projects"],"summary":"Gives an account or group of the tenant a role of the project – of its own, or one granted to it (needs\n`authorizations.manage`).","operationId":"grant","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"role","in":"path","required":true,"schema":{"type":"string"}},{"name":"kind","in":"path","required":true,"schema":{"type":"string"}},{"name":"principal","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["projects"],"summary":"Takes a project role back (needs `authorizations.manage`).","operationId":"revoke","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"role","in":"path","required":true,"schema":{"type":"string"}},{"name":"kind","in":"path","required":true,"schema":{"type":"string"}},{"name":"principal","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/projects/{id}/grants":{"get":{"tags":["projects"],"summary":"The tenants the project is granted to (needs `directory.read`).","operationId":"grants","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GrantView"}}}}}}}},"/v1/projects/{id}/grants/{tenant}":{"put":{"tags":["projects"],"summary":"Grants the project to another tenant of the instance – named by its id or a verified mail domain – with some of\nits roles, or changes them (needs `projects.manage`).","operationId":"grant_project","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"tenant","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantRoles"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["projects"],"summary":"Takes a grant back, once that tenant holds none of the project's roles (needs `projects.manage`).","operationId":"revoke_project_grant","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"tenant","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"roles still held","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/projects/{id}/roles/{key}":{"put":{"tags":["projects"],"summary":"Adds a role to the project, or changes its display name and group (needs `projects.manage`).","operationId":"set_role","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectRoleDefinition"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["projects"],"summary":"Removes a role from the project, once nobody holds it (needs `projects.manage`).","operationId":"remove_role","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"still assigned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/registration":{"get":{"tags":["login"],"summary":"What registering offers at this instance; the providers to register with are at `/v1/login-providers`.","operationId":"options","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationOptionsView"}}}}}}},"/v1/registrations":{"post":{"tags":["login"],"summary":"Starts a registration: checks it, refuses what is taken (`409`: log in instead), and sends a code to the email\naddress. Nothing is stored as an account before the code is confirmed.","operationId":"start","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewRegistrationBody"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationStarted"}}}},"400":{"description":"not possible here, or not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"the address, username or email address is taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"too many registrations from this address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/registrations/{id}/confirm":{"post":{"tags":["login"],"summary":"Finishes a registration with the code from the message: the account is created.","operationId":"confirm","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Registered"}}}},"401":{"description":"wrong, expired or used code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/roles":{"get":{"tags":["roles"],"summary":"The roles there are, and who holds which in the tenant (needs `directory.read`).","operationId":"roles","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RolesView"}}}}}}},"/v1/roles/{role}":{"put":{"tags":["roles"],"summary":"Defines a role of the tenant's own, or changes its permissions (needs `roles.manage`).","operationId":"define_role","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"role","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDefinition"}}},"required":true},"responses":{"204":{},"400":{"description":"a built-in role, or not tenant permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["roles"],"summary":"Deletes a role of the tenant's own, once nobody holds it (needs `roles.manage`).","operationId":"delete_role","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"role","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"still assigned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/roles/{role}/{kind}/{id}":{"put":{"tags":["roles"],"summary":"Assigns a role to an account or a group of the tenant (needs `roles.manage`).","operationId":"grant_role","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"role","in":"path","description":"e.g. `user_manager`","required":true,"schema":{"type":"string"}},{"name":"kind","in":"path","description":"`account` or `group`","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"403":{"description":"needs roles.manage","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["roles"],"summary":"Takes a role back; the tenant's last `tenant_admin` assignment cannot be revoked (needs `roles.manage`).","operationId":"revoke_role","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"role","in":"path","required":true,"schema":{"type":"string"}},{"name":"kind","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"the last tenant_admin assignment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/scim-tokens":{"get":{"tags":["provisioning"],"summary":"The tenant's SCIM tokens (needs `directory.read`).","operationId":"list","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScimTokenView"}}}}}}},"post":{"tags":["provisioning"],"summary":"A new SCIM token for the tenant's directory (needs `provisioning.manage`).","operationId":"add","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewScimToken"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScimTokenCreated"}}}}}}},"/v1/scim-tokens/{id}":{"delete":{"tags":["provisioning"],"summary":"Revokes a SCIM token (needs `provisioning.manage`).","operationId":"remove","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{}}}},"/v1/sessions":{"get":{"tags":["sessions"],"summary":"The valid sessions of the bearer token's account, newest first.","operationId":"list","responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SessionSummaryView"}}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["sessions"],"summary":"Logs in: checks address and password at the instance of this host and creates a session.","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSession"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionCreated"}}}},"401":{"description":"address or password wrong","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"the account or its tenant is deactivated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"too many failed attempts; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions/current":{"get":{"tags":["sessions"],"summary":"The session of the bearer token.","operationId":"current","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionView"}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["sessions"],"summary":"Logs out: ends the session of the bearer token.","operationId":"terminate","responses":{"204":{"description":"ended"},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions/current/logout":{"post":{"tags":["sessions"],"summary":"Logs out: ends the session of the bearer token. If it came from a SAML provider with single logout, the answer\nsays where to send the browser next.","operationId":"logout","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoggedOut"}}}},"401":{"description":"no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions/current/passkey/finish":{"post":{"tags":["sessions"],"summary":"Finishes a passkey check of the current session.","operationId":"finish_check","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Answer"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionView"}}}},"401":{"description":"the passkey did not pass","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions/current/passkey/start":{"post":{"tags":["sessions"],"summary":"Starts a passkey check of the current session.","operationId":"start_check","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeView"}}}}}}},"/v1/sessions/current/recovery":{"post":{"tags":["sessions"],"summary":"Uses a recovery code as a further check of the current session.","operationId":"check_recovery_code","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Code"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionView"}}}},"401":{"description":"wrong or used code, or no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions/current/totp":{"post":{"tags":["sessions"],"summary":"Checks a TOTP code as a further check of the current session.","operationId":"check_totp","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Code"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionView"}}}},"401":{"description":"wrong code, or no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions/passkey/finish":{"post":{"tags":["sessions"],"summary":"Finishes a passkey login and creates a session.","operationId":"finish_login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Answer"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionCreated"}}}},"401":{"description":"the passkey did not pass","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions/passkey/start":{"post":{"tags":["sessions"],"summary":"Starts a login with a passkey – no address, no password.","operationId":"start_login","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeView"}}}},"429":{"description":"too many failed attempts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sessions/{id}":{"delete":{"tags":["sessions"],"summary":"Ends a session of the bearer token's own account – e.g. one left open on another device.","operationId":"terminate_other","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"ended"},"404":{"description":"no such session of this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/shared-mailboxes":{"post":{"tags":["mail"],"summary":"Creates a shared mailbox: an account nobody logs in as, used through granted access (needs `accounts.manage`).","operationId":"add_shared_mailbox","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewSharedMailbox"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Created"}}}},"409":{"description":"the address is taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant":{"get":{"tags":["tenant"],"summary":"The tenant administered (needs `directory.read`).","operationId":"get","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantView"}}}},"403":{"description":"needs directory.read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["tenant"],"summary":"Renames the tenant (needs `tenant.manage`).","operationId":"rename","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Name"}}},"required":true},"responses":{"204":{},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant/domains":{"post":{"tags":["tenant"],"summary":"Claims a mail domain (needs `domains.manage`); answers with the TXT record that proves it.","operationId":"add_domain","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewDomain"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainView"}}}},"409":{"description":"claimed already","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant/domains/{domain}":{"delete":{"tags":["tenant"],"summary":"Removes a mail domain – unless addresses use it (needs `domains.manage`).","operationId":"remove_domain","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"domain","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{},"400":{"description":"addresses use it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant/domains/{domain}/verify":{"post":{"tags":["tenant"],"summary":"Verifies a claimed domain by its TXT record (needs `domains.manage`), or marks it verified without DNS\n(`trust`, needs `tenants.manage`).","operationId":"verify_domain","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"domain","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"}}},"required":true},"responses":{"204":{},"400":{"description":"the record was not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant/files-quota":{"get":{"tags":["files"],"summary":"The tenant's default files quota (needs `directory.read`).","operationId":"default_quota","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilesQuota"}}}}}},"put":{"tags":["files"],"summary":"Sets the tenant's default files quota, for every account without its own; null for no limit (needs\n`tenant.manage`).","operationId":"set_default_quota","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilesQuota"}}},"required":true},"responses":{"204":{}}}},"/v1/tenant/login-policy":{"get":{"tags":["tenant"],"summary":"How the tenant's accounts log in (needs `directory.read`).","operationId":"login_policy","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginPolicyView"}}}}}},"put":{"tags":["tenant"],"summary":"Sets how the tenant's accounts log in (needs `policies.manage`).","operationId":"set_login_policy","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginPolicyView"}}},"required":true},"responses":{"204":{}}}},"/v1/tenant/mail-dns":{"get":{"tags":["tenant"],"summary":"The tenant's verified domains as mail domains of kernoid: the DNS records to publish (MX, SPF, DKIM, DMARC) and\nwhether they are published (needs `directory.read`; reads DNS, changes nothing).","operationId":"mail_dns","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MailDnsView"}}}}},"400":{"description":"this installation does not handle mail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant/mail-quota":{"get":{"tags":["mail"],"summary":"The tenant's default mail quota (needs `directory.read`).","operationId":"default_quota","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quota"}}}}}},"put":{"tags":["mail"],"summary":"Sets the tenant's default mail quota, for every account without its own; null for no limit (needs\n`tenant.manage`).","operationId":"set_default_quota","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quota"}}},"required":true},"responses":{"204":{}}}},"/v1/tenant/mail-retention":{"get":{"tags":["mail"],"summary":"The tenant's mail retention (needs `directory.read`).","operationId":"retention","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Retention"}}}}}},"put":{"tags":["mail"],"summary":"Sets how many days emails stay in the accounts' Trash and Junk; null keeps them (needs `tenant.manage`).","operationId":"set_retention","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Retention"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant/modules/{module}":{"put":{"tags":["tenant"],"summary":"Switches a module on or off for the tenant (needs `tenant.manage`). The module must be compiled in; whether it\nruns is decided by the installation's configuration.","operationId":"set_module","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"module","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Switch"}}},"required":true},"responses":{"204":{},"400":{"description":"no such module","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant/permissions":{"get":{"tags":["tenant"],"summary":"The permissions of the caller for the tenant administered – for a UI to show what it may do.","operationId":"permissions","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermissionsView"}}}}}}},"/v1/tenant/policy":{"put":{"tags":["tenant"],"summary":"Sets whether every login to an application of the tenant needs a second factor, and how long accounts without one\nmay still log in (needs `policies.manage`).","operationId":"set_policy","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Policy"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantView"}}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant/registration":{"get":{"tags":["tenant"],"summary":"Whether people may register with the tenant, and on which domains (needs `directory.read`).","operationId":"registration","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationView"}}}}}},"put":{"tags":["tenant"],"summary":"Opens or closes registration, and names the domains new accounts may take an address on (needs\n`policies.manage`).","operationId":"set_registration","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationView"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/tenant/service-policies":{"get":{"tags":["tenant"],"summary":"The tenant's rules for each service (needs `directory.read`).","operationId":"service_policies","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ServicePolicyView"}}}}}}}},"/v1/tenant/service-policies/{service}":{"put":{"tags":["tenant"],"summary":"Sets who gets a service when an account is created, and whether it needs approval (needs `policies.manage`).","operationId":"set_service_policy","parameters":[{"name":"kernoid-tenant","in":"header","description":"The tenant to act on – for instance administrators; the caller's own tenant if left out.","required":false,"schema":{"type":["string","null"]}},{"name":"service","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServicePolicyView"}}},"required":true},"responses":{"204":{},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/version":{"get":{"tags":["meta"],"summary":"The name and version of this kernoid.","operationId":"version","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Version"}}}}}}}},"components":{"schemas":{"AccountChange":{"type":"object","properties":{"active":{"type":["boolean","null"],"description":"`false` deactivates the account and ends its sessions."},"display_name":{"type":["string","null"]},"primary_address":{"type":["string","null"],"description":"An alias of the account that becomes its login name; the former one stays as an alias."}}},"AccountDetails":{"type":"object","required":["id","tenant","address","display_name","active","shared","native","drive"],"properties":{"active":{"type":"boolean"},"address":{"type":"string","description":"The login name: the primary address, else the username, else the contact address."},"display_name":{"type":"string"},"drive":{"type":"boolean","description":"A drive (RFC 0005, 12): a file store of the tenant; nobody logs in as it."},"id":{"type":"string"},"native":{"type":"boolean","description":"Has an address of the tenant (RFC 0003, 1); only such an account can have mail."},"shared":{"type":"boolean","description":"A shared mailbox (RFC 0002, 12.1): nobody logs in as it."},"tenant":{"type":"string"}}},"AccountView":{"type":"object","required":["id","tenant","address","display_name"],"properties":{"address":{"type":"string"},"display_name":{"type":"string"},"id":{"type":"string"},"tenant":{"type":"string"}}},"ActiveScript":{"type":"object","properties":{"name":{"type":["string","null"],"description":"The script that runs; null for none."}}},"Answer":{"type":"object","required":["challenge_id","credential"],"properties":{"challenge_id":{"type":"string"},"cookie":{"type":"boolean","description":"For a login in a browser: keep the session in an HttpOnly cookie instead of answering with the token."},"credential":{"type":"object","description":"What the browser returned, as JSON."},"lifetime_seconds":{"type":["integer","null"],"format":"int64","description":"For a login: how long the session lasts; 8 hours if left out.","minimum":0},"name":{"type":["string","null"],"description":"For a registration: a name for the passkey, e.g. the device."}}},"AppPasswordCreated":{"type":"object","required":["id","password"],"properties":{"id":{"type":"string"},"password":{"type":"string","description":"The app password – shown this once."}}},"AppPasswordName":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Which device or program it is for, e.g. \"Thunderbird at home\"."}}},"AppPasswordView":{"type":"object","required":["id","name","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"last_used_at":{"type":["string","null"],"format":"date-time"},"name":{"type":"string"}}},"ApplicationChange":{"type":"object","properties":{"active":{"type":["boolean","null"]},"name":{"type":["string","null"]},"post_logout_redirect_uris":{"type":["array","null"],"items":{"type":"string"}},"project":{"type":["string","null"],"description":"Move it to another project of the tenant."},"redirect_uris":{"type":["array","null"],"items":{"type":"string"}}}},"ApplicationCreated":{"type":"object","required":["id"],"properties":{"client_secret":{"type":["string","null"],"description":"For a confidential application: its secret, shown this once."},"id":{"type":"string","description":"The `client_id`."}}},"ApplicationView":{"type":"object","required":["id","name","kind","redirect_uris","post_logout_redirect_uris","mfa_required","active","options"],"properties":{"active":{"type":"boolean"},"id":{"type":"string","description":"The `client_id`."},"kind":{"type":"string","description":"`confidential` or `public`."},"mfa_required":{"type":"boolean"},"name":{"type":"string"},"options":{"$ref":"#/components/schemas/OptionsView"},"post_logout_redirect_uris":{"type":"array","items":{"type":"string"}},"project":{"type":["string","null"]},"redirect_uris":{"type":"array","items":{"type":"string"}}}},"AssignmentView":{"type":"object","description":"A role assignment or authorization: who holds which role.","required":["role","principal_kind","principal_id"],"properties":{"principal_id":{"type":"string"},"principal_kind":{"type":"string","description":"`account` or `group`."},"role":{"type":"string"}}},"AuthRequestView":{"type":"object","required":["id","application","scopes","prompt","expires_at"],"properties":{"application":{"type":"string","description":"The name of the application asking."},"expires_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"max_age":{"type":["integer","null"],"format":"int32","description":"The session may be at most this many seconds old."},"prompt":{"type":"array","items":{"type":"string"},"description":"`none`, `login`, `consent`, `select_account` – what the login UI must respect."},"scopes":{"type":"array","items":{"type":"string"}}}},"AuthorizationView":{"type":"object","description":"A project role held by an account or group.","required":["role","tenant","principal_kind","principal_id"],"properties":{"principal_id":{"type":"string"},"principal_kind":{"type":"string","description":"`account` or `group`."},"role":{"type":"string"},"tenant":{"type":"string","description":"The tenant that gave it: the project's own, or one it is granted to."}}},"ChallengeView":{"type":"object","required":["challenge_id","options"],"properties":{"challenge_id":{"type":"string","description":"Send it back with the answer."},"options":{"type":"object","description":"For `navigator.credentials.create()` or `.get()`."}}},"Check":{"type":"string","enum":["ok","failed"]},"ClientSecret":{"type":"object","required":["client_secret"],"properties":{"client_secret":{"type":"string","description":"Shown this once."}}},"Code":{"type":"object","required":["code"],"properties":{"code":{"type":"string","description":"Six digits from the app."}}},"CollectionGrantChange":{"type":"object","required":["grantee_kind","grantee_id","level"],"properties":{"grantee_id":{"type":"string"},"grantee_kind":{"type":"string","description":"`account` or `group`."},"level":{"type":"string","description":"`freebusy`, `read`, `rsvp`, `write` or `admin`; address books: `read`, `write` or `admin`."}}},"CollectionGrantView":{"type":"object","required":["kind","collection","grantee_kind","grantee_id","grantee_name","level"],"properties":{"collection":{"type":"string"},"grantee_id":{"type":"string"},"grantee_kind":{"type":"string","description":"`account` or `group`."},"grantee_name":{"type":"string","description":"The account's address, or `$` and the group's name."},"kind":{"type":"string","description":"`calendar` or `addressbook`."},"level":{"type":"string"}}},"CollectionView":{"type":"object","required":["owner","owner_name","kind","id","name","is_default","level"],"properties":{"color":{"type":["string","null"]},"id":{"type":"string"},"is_default":{"type":"boolean"},"kind":{"type":"string","description":"`calendar` or `addressbook`."},"level":{"type":"string","description":"The caller's level: `freebusy`, `read`, `rsvp`, `write` or `admin` (an owner's)."},"name":{"type":"string"},"owner":{"type":"string"},"owner_name":{"type":"string"}}},"Confirmation":{"type":"object","required":["code"],"properties":{"code":{"type":"string"}}},"ConsentView":{"type":"object","required":["application","application_name","scopes","granted_at"],"properties":{"application":{"type":"string"},"application_name":{"type":"string"},"granted_at":{"type":"string","format":"date-time"},"scopes":{"type":"array","items":{"type":"string"}}}},"ContactChange":{"type":"object","properties":{"email":{"type":["string","null"],"description":"Any domain; null removes it."},"verified":{"type":"boolean","description":"Verified addresses log in and are unique in the instance."}}},"CreateSession":{"type":"object","required":["address","password"],"properties":{"address":{"type":"string","description":"The login name: an address of the account."},"cookie":{"type":"boolean","description":"For browsers: keep the session in an HttpOnly cookie instead of answering with the token."},"device_token":{"type":["string","null"],"description":"The token of this device from an earlier login with this address: failed logins then count against the device,\nnot the address, so others failing on purpose do not lock the account out here."},"lifetime_seconds":{"type":["integer","null"],"format":"int64","description":"How long the session lasts; 8 hours if left out, at most 30 days.","minimum":0},"password":{"type":"string"}}},"Created":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"Decline":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"`login_required`, `consent_required`, `interaction_required`, `account_selection_required` or `access_denied`."}}},"DnsRecord":{"type":"object","required":["name","kind","value"],"properties":{"kind":{"type":"string","description":"Always `TXT`."},"name":{"type":"string","description":"E.g. `_kernoid-challenge.firma.de`."},"value":{"type":"string"}}},"DomainView":{"type":"object","required":["domain","verified"],"properties":{"domain":{"type":"string"},"record":{"oneOf":[{"$ref":"#/components/schemas/DnsRecord","description":"For a domain not verified yet: the TXT record that proves it."},{"type":"null"}]},"verified":{"type":"boolean"}}},"DriveView":{"type":"object","required":["id","name","active"],"properties":{"active":{"type":"boolean"},"id":{"type":"string"},"name":{"type":"string"}}},"ExchangeLogin":{"type":"object","required":["login"],"properties":{"cookie":{"type":"boolean","description":"For browsers: keep the session in an HttpOnly cookie instead of answering with the token."},"lifetime_seconds":{"type":["integer","null"],"format":"int64","description":"How long the session lasts; 8 hours if left out.","minimum":0},"login":{"type":"string","description":"What the login UI got after the callback: `<login id>.<code>`, usable once."}}},"ExchangedLogin":{"type":"object","required":["session"],"properties":{"auth_request":{"type":["string","null"],"description":"The auth request the login was for – finish it next."},"session":{"$ref":"#/components/schemas/SessionCreated"}}},"FactorsView":{"type":"object","required":["totp","passkeys","recovery_codes_left","required"],"properties":{"passkeys":{"type":"integer","format":"int64"},"recovery_codes_left":{"type":"integer","format":"int64"},"required":{"type":"boolean","description":"The tenant requires a second factor."},"setup_due":{"type":["string","null"],"format":"date-time","description":"The account has none yet and may log in without one until then (the tenant's grace period)."},"totp":{"type":"boolean"}}},"FileGrantChange":{"type":"object","required":["grantee_kind","grantee_id","rights"],"properties":{"grantee_id":{"type":"string"},"grantee_kind":{"type":"string","description":"`account` or `group`."},"node":{"type":["string","null"],"description":"A directory of the account; leave out for the whole store."},"rights":{"type":"string","description":"Letters of `randws`: read, add, rename, delete, write content, share."}}},"FileGrantView":{"type":"object","required":["grantee_kind","grantee_id","grantee_name","rights"],"properties":{"grantee_id":{"type":"string"},"grantee_kind":{"type":"string","description":"`account` or `group`."},"grantee_name":{"type":"string","description":"The account's address, or `$` and the group's name."},"node":{"type":["string","null"],"description":"A directory; null: the whole store."},"rights":{"type":"string","description":"Letters of `randws`: read, add, rename, delete, write content, share."}}},"FilesOverviewView":{"type":"object","required":["used_bytes"],"properties":{"effective_quota":{"type":["integer","null"],"format":"int64","description":"What holds: the account's own quota or the tenant's default; null for no limit.","minimum":0},"quota":{"type":["integer","null"],"format":"int64","description":"The account's own quota; null when the tenant's default holds.","minimum":0},"used_bytes":{"type":"integer","format":"int64","minimum":0}}},"FilesQuota":{"type":"object","properties":{"bytes":{"type":["integer","null"],"format":"int64","description":"Bytes; null for none (the tenant's default, or no limit).","minimum":0}}},"Finish":{"type":"object","properties":{"consent":{"type":"boolean","description":"The person agreed to what the application asks for (after `urn:kernoid:problem:consent-required`)."}}},"Finished":{"type":"object","required":["callback_url"],"properties":{"callback_url":{"type":"string","description":"Where to send the browser: the application's redirect URI with the code."}}},"GrantChange":{"type":"object","required":["grantee_kind","grantee_id","rights"],"properties":{"grantee_id":{"type":"string"},"grantee_kind":{"type":"string","description":"`account` or `group`."},"mailbox":{"type":["string","null"],"description":"A mailbox of the account; leave out for the whole store."},"rights":{"type":"string","description":"IMAP ACL rights (RFC 4314): letters of `lrswipkxtea`."},"send_as":{"type":"boolean","description":"May send from the account's addresses; for the whole store only."}}},"GrantRoles":{"type":"object","required":["roles"],"properties":{"roles":{"type":"array","items":{"type":"string"}}}},"GrantView":{"type":"object","description":"A project granted to another tenant.","required":["project","project_name","owner","tenant","tenant_name","roles"],"properties":{"owner":{"type":"string","description":"The project's own tenant."},"project":{"type":"string"},"project_name":{"type":"string"},"roles":{"type":"array","items":{"type":"string"},"description":"The roles that tenant may give its accounts and groups."},"tenant":{"type":"string","description":"The tenant it is granted to."},"tenant_name":{"type":"string"}}},"GroupName":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"GroupView":{"type":"object","required":["id","name","members","addresses"],"properties":{"addresses":{"type":"array","items":{"type":"string"},"description":"Addresses mail to the group arrives at; it goes to every member."},"id":{"type":"string"},"members":{"type":"array","items":{"type":"string"},"description":"Account ids."},"name":{"type":"string"}}},"Handoff":{"type":"object","required":["login"],"properties":{"login":{"type":"string","description":"The one-time code from `/idp#link=…`."}}},"ImportedView":{"type":"object","required":["stored","refused"],"properties":{"refused":{"type":"array","items":{"type":"array","items":false,"prefixItems":[{"type":"string"},{"type":"string"}]},"description":"Objects not stored: their UID and why."},"stored":{"type":"integer","minimum":0}}},"InstanceDetails":{"type":"object","required":["id","name","primary_domain","domains","passkey_rp_id"],"properties":{"domains":{"type":"array","items":{"type":"string"}},"id":{"type":"string"},"login_ui_url":{"type":["string","null"],"description":"The instance's own login UI; without one, kernoid's at `/login`."},"name":{"type":"string"},"passkey_rp_id":{"type":"string","description":"The WebAuthn RP ID its passkeys are bound to."},"primary_domain":{"type":"string"}}},"InstanceRoleDefinition":{"type":"object","required":["permissions"],"properties":{"permissions":{"type":"array","items":{"type":"string"},"description":"Instance permissions (e.g. `instance.read`), applied at the instance, and tenant permissions (e.g.\n`directory.read`), applied in every tenant."}}},"InstanceRoleView":{"type":"object","required":["name","permissions","tenant_permissions","builtin"],"properties":{"builtin":{"type":"boolean"},"name":{"type":"string","description":"`instance_admin`, `instance_auditor`, or one of the instance's own."},"permissions":{"type":"array","items":{"type":"string"},"description":"At the instance."},"tenant_permissions":{"type":"array","items":{"type":"string"},"description":"In every tenant of the instance."}}},"InstanceRolesView":{"type":"object","required":["roles","assignments"],"properties":{"assignments":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentView"}},"roles":{"type":"array","items":{"$ref":"#/components/schemas/InstanceRoleView"}}}},"InstanceView":{"type":"object","required":["id","name","primary_domain"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"primary_domain":{"type":"string"}}},"LinkProposalView":{"type":"object","required":["email","provider","may_register"],"properties":{"email":{"type":"string","description":"The provider's verified address, which an account of the instance has."},"may_register":{"type":"boolean","description":"A separate account may be created instead (`POST /v1/idp-logins/register`)."},"provider":{"type":"string"}}},"LinkView":{"type":"object","required":["identity_provider","subject","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"identity_provider":{"type":"string"},"subject":{"type":"string","description":"The account's `sub` at the provider."}}},"LoggedOut":{"type":"object","properties":{"redirect":{"type":["string","null"],"description":"Where to send the browser next: the SAML provider the session came from, to log out there too – or nothing."}}},"LoginOptions":{"type":"object","properties":{"identity_provider":{"oneOf":[{"$ref":"#/components/schemas/ProviderSummary","description":"If set, this address logs in at that identity provider instead of with a password."},{"type":"null"}]}}},"LoginPolicyView":{"type":"object","required":["usernames","email_login"],"properties":{"email_login":{"type":"boolean","description":"A verified contact address logs in as well."},"usernames":{"type":"boolean","description":"Accounts may have usernames to log in with."}}},"LoginUi":{"type":"object","properties":{"url":{"type":["string","null"],"description":"An HTTPS URL without query or fragment; `null` for kernoid's own."}}},"MailDnsView":{"type":"object","required":["domain","records"],"properties":{"domain":{"type":"string"},"records":{"type":"array","items":{"$ref":"#/components/schemas/RecordCheckView"}}}},"MailOverviewView":{"type":"object","required":["shared","used_bytes","mailboxes"],"properties":{"effective_quota":{"type":["integer","null"],"format":"int64","description":"What holds: the account's own quota or the tenant's default; null for no limit.","minimum":0},"mailboxes":{"type":"array","items":{"$ref":"#/components/schemas/MailboxView"}},"quota":{"type":["integer","null"],"format":"int64","description":"The account's own quota; null when the tenant's default holds.","minimum":0},"shared":{"type":"boolean","description":"A shared mailbox, which nobody logs in as."},"used_bytes":{"type":"integer","format":"int64","minimum":0}}},"MailboxView":{"type":"object","required":["id","name","total_emails","unread_emails"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"parent_id":{"type":["string","null"]},"role":{"type":["string","null"]},"total_emails":{"type":"integer","format":"int64","minimum":0},"unread_emails":{"type":"integer","format":"int64","minimum":0}}},"MboxImportView":{"type":"object","required":["imported","failed"],"properties":{"failed":{"type":"integer","format":"int64","description":"Messages refused: not a message, too large, over the quota.","minimum":0},"imported":{"type":"integer","format":"int64","minimum":0}}},"Name":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"NewAccount":{"type":"object","required":["address","display_name"],"properties":{"address":{"type":"string","description":"The login name; on a verified domain of the tenant."},"display_name":{"type":"string"},"password":{"type":["string","null"],"description":"An initial password; without one, the account cannot log in with a password yet."}}},"NewApplication":{"type":"object","required":["project","name","kind","redirect_uris"],"properties":{"kind":{"type":"string","description":"`confidential` (a server, with a secret) or `public` (browser and mobile apps, PKCE only)."},"name":{"type":"string"},"post_logout_redirect_uris":{"type":"array","items":{"type":"string"}},"project":{"type":"string"},"redirect_uris":{"type":"array","items":{"type":"string"}}}},"NewDomain":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string"}}},"NewDrive":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"NewExternalAccount":{"type":"object","required":["display_name"],"properties":{"display_name":{"type":"string"},"email":{"type":["string","null"],"description":"A contact address of any domain; the person confirms it at their next login with it."},"username":{"type":["string","null"],"description":"Where the tenant uses usernames."}}},"NewKey":{"type":"object","required":["kid"],"properties":{"kid":{"type":"string"}}},"NewPassword":{"type":"object","required":["password"],"properties":{"password":{"type":"string"}}},"NewProject":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"NewProvider":{"type":"object","required":["name","issuer"],"properties":{"auto_create":{"type":"boolean"},"auto_link":{"type":"boolean"},"client_id":{"type":"string","description":"OpenID Connect only."},"client_secret":{"type":["string","null"],"description":"The secret kernoid authenticates with at the provider; stored sealed, never shown again."},"domains":{"type":"array","items":{"type":"string"}},"instance_wide":{"type":"boolean","description":"For every tenant of the instance – their verified domains may be routed to it (needs `instance.manage`)."},"issuer":{"type":"string","description":"OpenID Connect: the issuer. SAML: the provider's entity ID."},"name":{"type":"string"},"register":{"type":"boolean","description":"Offered to everyone on the login page; creates accounts where the tenant allows registration."},"saml":{"oneOf":[{"$ref":"#/components/schemas/SamlView","description":"Set for a SAML 2.0 provider."},{"type":"null"}]},"scopes":{"type":"array","items":{"type":"string"},"description":"`openid` is added; `email` and `profile` let kernoid create and link accounts."},"sync_profile":{"type":"boolean"}}},"NewRegistrationBody":{"type":"object","required":["email","password","display_name"],"properties":{"display_name":{"type":"string"},"email":{"type":"string","description":"The code goes here; it becomes the verified contact address."},"native_address":{"type":["string","null"],"description":"An address of one's own on one of the offered domains: an account with a mailbox."},"password":{"type":"string"},"username":{"type":["string","null"],"description":"Where usernames are offered."}}},"NewScimToken":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"E.g. the directory's name."}}},"NewSharedMailbox":{"type":"object","required":["address","display_name"],"properties":{"address":{"type":"string","description":"On a verified domain of the tenant."},"display_name":{"type":"string"}}},"NewSieveScript":{"type":"object","required":["content"],"properties":{"activate":{"type":"boolean","description":"Make it the script that runs."},"content":{"type":"string"}}},"OptionsView":{"type":"object","description":"What an application may do beyond the basic flow, and how it learns of logouts.","properties":{"access_token_format":{"type":"string","description":"`opaque` (checked with kernoid at userinfo or introspection) or `jwt` (RFC 9068, checked by the resource\nserver itself)."},"backchannel_logout_uri":{"type":["string","null"],"description":"Receives a logout token when a session it logged in to ends (Back-Channel Logout 1.0); HTTPS, public."},"consent_required":{"type":"boolean","description":"Asks the person to agree before the first login."},"frontchannel_logout_uri":{"type":["string","null"],"description":"Loaded in a frame when the person logs out through kernoid (Front-Channel Logout 1.0); HTTPS."},"offline_access":{"type":"boolean","description":"May ask for `offline_access`: refresh tokens that outlive the session, with the person's consent."}}},"OwnCollectionGrantChange":{"type":"object","required":["grantee","level"],"properties":{"grantee":{"type":"string","description":"An address of an account of the tenant, or `$` and a group's name."},"level":{"type":"string","description":"`freebusy`, `read`, `rsvp`, `write` or `admin`; address books: `read`, `write` or `admin`."}}},"OwnGrantChange":{"type":"object","required":["grantee","rights"],"properties":{"grantee":{"type":"string","description":"An address of an account of the tenant, or `$` and a group's name."},"mailbox":{"type":["string","null"],"description":"A mailbox of one's own; leave out for the whole store."},"rights":{"type":"string","description":"IMAP ACL rights (RFC 4314): letters of `lrswipkxtea`."}}},"PasskeyRpId":{"type":"object","required":["rp_id"],"properties":{"rp_id":{"type":"string","description":"One of the instance's domains or a parent domain of one."}}},"PasskeyView":{"type":"object","required":["id","name","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"last_used_at":{"type":["string","null"],"format":"date-time"},"name":{"type":"string"}}},"PasswordChange":{"type":"object","required":["current_password","new_password"],"properties":{"current_password":{"type":"string"},"new_password":{"type":"string"}}},"PermissionsView":{"type":"object","required":["account","tenant","permissions"],"properties":{"account":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"},"description":"E.g. `directory.read`, `groups.manage`, `instance.read`."},"tenant":{"type":"string","description":"The tenant administered."}}},"Policy":{"type":"object","required":["mfa_required"],"properties":{"mfa_required":{"type":"boolean"}}},"PrimaryDomain":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string"}}},"Problem":{"type":"object","required":["type","title","status"],"properties":{"detail":{"type":["string","null"]},"status":{"type":"integer","format":"int32","minimum":0},"title":{"type":"string"},"type":{"type":"string","description":"A URI identifying the kind of problem; `about:blank` when the status says it all."}}},"Profile":{"type":"object","required":["display_name"],"properties":{"display_name":{"type":"string"}}},"ProjectChange":{"type":"object","properties":{"name":{"type":["string","null"]},"role_assertion":{"type":["boolean","null"]},"role_check":{"type":["boolean","null"]}}},"ProjectRoleDefinition":{"type":"object","required":["display_name"],"properties":{"display_name":{"type":"string"},"group":{"type":["string","null"]}}},"ProjectRoleView":{"type":"object","required":["key","display_name"],"properties":{"display_name":{"type":"string"},"group":{"type":["string","null"]},"key":{"type":"string"}}},"ProjectView":{"type":"object","required":["id","name","role_assertion","role_check","roles"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"role_assertion":{"type":"boolean","description":"Project roles go into ID tokens and userinfo (`urn:kernoid:project:roles`)."},"role_check":{"type":"boolean","description":"Only accounts with a role in the project may log in to its applications."},"roles":{"type":"array","items":{"$ref":"#/components/schemas/ProjectRoleView"}}}},"ProviderChange":{"type":"object","properties":{"active":{"type":["boolean","null"]},"auto_create":{"type":["boolean","null"]},"auto_link":{"type":["boolean","null"]},"client_id":{"type":["string","null"]},"domains":{"type":["array","null"],"items":{"type":"string"}},"issuer":{"type":["string","null"]},"name":{"type":["string","null"]},"register":{"type":["boolean","null"]},"saml":{"oneOf":[{"$ref":"#/components/schemas/SamlView","description":"SAML settings, replacing the earlier ones."},{"type":"null"}]},"scopes":{"type":["array","null"],"items":{"type":"string"}},"sync_profile":{"type":["boolean","null"]}}},"ProviderSummary":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"ProviderView":{"type":"object","required":["id","name","kind","issuer","client_id","scopes","domains","auto_create","auto_link","sync_profile","register","instance_wide","has_secret","active","redirect_uri"],"properties":{"active":{"type":"boolean"},"auto_create":{"type":"boolean"},"auto_link":{"type":"boolean"},"client_id":{"type":"string"},"domains":{"type":"array","items":{"type":"string"},"description":"Mail domains whose logins go to this provider."},"has_secret":{"type":"boolean"},"id":{"type":"string"},"instance_wide":{"type":"boolean","description":"Serves the domains of every tenant of the instance (changed with `instance.manage`)."},"issuer":{"type":"string","description":"OpenID Connect: the issuer. SAML: the provider's entity ID."},"kind":{"type":"string","description":"`oidc` or `saml`."},"name":{"type":"string"},"redirect_uri":{"type":"string","description":"Register this at the provider: the redirect URI (OpenID Connect) or the Assertion Consumer Service URL (SAML)."},"register":{"type":"boolean","description":"Offered to everyone on the login page; creates accounts where the tenant allows registration (RFC 0003)."},"saml":{"oneOf":[{"$ref":"#/components/schemas/SamlView","description":"SAML only."},{"type":"null"}]},"scopes":{"type":"array","items":{"type":"string"}},"sp_entity_id":{"type":["string","null"],"description":"SAML: kernoid's entity ID at this instance – metadata at `/idp/saml/metadata`."},"sync_profile":{"type":"boolean","description":"The display name follows the provider's at every login."}}},"QueuedView":{"type":"object","required":["message","address","status","attempts","next_attempt_at"],"properties":{"address":{"type":"string"},"attempts":{"type":"integer","format":"int32"},"last_error":{"type":["string","null"]},"message":{"type":"string"},"next_attempt_at":{"type":"string","format":"date-time"},"status":{"type":"string"}}},"Quota":{"type":"object","properties":{"bytes":{"type":["integer","null"],"format":"int64","description":"Bytes; null for none (the tenant's default, or no limit).","minimum":0}}},"Readiness":{"type":"object","required":["database","blob"],"properties":{"blob":{"$ref":"#/components/schemas/Check"},"database":{"$ref":"#/components/schemas/Check"}}},"RecordCheckView":{"type":"object","required":["kind","name","record_type","expected","found","status"],"properties":{"expected":{"type":"string","description":"What to publish."},"found":{"type":"array","items":{"type":"string"},"description":"What DNS has now."},"kind":{"type":"string","description":"`MX`, `SPF`, `DKIM` or `DMARC`."},"name":{"type":"string","description":"The name the record belongs at."},"record_type":{"type":"string","description":"`MX` or `TXT`."},"status":{"type":"string","description":"`ok`, `missing` or `different`."}}},"RecoveryCodes":{"type":"object","required":["codes"],"properties":{"codes":{"type":"array","items":{"type":"string"},"description":"Shown this once; each works once."}}},"Registered":{"type":"object","required":["account"],"properties":{"account":{"type":"string","description":"The new account; log in with the address or username and the password."}}},"RegistrationOptionsView":{"type":"object","required":["open","domains","usernames","by_email"],"properties":{"by_email":{"type":"boolean","description":"kernoid can send the code; without it, registering works only with the providers."},"domains":{"type":"array","items":{"type":"string"},"description":"Domains on which new accounts may take an address – a mailbox."},"open":{"type":"boolean","description":"People without an address of their own may register."},"usernames":{"type":"boolean","description":"A username may be chosen."}}},"RegistrationStarted":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"Confirm with the code at `/v1/registrations/{id}/confirm`."}}},"RegistrationTenant":{"type":"object","properties":{"tenant":{"type":["string","null"],"description":"Where people without an address of a tenant register; null: nowhere."}}},"RegistrationView":{"type":"object","required":["allowed","domains"],"properties":{"allowed":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"},"description":"Verified domains of the tenant on which new accounts may take an address – a mailbox."}}},"Retention":{"type":"object","properties":{"junk_days":{"type":["integer","null"],"format":"int32","description":"Days emails stay in the accounts' Junk; null keeps them.","minimum":0},"trash_days":{"type":["integer","null"],"format":"int32","description":"Days emails stay in the accounts' Trash; null keeps them.","minimum":0}}},"RoleDefinition":{"type":"object","required":["permissions"],"properties":{"permissions":{"type":"array","items":{"type":"string"},"description":"Tenant permissions, e.g. `directory.read`."}}},"RoleView":{"type":"object","required":["name","permissions","builtin"],"properties":{"builtin":{"type":"boolean","description":"Built in (the same in every tenant), or defined by the tenant."},"name":{"type":"string","description":"E.g. `tenant_admin`, or a name the tenant chose."},"permissions":{"type":"array","items":{"type":"string"}}}},"RolesView":{"type":"object","required":["roles","assignments"],"properties":{"assignments":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentView"},"description":"Who holds which role in the tenant."},"roles":{"type":"array","items":{"$ref":"#/components/schemas/RoleView"},"description":"The roles there are: built in and the tenant's own."}}},"SamlView":{"type":"object","required":["sso_url","certificates"],"properties":{"certificates":{"type":"array","items":{"type":"string"},"description":"The provider's signing certificates, base64 DER (PEM is accepted too)."},"email_attribute":{"type":["string","null"]},"name_attribute":{"type":["string","null"]},"sign_requests":{"type":"boolean","description":"Sign AuthnRequests with kernoid's SAML key of the instance."},"slo_url":{"type":["string","null"],"description":"The provider's single logout service (HTTP-Redirect binding)."},"sso_url":{"type":"string","description":"Where kernoid sends the AuthnRequest (HTTP-Redirect binding)."}}},"ScimTokenCreated":{"type":"object","required":["id","token","endpoint"],"properties":{"endpoint":{"type":"string","description":"The SCIM base URL to give the directory."},"id":{"type":"string"},"token":{"type":"string","description":"The bearer token for the directory – shown this once."}}},"ScimTokenView":{"type":"object","required":["id","name","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"last_used_at":{"type":["string","null"],"format":"date-time"},"name":{"type":"string"}}},"Secret":{"type":"object","required":["client_secret"],"properties":{"client_secret":{"type":"string"}}},"ServicePolicyView":{"type":"object","required":["assign","approval"],"properties":{"approval":{"type":"boolean","description":"New accounts get it only as requested, until an administrator grants it."},"assign":{"type":"string","description":"Who gets it when an account is created: `none`, `native` or `all`."},"service":{"type":"string","description":"`mail` or `files`; ignored in a request."}}},"ServiceView":{"type":"object","required":["service","state"],"properties":{"service":{"type":"string","description":"`mail` or `files`."},"state":{"type":"string","description":"`on`, or `requested` – waiting for an administrator."}}},"SessionCreated":{"type":"object","required":["id","expires_at","account"],"properties":{"account":{"$ref":"#/components/schemas/AccountView"},"device_token":{"type":["string","null"],"description":"After a password login: keep it for this address, and send it with the next login (`device_token`)."},"expires_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"token":{"type":["string","null"],"description":"The session token: shown this once, sent as `Authorization: Bearer <token>`. Left out when the session is kept\nin the cookie."}}},"SessionSummaryView":{"type":"object","required":["id","checks","created_at","expires_at"],"properties":{"checks":{"type":"array","items":{"type":"string"}},"client_address":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"id":{"type":"string"},"user_agent":{"type":["string","null"]}}},"SessionView":{"type":"object","required":["id","account","checks","created_at","expires_at"],"properties":{"account":{"$ref":"#/components/schemas/AccountView"},"checks":{"type":"array","items":{"type":"string"},"description":"The checks the session passed, e.g. `password`."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"id":{"type":"string"}}},"SharedStoreView":{"type":"object","required":["account","address","display_name","rights","send_as"],"properties":{"account":{"type":"string","description":"The owner's account id – the JMAP account id."},"address":{"type":"string"},"display_name":{"type":"string"},"rights":{"type":"string","description":"Rights on the whole store (RFC 4314); further rights may hold on single mailboxes."},"send_as":{"type":"boolean"}}},"SieveScriptView":{"type":"object","required":["name","content","active"],"properties":{"active":{"type":"boolean"},"content":{"type":"string"},"name":{"type":"string"}}},"SigningKeyView":{"type":"object","required":["kid","algorithm","state","created_at","state_since"],"properties":{"algorithm":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"kid":{"type":"string"},"state":{"type":"string","description":"`initial` (published, not signing), `active` (signing) or `inactive` (published, no longer signing)."},"state_since":{"type":"string","format":"date-time"}}},"StartLink":{"type":"object","required":["identity_provider"],"properties":{"identity_provider":{"type":"string"}}},"StartLogin":{"type":"object","required":["identity_provider"],"properties":{"auth_request":{"type":["string","null"],"description":"The OpenID Connect auth request to finish afterwards, if any."},"identity_provider":{"type":"string"},"login_hint":{"type":["string","null"],"description":"The address typed in, passed on as `login_hint`."}}},"StartedLogin":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"Send the browser here."}}},"Switch":{"type":"object","required":["enabled"],"properties":{"enabled":{"type":"boolean"}}},"TenantChange":{"type":"object","properties":{"active":{"type":["boolean","null"]},"name":{"type":["string","null"]}}},"TenantSummary":{"type":"object","required":["id","name","active"],"properties":{"active":{"type":"boolean"},"id":{"type":"string"},"name":{"type":"string"}}},"TenantView":{"type":"object","required":["id","instance","name","active","mfa_required","mfa_grace_days","domains","modules"],"properties":{"active":{"type":"boolean"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/DomainView"}},"id":{"type":"string"},"instance":{"type":"string"},"mfa_grace_days":{"type":"integer","format":"int32","description":"Days an account without a second factor may still log in without one, after the requirement (or the account)\nbegan.","minimum":0},"mfa_required":{"type":"boolean","description":"Logins to applications need a second factor, and so does administration."},"modules":{"type":"array","items":{"type":"string"},"description":"The modules the tenant has switched on."},"name":{"type":"string"}}},"TotpSetupView":{"type":"object","required":["secret","uri","qr_code"],"properties":{"qr_code":{"type":"string","description":"The URI as a QR code: an SVG image as a `data:` URL."},"secret":{"type":"string","description":"The secret in base32, for typing it in."},"uri":{"type":"string","description":"`otpauth://` URI for a QR code."}}},"UsernameChange":{"type":"object","properties":{"username":{"type":["string","null"],"description":"Null removes it."}}},"Verification":{"type":"object","properties":{"trust":{"type":"boolean","description":"Mark it verified without asking DNS – instance administrators only (`tenants.manage`)."}}},"Version":{"type":"object","required":["name","version"],"properties":{"name":{"type":"string"},"version":{"type":"string"}}}}}}
