{"openapi":"3.1.0","info":{"title":"marve-py-user-service","version":"0.1.0"},"paths":{"/users":{"get":{"tags":["Users"],"summary":"List users","description":"Paged, ten to a page. A super administrator sees every user; anybody else\nsees their own organisation's. Any field of the user can be used as a filter (`?field=value`),\nnot only the ones listed; text is matched partially and case-insensitively, and `true`/`false`\n(or `1`/`0`) become booleans. `all` searches across the text fields instead. `ordering=field`\nsorts ascending, `ordering=-field` descending; the default is newest first.","operationId":"get_users_users_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Page number. `all` turns paging off.","examples":["1"],"title":"Page"},"description":"Page number. `all` turns paging off."},{"name":"ordering","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`field` ascending, `-field` descending. Default `-created_at_timestamp`.","examples":["last_name"],"title":"Ordering"},"description":"`field` ascending, `-field` descending. Default `-created_at_timestamp`."},{"name":"all","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search across the text fields.","title":"All"},"description":"Search across the text fields."},{"name":"email","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Partial, case-insensitive.","title":"Email"},"description":"Partial, case-insensitive."},{"name":"role","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"For example `user` or `organisation_admin`.","title":"Role"},"description":"For example `user` or `organisation_admin`."},{"name":"is_active","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`true` or `false`.","title":"Is Active"},"description":"`true` or `false`."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"reference":{"type":"string"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"full_name":{"type":["string","null"]},"mobile_number":{"type":["string","null"]},"country":{"type":["string","null"]},"email":{"type":"string"},"role":{"type":"string","description":"For example `user`, `organisation_admin` or `super_admin`."},"is_verified_email":{"type":"boolean"},"is_verified_phone":{"type":"boolean"},"is_active":{"type":"boolean"},"license":{"type":"object","additionalProperties":true},"signup_status":{"type":"array","description":"The signup steps done, each `{STEP: timestamp}`.","items":{"type":"object","additionalProperties":true}},"organisation":{"type":"object","description":"The user's organisation, or `{}`.","additionalProperties":true},"created_at_timestamp":{"type":["string","null"]},"updated_at_timestamp":{"type":["string","null"]},"consent_preferences":{"type":"object","additionalProperties":true},"user_preferences":{"type":"object","additionalProperties":true},"last_login_at":{"type":["string","null"]},"models_used":{"type":"object","description":"Each model the user has run, with when they last ran it.","additionalProperties":true}},"required":["reference","first_name","last_name","full_name","mobile_number","country","email","role","is_verified_email","is_verified_phone","is_active","license","signup_status","organisation","created_at_timestamp","updated_at_timestamp","consent_preferences","user_preferences","last_login_at","models_used"],"description":"A user, as `UserDto.to_dict` renders it.","additionalProperties":true}},"pagination":{"type":"object","properties":{"current_page":{"type":"integer"},"page_size":{"type":"integer"},"total_records":{"type":"integer"},"total_pages":{"type":"integer"},"has_next":{"type":"boolean"},"has_previous":{"type":"boolean"}},"required":["current_page","page_size","total_records","total_pages","has_next","has_previous"],"additionalProperties":true}},"required":["items","pagination"],"additionalProperties":true},"example":{"items":[{"reference":"11111111-1111-1111-1111-111111111111","first_name":"Jane","last_name":"Doe","full_name":"Jane Doe","mobile_number":"+447700900123","country":"GB","email":"jane@example.com","role":"user","is_verified_email":true,"is_verified_phone":false,"is_active":true,"license":{},"signup_status":[{"PASSWORD_CREATED":"2026-01-01T09:30:00"},{"ACCOUNT_CREATED":"2026-01-01T09:30:00"}],"organisation":{"organisation_reference":"55555555-5555-5555-5555-555555555555","organisation_name":"Acme"},"created_at_timestamp":"2026-01-01T09:30:00","updated_at_timestamp":"2026-01-01T09:30:00","consent_preferences":{"marketing":false},"user_preferences":{},"last_login_at":"2026-01-02T08:15:00","models_used":{"CS20_7L":"2026-01-02T08:20:00"}}],"pagination":{"current_page":1,"page_size":10,"total_records":1,"total_pages":1,"has_next":false,"has_previous":false}}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/export":{"get":{"tags":["Users"],"summary":"Export user activity (CSV)","description":"One row per user the caller may list: name, email, organisation, last login, licensed models, and each model used with when it was last run.","operationId":"export_activity_users_export_get","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}},"text/csv":{"example":"Name,Email,Organisation,Last login,Licensed models,Models used\r\nJane Doe,jane@example.com,Acme,2026-01-02T08:15:00,CS20_7L,CS20_7L (last 2026-01-02T08:20:00)\r\n"}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/message":{"post":{"tags":["Users"],"summary":"Email a message to users","description":"Sends the message to the users named by `user_references`, `emails` or `search`, in any mix, or with none of these to every active user the caller may list. A reference or address the caller cannot list is refused by name, as is a search matching nobody. Answers with who it went to; the emails follow from the notification service.","operationId":"send_message_users_message_post","requestBody":{"content":{"application/json":{"schema":{"properties":{"subject":{"type":"string","description":"The email subject, at most 200 characters."},"message":{"type":"string","description":"Plain text, at most 10000 characters; a blank line starts a new paragraph."},"user_references":{"items":{"type":"string"},"type":"array","description":"Users to send to, by reference."},"emails":{"items":{"type":"string"},"type":"array","description":"Users to send to, by email address (any case)."},"search":{"type":"string","description":"Users to send to, by the users list's search: name, email, organisation, licence product or model, e.g. polpred or CS20_7L."}},"additionalProperties":true,"type":"object","required":["subject","message"]},"examples":{"Every active user":{"summary":"Every active user","value":{"subject":"Planned maintenance","message":"MARVE will be unavailable on Saturday morning."}},"Users by reference":{"summary":"Users by reference","value":{"subject":"Planned maintenance","message":"MARVE will be unavailable on Saturday morning.","user_references":["11111111-1111-1111-1111-111111111111"]}},"Users by email":{"summary":"Users by email","value":{"subject":"Planned maintenance","message":"MARVE will be unavailable on Saturday morning.","emails":["jane@acme.com","sam@tide.co"]}},"Users found by search":{"summary":"Users found by search","value":{"subject":"Planned maintenance","message":"MARVE will be unavailable on Saturday morning.","search":"CS20_7L"}}}}},"required":true},"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"properties":{"reference":{"type":"string","description":"Names this send, for quoting it back."},"recipients":{"type":"integer","description":"How many users the message is going to."},"emails":{"items":{"type":"string"},"type":"array","description":"Who it is going to."}},"additionalProperties":true,"type":"object","required":["reference","recipients","emails"]},"example":{"reference":"77777777-7777-7777-7777-777777777777","recipients":2,"emails":["jane@acme.com","sam@tide.co"]}}}},"400":{"description":"The body or a value in it is not valid","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":400,"timestamp":"2026-09-30T10:00:00.000000"}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/signup":{"post":{"tags":["Users"],"summary":"Start a signup","description":"Starts the email signup for a new user. Refused while one for the same email is still in progress (15 minutes). 400 if `invite_reference` names an invite that has run out.","operationId":"signup_user_users_signup_post","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"}},"required":["reference"],"description":"The reference of the user or record acted on.","additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111"}}}},"400":{"description":"The body or a value in it is not valid","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":400,"timestamp":"2026-09-30T10:00:00.000000"}}}},"409":{"description":"Already exists, a signup for that email is still in progress, or still in an organisation","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":409,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"invite_reference":{"type":["string","null"],"description":"The invite being answered, when there is one."}},"required":["email"]},"example":{"email":"jane@example.com"}}}}}},"/users/current":{"get":{"tags":["Users"],"summary":"The signed-in user","description":"Resolved from the token.","operationId":"get_current_user_users_current_get","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"full_name":{"type":["string","null"]},"mobile_number":{"type":["string","null"]},"country":{"type":["string","null"]},"email":{"type":"string"},"role":{"type":"string","description":"For example `user`, `organisation_admin` or `super_admin`."},"is_verified_email":{"type":"boolean"},"is_verified_phone":{"type":"boolean"},"is_active":{"type":"boolean"},"license":{"type":"object","additionalProperties":true},"signup_status":{"type":"array","description":"The signup steps done, each `{STEP: timestamp}`.","items":{"type":"object","additionalProperties":true}},"organisation":{"type":"object","description":"The user's organisation, or `{}`.","additionalProperties":true},"created_at_timestamp":{"type":["string","null"]},"updated_at_timestamp":{"type":["string","null"]},"consent_preferences":{"type":"object","additionalProperties":true},"user_preferences":{"type":"object","additionalProperties":true},"last_login_at":{"type":["string","null"]},"models_used":{"type":"object","description":"Each model the user has run, with when they last ran it.","additionalProperties":true}},"required":["reference","first_name","last_name","full_name","mobile_number","country","email","role","is_verified_email","is_verified_phone","is_active","license","signup_status","organisation","created_at_timestamp","updated_at_timestamp","consent_preferences","user_preferences","last_login_at","models_used"],"description":"A user, as `UserDto.to_dict` renders it.","additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111","first_name":"Jane","last_name":"Doe","full_name":"Jane Doe","mobile_number":"+447700900123","country":"GB","email":"jane@example.com","role":"user","is_verified_email":true,"is_verified_phone":false,"is_active":true,"license":{},"signup_status":[{"PASSWORD_CREATED":"2026-01-01T09:30:00"},{"ACCOUNT_CREATED":"2026-01-01T09:30:00"}],"organisation":{"organisation_reference":"55555555-5555-5555-5555-555555555555","organisation_name":"Acme"},"created_at_timestamp":"2026-01-01T09:30:00","updated_at_timestamp":"2026-01-01T09:30:00","consent_preferences":{"marketing":false},"user_preferences":{},"last_login_at":"2026-01-02T08:15:00","models_used":{"CS20_7L":"2026-01-02T08:20:00"}}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/health":{"get":{"tags":["Users"],"summary":"Health check","operationId":"health_users_health_get","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"properties":{"message":{"type":"string"}},"additionalProperties":true,"type":"object","required":["message"]},"example":{"message":"marve-py-user-service is okay and running, fast!"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"properties":{},"additionalProperties":true,"type":"object","description":"Field name, or `message`, to a list of messages."},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"additionalProperties":true,"type":"object","required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError."},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}}}}},"/users/invite/{invite_reference}/accept":{"patch":{"tags":["Users"],"summary":"Accept an invite","description":"Accepts the invite for the signed-in user. No body. 400 once its 7 days have run out.","operationId":"accept_invite_users_invite__invite_reference__accept_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"invite_reference","in":"path","required":true,"schema":{"type":"string","title":"Invite Reference"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"}},"required":["reference"],"description":"The reference of the user or record acted on.","additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111"}}}},"400":{"description":"The body or a value in it is not valid","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":400,"timestamp":"2026-09-30T10:00:00.000000"}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/{reference}":{"post":{"tags":["Users"],"summary":"Complete the account","description":"Fills in the details after signup. `reference` must be the signed-in user. Accepts a pending invite for this email. One that has run out is skipped: the account is still created, without joining the organisation.","operationId":"create_user_account_users__reference__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string","title":"Reference"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"}},"required":["reference"],"description":"The reference of the user or record acted on.","additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111"}}}},"400":{"description":"The body or a value in it is not valid","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":400,"timestamp":"2026-09-30T10:00:00.000000"}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"country":{"type":"string"},"mobile_number":{"type":"string"},"consent_preferences":{"type":"object","description":"Consent name to true or false.","additionalProperties":true}},"required":["first_name","last_name","country","mobile_number","consent_preferences"]},"example":{"first_name":"Jane","last_name":"Doe","country":"GB","mobile_number":"+447700900123","consent_preferences":{"marketing":false}}}}}},"put":{"tags":["Users"],"summary":"Update a user","description":"Partial: send only what changes.","operationId":"update_user_users__reference__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string","title":"Reference"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"}},"required":["reference"],"description":"The reference of the user or record acted on.","additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111"}}}},"400":{"description":"The body or a value in it is not valid","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":400,"timestamp":"2026-09-30T10:00:00.000000"}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"mobile_number":{"type":["string","null"]},"country":{"type":["string","null"]},"organisation":{"type":["object","null"],"description":"Must carry `organisation_reference` when given.","additionalProperties":true},"license":{"type":["object","null"],"additionalProperties":true},"user_preferences":{"type":["object","null"],"additionalProperties":true}},"description":"Send only what changes."},"example":{"first_name":"Jane"}}}}},"get":{"tags":["Users"],"summary":"One user","operationId":"get_user_by_reference_users__reference__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string","title":"Reference"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"full_name":{"type":["string","null"]},"mobile_number":{"type":["string","null"]},"country":{"type":["string","null"]},"email":{"type":"string"},"role":{"type":"string","description":"For example `user`, `organisation_admin` or `super_admin`."},"is_verified_email":{"type":"boolean"},"is_verified_phone":{"type":"boolean"},"is_active":{"type":"boolean"},"license":{"type":"object","additionalProperties":true},"signup_status":{"type":"array","description":"The signup steps done, each `{STEP: timestamp}`.","items":{"type":"object","additionalProperties":true}},"organisation":{"type":"object","description":"The user's organisation, or `{}`.","additionalProperties":true},"created_at_timestamp":{"type":["string","null"]},"updated_at_timestamp":{"type":["string","null"]},"consent_preferences":{"type":"object","additionalProperties":true},"user_preferences":{"type":"object","additionalProperties":true},"last_login_at":{"type":["string","null"]},"models_used":{"type":"object","description":"Each model the user has run, with when they last ran it.","additionalProperties":true}},"required":["reference","first_name","last_name","full_name","mobile_number","country","email","role","is_verified_email","is_verified_phone","is_active","license","signup_status","organisation","created_at_timestamp","updated_at_timestamp","consent_preferences","user_preferences","last_login_at","models_used"],"description":"A user, as `UserDto.to_dict` renders it.","additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111","first_name":"Jane","last_name":"Doe","full_name":"Jane Doe","mobile_number":"+447700900123","country":"GB","email":"jane@example.com","role":"user","is_verified_email":true,"is_verified_phone":false,"is_active":true,"license":{},"signup_status":[{"PASSWORD_CREATED":"2026-01-01T09:30:00"},{"ACCOUNT_CREATED":"2026-01-01T09:30:00"}],"organisation":{"organisation_reference":"55555555-5555-5555-5555-555555555555","organisation_name":"Acme"},"created_at_timestamp":"2026-01-01T09:30:00","updated_at_timestamp":"2026-01-01T09:30:00","consent_preferences":{"marketing":false},"user_preferences":{},"last_login_at":"2026-01-02T08:15:00","models_used":{"CS20_7L":"2026-01-02T08:20:00"}}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Users"],"summary":"Delete a user","description":"`admin` or `super_admin` only (403 for anybody else). 409 while the person is still in an organisation: remove them first, which frees their seats. The login goes too, so the email can be registered again as a new account.","operationId":"delete_user_users__reference__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string","title":"Reference"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"}},"required":["reference"],"description":"The reference of the user or record acted on.","additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111"}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"403":{"description":"Signed in, but this role may not do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":403,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"409":{"description":"Already exists, a signup for that email is still in progress, or still in an organisation","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":409,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/{reference}/export":{"get":{"tags":["Users"],"summary":"Export one user's activity (CSV)","description":"The same row as the full export, for one user the caller may list.","operationId":"export_user_activity_users__reference__export_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string","title":"Reference"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}},"text/csv":{"example":"Name,Email,Organisation,Last login,Licensed models,Models used\r\nJane Doe,jane@example.com,Acme,2026-01-02T08:15:00,CS20_7L,CS20_7L (last 2026-01-02T08:20:00)\r\n"}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/{reference}/role":{"put":{"tags":["Users"],"summary":"Change a user's role","description":"An organisation has one `organisation_admin`. Making somebody it hands the role over: the old one becomes a `user`, and can then leave. The licence the organisation uses moves with it if the old one owned it and holds no other, the new one has a seat on it and no other licence, and it is not linked to another organisation. The only one cannot be made a `user` (403), so appoint a new one first. An `organisation_admin` cannot change roles in another organisation (403). 409 if an invitation is still offering the role to somebody else, or if the person named has a deactivated account and would take it over.","operationId":"change_role_users__reference__role_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string","title":"Reference"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"}},"required":["reference"],"description":"The reference of the user or record acted on.","additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111"}}}},"400":{"description":"The body or a value in it is not valid","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":400,"timestamp":"2026-09-30T10:00:00.000000"}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"403":{"description":"Signed in, but this role may not do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":403,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"409":{"description":"Already exists, a signup for that email is still in progress, or still in an organisation","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":409,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","description":"`organisation_admin` or `user`."}},"required":["role"]},"example":{"role":"organisation_admin"}}}}}},"/users/{reference}/deactivate":{"post":{"tags":["Users"],"summary":"Deactivate an account","description":"Your own, or, as an administrator, somebody else's. An `organisation_admin` only reaches their own organisation's members (403 otherwise). Closing your own also blocks your login and ends your session. An administrator blocks somebody else's login with `POST /accounts/{reference}/deactivate`. The seat is kept either way: remove them from the product or the organisation to free it.","operationId":"deactivate_account_users__reference__deactivate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"reference","in":"path","required":true,"schema":{"type":"string","title":"Reference"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":"string"}},"required":["reference"],"description":"The reference of the user or record acted on.","additionalProperties":true},"example":{"reference":"11111111-1111-1111-1111-111111111111"}}}},"400":{"description":"The body or a value in it is not valid","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":400,"timestamp":"2026-09-30T10:00:00.000000"}}}},"401":{"description":"No token, an expired token, or not allowed to do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":401,"timestamp":"2026-09-30T10:00:00.000000"}}}},"403":{"description":"Signed in, but this role may not do this","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":403,"timestamp":"2026-09-30T10:00:00.000000"}}}},"404":{"description":"No such user, or not the signed-in user","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":404,"timestamp":"2026-09-30T10:00:00.000000"}}}},"500":{"description":"Unexpected failure. Quote `error_reference` when reporting it","content":{"application/json":{"schema":{"type":"object","properties":{"error_reference":{"type":"string","description":"Quote this when reporting a failure."},"error_type":{"type":"string"},"errors":{"type":"object","properties":{},"description":"Field name, or `message`, to a list of messages.","additionalProperties":true},"status_code":{"type":"integer"},"timestamp":{"type":"string"}},"required":["error_reference","error_type","errors","status_code","timestamp"],"description":"Every error from this service, whatever the cause. Rendered by InfrastructureError.","additionalProperties":true},"example":{"error_reference":"b7825cd3-59dc-43a9-9e1f-964676d3cf72","error_type":"NOT_FOUND_ERROR","errors":{"message":["User with reference 11111111-1111-1111-1111-111111111111 not found."]},"status_code":500,"timestamp":"2026-09-30T10:00:00.000000"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"At least 10 characters."}},"required":["reason"],"additionalProperties":true},"example":{"reason":"Leaving the organisation"}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","description":"The access token from sign-in.","scheme":"bearer"}}}}