{"openapi":"3.0.3","info":{"title":"Speedify Teams API","version":"1.6.3","description":"The Speedify for Teams API is used to query information and manage user accounts in your Speedify team. The API is RESTful, accepts JSON request bodies, and returns JSON responses with standard HTTP status codes.\n\n## Getting Started\n\n1. You need a [Speedify for Teams account](https://speedify.com/enterprise/for-teams/).\n2. Once you have an account, log in to the admin console and navigate to [https://my.speedify.com/api](https://my.speedify.com/api).\n3. Generate an API key by clicking the **+** button. Enter a description and click **Generate Key**.\n4. Copy the key and use it in your application (see Authentication below).\n\n## Versioning\n\nAll endpoints begin with a version number (v1, v2, etc.). Non-breaking changes are added without a version bump. Breaking changes result in a new version; the previous version will continue to be supported for a transition period.\n\n## Authentication\n\nThe API requires an API key sent in the `x-api-key` header:\n\n```\ncurl -H \"x-api-key: YOUR_API_KEY\" https://api.speedify.com/v1/teams\n```\n\nKeep your API key private — do not add it to public repositories. If a key is compromised, revoke it from the [admin console](https://my.speedify.com/api).\n\nLegacy HTTP Basic Authentication is also supported, where the password is the API key and the username is ignored.","contact":{"name":"Connectify, Inc.","url":"https://speedify.com"}},"servers":[{"url":"https://api.speedify.com","description":"Current instance"},{"url":"https://api.speedify.com","description":"Production"}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"Team API key passed via the x-api-key header."},"BasicAuth":{"type":"http","scheme":"basic","description":"Basic Auth where the password is the team API key (username is ignored)."}},"schemas":{"Subscription":{"type":"object","properties":{"referenceId":{"type":"string","description":"Subscription reference identifier","example":"CON170207-2840-94312S"},"active":{"type":"integer","description":"Subscription status: 1 = active, 0 = deactivated (team no longer has unlimited data)","example":1},"url":{"type":"string","nullable":true,"description":"URL used to manage payment and billing address aspects of the subscription. Null when no customer portal URL is available.","example":"https://sites.fastspring.com/speedify/order/s/CON170207-2847-37127S"},"seats":{"type":"integer","description":"Number of seats available to the team. Dictates the total number of members (including guests) that a team can have. Can be changed using the /seats endpoint.","example":50},"nextPeriodDate":{"type":"string","format":"date-time","description":"Date when the subscription will be renewed","example":"2026-04-01T00:00:00.000Z"},"endDate":{"type":"string","description":"Date the subscription will end. Most auto-renewing subscriptions do not have an end date and the value will be \"0000-00-00 00:00:00\". If canceled or set for a fixed term, this will be a future date.","example":"0000-00-00 00:00:00"}}},"SubscriptionV2":{"description":"v2 subscription shape. Identical to Subscription except date fields use null — not the \"0000-00-00 00:00:00\" sentinel — to signal \"no scheduled end / next period\".","type":"object","properties":{"referenceId":{"type":"string","example":"CON170207-2840-94312S"},"active":{"type":"integer","example":1},"url":{"type":"string","nullable":true,"example":"https://sites.fastspring.com/speedify/order/s/CON170207-2847-37127S"},"seats":{"type":"integer","example":50},"nextPeriodDate":{"type":"string","format":"date-time","nullable":true,"description":"Date when the subscription will be renewed; null if none","example":"2026-04-01T00:00:00.000Z"},"endDate":{"type":"string","format":"date-time","nullable":true,"description":"Date the subscription will end; null if no scheduled end","example":null}}},"TeamInfo":{"type":"object","properties":{"teamId":{"type":"integer","example":56328},"dateGenerated":{"type":"string","format":"date-time","description":"Date the team was created","example":"2017-03-10T14:39:48.000Z"},"teamName":{"type":"string","example":"Test Team 001"},"masterUserid":{"type":"integer","description":"Userid of the main admin of the team","example":21474550},"subscription":{"$ref":"#/components/schemas/Subscription"}}},"TeamInfoV2":{"description":"v2 team info; subscription uses null-based date fields.","type":"object","properties":{"teamId":{"type":"integer","example":56328},"dateGenerated":{"type":"string","format":"date-time","description":"Date the team was created","example":"2017-03-10T14:39:48.000Z"},"teamName":{"type":"string","example":"Test Team 001"},"masterUserid":{"type":"integer","description":"Userid of the main admin of the team","example":21474550},"subscription":{"$ref":"#/components/schemas/SubscriptionV2"}}},"TeamSettings":{"type":"object","properties":{"entryId":{"type":"integer","example":111},"teamId":{"type":"integer","example":12345},"dateGenerated":{"type":"string","format":"date-time","example":"2020-04-01T14:59:12.000Z"},"dateUpdated":{"type":"string","format":"date-time","example":"2020-04-01T14:59:12.000Z"},"settings":{"type":"object","description":"Arbitrary settings object. Use the /schema endpoint to see valid keys and value types."}}},"MemberSpeedifyUsage":{"type":"object","properties":{"usageBytesThisPeriod":{"type":"integer","description":"Number of bytes the user has used while connected to Speedify this period","example":980740},"usageMinutesThisPeriod":{"type":"integer","description":"Minutes the user has been connected to Speedify this period","example":38},"availableBytesThisPeriod":{"type":"integer","description":"Bytes remaining this billing period","example":53687091200},"availableMinutesThisPeriod":{"type":"integer","description":"Minutes remaining this billing period","example":39600},"lastUsageReport":{"type":"string","format":"date-time","nullable":true,"description":"Last time the user was connected to a server and sent a usage report. Null if the user has never connected.","example":"2017-08-24T17:05:40.000Z"}}},"Member":{"type":"object","properties":{"userid":{"type":"integer","example":264650114},"email":{"type":"string","format":"email","example":"user@example.com"},"firstname":{"type":"string","example":"Test"},"lastname":{"type":"string","example":"User"},"role":{"type":"string","enum":["admin","user","guest"],"description":"Role in the team. admin: can add/remove members, manage API keys, and change seats. user: can access Speedify and dedicated servers. guest: same as user.","example":"user"},"dateAdded":{"type":"string","format":"date-time","description":"Date the user was added to the team","example":"2017-08-22T16:15:28.000Z"},"speedify":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/MemberSpeedifyUsage"}],"example":{"usageBytesThisPeriod":0,"usageMinutesThisPeriod":11,"availableBytesThisPeriod":-1,"availableMinutesThisPeriod":-1,"lastUsageReport":"2025-11-29T14:09:57.000Z"}}}},"MemberList":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of members in the team","example":2},"members":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}}},"AddMemberResponse":{"type":"object","properties":{"role":{"type":"string","enum":["admin","user","guest"],"example":"user"},"teamId":{"type":"string","example":"181615"},"userid":{"type":"integer","example":4469112514},"email":{"type":"string","format":"email","example":"newuser@example.com"}}},"SettingsUpdateResponse":{"type":"object","properties":{"message":{"type":"string","example":"Successfully updated team settings"},"settings":{"type":"object","description":"The settings that were applied"}}},"MemberSettingsUpdateResponse":{"type":"object","properties":{"message":{"type":"string","example":"Successfully updated team member settings"},"settings":{"type":"object","description":"The settings that were applied","example":{"encrypted":{"locked":false,"value":true},"transportMode":{"locked":false,"value":"tcp"}}}}},"MemberSettingsResponse":{"allOf":[{"$ref":"#/components/schemas/TeamSettings"},{"type":"object","properties":{"userid":{"type":"integer","description":"The user ID of the member these settings apply to","example":333}}}]},"SeatsResponse":{"type":"object","properties":{"quantity":{"type":"integer","description":"The new seat count","example":30}}},"Server":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the server","example":"us-nyc-1"},"city":{"type":"string","description":"City the server is located in","example":"us-nyc"},"country":{"type":"string","description":"Two-letter country code (prefixed with \"private\" for private servers)","example":"US"},"num":{"type":"string","description":"Numeric identifier for the server in that city","example":"1"},"dc":{"type":"string","description":"Datacenter the server is located in","example":"do-nyc"},"publicIP":{"type":"array","description":"Public IPv4 addresses of the server","items":{"type":"string"},"example":["203.0.113.1"]},"private":{"type":"string","enum":["yes","no"],"description":"Whether the server is reserved for team members only","example":"no"},"premiumOnly":{"type":"string","enum":["yes","no"],"example":"no"},"currentState":{"type":"string","description":"Current state of the server","example":"running"},"connectedUsers":{"type":"integer","description":"Number of users currently connected","example":42},"currentUsers":{"type":"integer","example":42},"longName":{"type":"string","description":"Human-readable name for the server","example":"New York City, NY"},"hostName":{"type":"string","example":"us-nyc-1.example.com"},"version":{"type":"string","description":"Server software version"},"torrent":{"type":"string","enum":["yes","no"],"description":"Whether the server supports torrenting"},"latitude":{"type":"string","example":"40.7128"},"longitude":{"type":"string","example":"-74.0060"},"expectedUpBw":{"type":"string","description":"Expected upload bandwidth"},"expectedDownBw":{"type":"string","description":"Expected download bandwidth"},"apiPort":{"type":"integer"},"date":{"type":"string"}}},"Device":{"type":"object","properties":{"deviceUUID":{"type":"string","description":"Unique identifier for the device","example":"2275583a-4587-4e5e-964f-fd4fae0508e2"},"userid":{"type":"integer","example":12345},"platform":{"type":"string","description":"Operating system / platform","example":"Android"},"friendlyName":{"type":"string","description":"User-friendly name for the device","example":"Google Pixel 6 Pro"},"lastActiveTime":{"type":"string","format":"date-time","description":"Last time the device was active","example":"2025-12-08T11:31:55.000Z"},"seenActivationSuccess":{"type":"boolean","description":"Whether the device has been successfully activated","example":false},"role":{"type":"string","description":"Device role","example":"client"},"vendor":{"type":"string","example":""},"routerReferenceId":{"type":"string","nullable":true,"deprecated":true,"description":"Deprecated: use referenceId instead"},"referenceId":{"type":"string","nullable":true}}},"ActivateDeviceResponse":{"type":"object","properties":{"deviceUUID":{"type":"string","description":"UUID of the activated device","example":"2275583a-4587-4e5e-964f-fd4fae0508e2"}}},"VersionInfo":{"type":"object","properties":{"name":{"type":"string","example":"speedify-teams-api"},"version":{"type":"string","example":"1.4.2"}}},"Error":{"type":"object","required":["message","type"],"properties":{"message":{"type":"string","description":"Human-readable error message"},"type":{"type":"string","description":"Machine-readable error type code"}}},"ValidationError":{"type":"object","required":["message","type"],"properties":{"message":{"type":"string","description":"Human-readable validation error message","example":"\"email\" is required"},"type":{"type":"string","example":"ERROR_VALIDATION"},"details":{"type":"array","description":"Joi validation error details","items":{"type":"object","properties":{"message":{"type":"string"},"path":{"type":"array","items":{"type":"string"}},"type":{"type":"string"}}}}}}},"responses":{"Unauthorized":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"invalid api key","type":"ERROR_UNAUTHORIZED"}}}},"Forbidden":{"description":"Valid API key but insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"You are not allowed to access this resource","type":"ERROR_FORBIDDEN"}}}},"ValidationError":{"description":"Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"ServerError":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"Something bad happened. Please try again","type":"ERROR_UNKNOWN"}}}}}},"security":[{"ApiKeyAuth":[]},{"BasicAuth":[]}],"paths":{"/v1/teams":{"get":{"tags":["Team"],"operationId":"getTeam","summary":"Get team info","description":"Get basic information about your team including details about the subscription that is tied to your Speedify for Teams account.","responses":{"200":{"description":"Team information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInfo"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/settings":{"get":{"tags":["Team Settings"],"operationId":"getTeamSettings","summary":"Get team settings","description":"Returns the settings configured for your team.","responses":{"200":{"description":"Team settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamSettings"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Team settings not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"Team settings do not exist","type":"ERROR_TEAM_SETTINGS_NOT_FOUND"}}}},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["Team Settings"],"operationId":"updateTeamSettings","summary":"Update team settings","description":"Create or update settings for the entire team.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["settings"],"properties":{"settings":{"type":"object","description":"Arbitrary settings object to apply to the team. Use the /schema endpoint to see valid keys and value types."}}},"example":{"settings":{"encrypted":{"locked":false,"value":true},"transportMode":{"locked":false,"value":"tcp"}}}}}},"responses":{"200":{"description":"Settings updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsUpdateResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Team Settings"],"operationId":"deleteTeamSettings","summary":"Delete team settings","description":"Removes all settings configured for the team.","responses":{"200":{"description":"Team settings deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/members/userid/{userid}/settings":{"get":{"tags":["Member Settings"],"operationId":"getMemberSettingsByUserId","summary":"Get member settings by user ID","description":"Returns the settings configured for a specific team member, looked up by their user ID.","parameters":[{"in":"path","name":"userid","required":true,"schema":{"type":"string"},"description":"The user ID of the team member"}],"responses":{"200":{"description":"Member settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberSettingsResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member settings not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"Team member settings do not exist","type":"ERROR_TEAM_MEMBER_SETTINGS_NOT_FOUND"}}}},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["Member Settings"],"operationId":"updateMemberSettingsByUserId","summary":"Update member settings by user ID","description":"Create or update settings for a specific team member, looked up by their user ID.","parameters":[{"in":"path","name":"userid","required":true,"schema":{"type":"string"},"description":"The user ID of the team member"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["settings"],"properties":{"settings":{"type":"object","description":"Arbitrary settings object to apply to the member"}}},"example":{"settings":{"encrypted":{"locked":false,"value":true},"transportMode":{"locked":false,"value":"tcp"}}}}}},"responses":{"200":{"description":"Member settings updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberSettingsUpdateResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Member Settings"],"operationId":"deleteMemberSettingsByUserId","summary":"Delete member settings by user ID","description":"Removes all settings configured for a specific team member, looked up by their user ID.","parameters":[{"in":"path","name":"userid","required":true,"schema":{"type":"integer"},"description":"The user ID of the team member"}],"responses":{"200":{"description":"Member settings deleted"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/members/email/{email}/settings":{"get":{"tags":["Member Settings"],"operationId":"getMemberSettingsByEmail","summary":"Get member settings by email","description":"Returns the settings configured for a specific team member, looked up by their email address.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"},"description":"The email address of the team member"}],"responses":{"200":{"description":"Member settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberSettingsResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member settings not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"Team member settings do not exist","type":"ERROR_TEAM_MEMBER_SETTINGS_NOT_FOUND"}}}},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["Member Settings"],"operationId":"updateMemberSettingsByEmail","summary":"Update member settings by email","description":"Create or update settings for a specific team member, looked up by their email address.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"},"description":"The email address of the team member"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["settings"],"properties":{"settings":{"type":"object","description":"Arbitrary settings object to apply to the member"}}},"example":{"settings":{"encrypted":{"locked":false,"value":true},"transportMode":{"locked":false,"value":"tcp"}}}}}},"responses":{"200":{"description":"Member settings updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberSettingsUpdateResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Member Settings"],"operationId":"deleteMemberSettingsByEmail","summary":"Delete member settings by email","description":"Removes all settings configured for a specific team member, looked up by their email address.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"},"description":"The email address of the team member"}],"responses":{"200":{"description":"Member settings deleted"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/members":{"get":{"tags":["Members"],"operationId":"listMembers","summary":"List team members","description":"Get information about the members of your team including Speedify usage stats for each user.","parameters":[{"in":"query","name":"sort","schema":{"type":"string","default":"added"},"description":"Field to sort by"},{"in":"query","name":"sortOrder","schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"description":"Sort direction"},{"in":"query","name":"page","schema":{"type":"string","default":"1"},"description":"Page number for pagination"}],"responses":{"200":{"description":"List of team members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Members"],"operationId":"addMember","summary":"Add a team member","description":"Sends an invitation to add a new member to the team. If you want to invite real people, omit the password field so they receive an invitation email. If you are creating accounts for machines, set a password and the account will be created directly.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"Email address of the new member"},"role":{"type":"string","enum":["admin","user","guest"],"default":"user","description":"Role to assign. admin: can manage members, API keys, and seats. user: can access Speedify and dedicated servers. guest: same as user."},"password":{"type":"string","description":"Optional password. If omitted, an invitation email is sent instead."}}},"example":{"email":"newuser@example.com","role":"user"}}}},"responses":{"200":{"description":"Member added (invitation sent)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddMemberResponse"}}}},"400":{"description":"Validation error or user already has a paid account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"validation":{"summary":"Validation error","value":{"message":"\"email\" is required","type":"ERROR_VALIDATION"}},"alreadyPaid":{"summary":"User already has a paid account","value":{"message":"This user already has a paid account. Please add this user as a guest or use a different email.","type":"ERROR_ALREADY_PAID_USER"}},"invalidRole":{"summary":"Invalid role","value":{"message":"This role does not exist. Please choose from 'admin', 'user', 'guest'.","type":"ERROR_NO_SUCH_ROLE"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"description":"No seats available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"You have no more seats left. You will have to add more seats or remove members before you can add new members.","type":"ERROR_NO_SEATS"}}}},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/members/email/{email}":{"delete":{"tags":["Members"],"operationId":"removeMember","summary":"Remove a team member","description":"Remove a member from the team. They will no longer have access to unlimited Speedify usage or be able to connect to your dedicated servers.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"},"description":"The email address of the member to remove"}],"responses":{"200":{"description":"Member removed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Successfully removed team member"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"This user is not a part of your team","type":"ERROR_NO_SUCH_TEAM_MEMBER"}}}},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/servers":{"get":{"tags":["Servers"],"operationId":"listServers","summary":"List available servers","description":"Returns the list of Speedify servers available to your team, including all public servers, any private servers assigned to your team, and self-hosted servers owned by team members.","responses":{"200":{"description":"List of servers","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Server"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/seats":{"put":{"tags":["Subscription"],"operationId":"updateSeats","summary":"Update seat count","description":"Change the number of seats available to your team. Note that this will result in a change in billing price. The quantity cannot be lower than the current number of members. If the requested quantity matches the current count, no change is made.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["quantity"],"properties":{"type":{"type":"string","description":"Set to \"headless\" for headless seat type"},"quantity":{"type":"integer","minimum":0,"description":"Desired number of seats"}}},"example":{"quantity":30}}}},"responses":{"200":{"description":"Seat count updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeatsResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"description":"Too many members for the requested seat count","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"You have more members than seats available. Please remove members or increase the seats.","type":"ERROR_TOO_MANY_MEMBERS"}}}},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/members/email/{email}/devices":{"get":{"tags":["Devices"],"operationId":"listMemberDevices","summary":"List member devices","description":"Get devices registered by a team member, looked up by their email address.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"},"description":"The email address of the team member"}],"responses":{"200":{"description":"List of devices","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Device"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"This user is not a part of your team","type":"ERROR_NO_SUCH_TEAM_MEMBER"}}}},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/members/email/{email}/activate-device":{"patch":{"tags":["Devices"],"operationId":"activateDevice","summary":"Activate a device","description":"Activate a device for a team member using an activation code.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"},"description":"The email address of the team member"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["activationCode"],"properties":{"activationCode":{"type":"string","description":"The activation code for the device"}}},"example":{"activationCode":"123456"}}}},"responses":{"200":{"description":"Device activated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateDeviceResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"This user is not a part of your team","type":"ERROR_NO_SUCH_TEAM_MEMBER"}}}},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/schema":{"get":{"tags":["Team Settings"],"operationId":"getSettingsSchema","summary":"Get settings schema","description":"Returns the JSON schema defining valid settings keys and value types for team and member settings.","responses":{"200":{"description":"Settings schema","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v1/teams/members/email/{email}/role":{"patch":{"tags":["Members"],"operationId":"changeMemberRole","summary":"Change member role","description":"Change a team member's role on your team. Valid roles are \"admin\", \"user\", and \"guest\".","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"},"description":"The email address of the team member"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["admin","user","guest"],"description":"The new role. admin: can manage members, API keys, and seats. user: can access Speedify and dedicated servers. guest: same as user."}}},"example":{"role":"admin"}}}},"responses":{"200":{"description":"Role updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["admin","user","guest"],"example":"admin"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"message":"This user is not a part of your team","type":"ERROR_NO_SUCH_TEAM_MEMBER"}}}},"500":{"$ref":"#/components/responses/ServerError"}}}},"/version":{"get":{"tags":["Health"],"operationId":"getVersion","summary":"Get API version","description":"Returns the name and version of the running API. No authentication required.","security":[],"responses":{"200":{"description":"Version information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInfo"}}}},"404":{"description":"Not found"}}}},"/v2/teams/api-keys":{"get":{"tags":["v2/API Keys"],"operationId":"v2ListAPIKeys","summary":"List API keys","description":"Returns all API keys for this team. Admin only. Feature flag: disabled by default. Enable with TEAMS_API_V2_LIST_API_KEYS=true.","responses":{"200":{"description":"List of API keys","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"keyId":101,"dateGenerated":"2026-03-23T22:18:19.000Z","teamId":3320,"userid":15264784,"apiKey":"03e0fd54...770cc093","description":"production","role":"admin","expirationDate":null,"invalidated":0,"allowedIPs":"0.0.0.0/0,::/0"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["v2/API Keys"],"operationId":"v2CreateAPIKey","summary":"Create API key","description":"Create a new API key for this team. Admin only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["description"],"properties":{"description":{"type":"string","maxLength":50},"role":{"type":"string","enum":["admin","user","guest"],"default":"admin"},"allowedIPs":{"type":"string","description":"Comma-separated IP addresses or CIDR ranges"}}}}}},"responses":{"200":{"description":"API key created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"teamId":3320,"userid":15264784,"apiKey":"6c619061...8c199187","description":"CI pipeline","role":"admin","expirationDate":null,"allowedIPs":"10.0.0.0/8"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/api-keys/{apiKey}/allowed-ips":{"put":{"tags":["v2/API Keys"],"operationId":"v2UpdateAPIKeyAllowedIPs","summary":"Update API key IP ACL","description":"Update the allowed IP addresses for an API key. Admin only.","parameters":[{"in":"path","name":"apiKey","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["allowedIPs"],"properties":{"allowedIPs":{"type":"string","description":"Comma-separated IP addresses or CIDR ranges"}}}}}},"responses":{"200":{"description":"IP ACL updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"updated"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/api-keys/{apiKey}":{"delete":{"tags":["v2/API Keys"],"operationId":"v2RevokeAPIKey","summary":"Revoke API key","description":"Revoke an API key for this team. Admin only.","parameters":[{"in":"path","name":"apiKey","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"API key revoked","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":[]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/devices":{"get":{"tags":["v2/Devices"],"operationId":"v2ListMemberDevices","summary":"List member devices","description":"Get devices registered by a team member. Self: any role. Other: admin or user.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"List of devices","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"deviceUUID":"141E5361-61D7-9693-5A13-A0C8BD8FFB57","userid":15264784,"platform":"Linux","friendlyName":"office-router","lastActiveTime":"2026-03-19T21:09:23.000Z","seenActivationSuccess":true,"role":"router","vendor":"speedify"},{"deviceUUID":"CC37E3E8-E9F2-D47C-CCDB-C7DF836A007C","userid":15264784,"platform":"ubuntu","friendlyName":null,"lastActiveTime":"2026-03-23T22:02:13.000Z","seenActivationSuccess":false,"role":"client","vendor":null}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/devices/link":{"post":{"tags":["v2/Devices"],"operationId":"v2LinkDevice","summary":"Link device via activation code","description":"Link a device to a team member using an activation code. Self: admin or user. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["activationCode"],"properties":{"activationCode":{"type":"string"}}}}}},"responses":{"200":{"description":"Device linked","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"deviceUUID":"A1B2C3D4-E5F6-7890-ABCD-EF1234567890","friendlyName":"New Device"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/devices/{deviceUUID}":{"patch":{"tags":["v2/Devices"],"operationId":"v2RenameDevice","summary":"Rename a device","description":"Update the friendly name of a device. Self: admin or user. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}},{"in":"path","name":"deviceUUID","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["friendlyName"],"properties":{"friendlyName":{"type":"string"}}}}}},"responses":{"200":{"description":"Device renamed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"deviceUUID":"141E5361-61D7-9693-5A13-A0C8BD8FFB57","friendlyName":"My Laptop"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["v2/Devices"],"operationId":"v2UnlinkDevice","summary":"Unlink a device","description":"Remove a device from a team member. Self: admin or user. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}},{"in":"path","name":"deviceUUID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Device unlinked","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"deleted"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/devices/{deviceUUID}/active":{"delete":{"tags":["v2/Devices"],"operationId":"v2ResetActiveDevice","summary":"Reset active device","description":"Reset the active session of a device. Self: admin or user. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}},{"in":"path","name":"deviceUUID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Active device reset","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"reset"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/invitations":{"get":{"tags":["v2/Invitations"],"operationId":"v2ListInvitations","summary":"List pending invitations","description":"Returns all pending team invitations. Admin only.","responses":{"200":{"description":"List of pending invitations","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"email":"invited@example.com","role":"user","teamId":3320}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/invitations/{email}":{"delete":{"tags":["v2/Invitations"],"operationId":"v2CancelInvitation","summary":"Cancel invitation","description":"Cancel a pending invitation for an email address. Admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"Invitation cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"rescinded"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/settings":{"get":{"tags":["v2/Member Settings"],"operationId":"v2GetMemberSettingsByEmail","summary":"Get member settings by email","description":"Returns settings for a team member by email. Self: any role. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"Member settings","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MemberSettingsResponse"}}},"example":{"data":{"entryId":11,"teamId":3320,"userid":15264785,"dateGenerated":"2026-03-23T22:37:23.000Z","dateUpdated":"2026-03-23T22:37:23.000Z","settings":{"encrypted":{"value":false,"locked":true}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member or settings not found"},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["v2/Member Settings"],"operationId":"v2UpdateMemberSettingsByEmail","summary":"Update member settings by email","description":"Create or update settings for a team member by email. Self: admin or user. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["settings"],"properties":{"settings":{"type":"object"}}}}}},"responses":{"200":{"description":"Settings updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"Successfully updated member settings"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["v2/Member Settings"],"operationId":"v2DeleteMemberSettingsByEmail","summary":"Delete member settings by email","description":"Removes all settings for a team member by email. Self: admin or user. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"Settings deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"message":{"type":"string"}}}}},"example":{"data":{"message":"Successfully deleted member settings"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/userid/{userid}/settings":{"get":{"tags":["v2/Member Settings"],"operationId":"v2GetMemberSettingsByUserId","summary":"Get member settings by user ID","description":"Returns settings for a team member by user ID. Self: any role. Other: admin only.","parameters":[{"in":"path","name":"userid","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Member settings","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MemberSettingsResponse"}}},"example":{"data":{"entryId":11,"teamId":3320,"userid":15264785,"dateGenerated":"2026-03-23T22:37:23.000Z","dateUpdated":"2026-03-23T22:37:23.000Z","settings":{"encrypted":{"value":false,"locked":true}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member or settings not found"},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["v2/Member Settings"],"operationId":"v2UpdateMemberSettingsByUserId","summary":"Update member settings by user ID","description":"Create or update settings for a team member by user ID. Self: admin or user. Other: admin only.","parameters":[{"in":"path","name":"userid","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["settings"],"properties":{"settings":{"type":"object"}}}}}},"responses":{"200":{"description":"Settings updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"Successfully updated member settings"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["v2/Member Settings"],"operationId":"v2DeleteMemberSettingsByUserId","summary":"Delete member settings by user ID","description":"Removes all settings for a team member by user ID. Self: admin or user. Other: admin only.","parameters":[{"in":"path","name":"userid","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Settings deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"message":{"type":"string"}}}}},"example":{"data":{"message":"Successfully deleted member settings"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members":{"get":{"tags":["v2/Members"],"operationId":"v2ListMembers","summary":"List team members","description":"Get paginated list of team members with usage stats. Requires admin or user role.","parameters":[{"in":"query","name":"sort","schema":{"type":"string","default":"added"},"description":"Field to sort by"},{"in":"query","name":"sortOrder","schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"description":"Sort direction"},{"in":"query","name":"page","schema":{"type":"string","default":"1"},"description":"Page number"},{"in":"query","name":"pageSize","schema":{"type":"string","default":"25"},"description":"Number of results per page"}],"responses":{"200":{"description":"Paginated list of team members","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"}}}}},"example":{"data":[{"userid":15264786,"email":"guest@example.com","firstname":null,"lastname":null,"role":"guest","dateAdded":"2026-03-19T20:48:35.000Z","speedify":{"usageBytesThisPeriod":0,"usageMinutesThisPeriod":0,"availableBytesThisPeriod":null,"availableMinutesThisPeriod":-1,"lastUsageReport":null}},{"userid":15264784,"email":"admin@example.com","firstname":null,"lastname":null,"role":"admin","dateAdded":"2026-03-19T20:48:33.000Z","speedify":{"usageBytesThisPeriod":257133,"usageMinutesThisPeriod":27,"availableBytesThisPeriod":-1,"availableMinutesThisPeriod":-1,"lastUsageReport":"2026-03-23T22:29:56.000Z"}}],"pagination":{"total":3,"page":1,"pageSize":25}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["v2/Members"],"operationId":"v2AddMember","summary":"Add a team member","description":"Sends an invitation to add a new member. Omit password for email invite; include password for direct account creation. Admin only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["admin","user","guest"],"default":"user"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Member added / invitation sent","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"teamId":3320,"userid":15264792}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"description":"No seats available"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}":{"delete":{"tags":["v2/Members"],"operationId":"v2RemoveMember","summary":"Remove a team member","description":"Remove a member from the team. Admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"Member removed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":[]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/role":{"patch":{"tags":["v2/Members"],"operationId":"v2ChangeMemberRole","summary":"Change member role","description":"Change a team member's role. Admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["admin","user","guest"]}}}}}},"responses":{"200":{"description":"Role updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"role":"admin"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/password":{"patch":{"tags":["v2/Members"],"operationId":"v2ChangeMemberPassword","summary":"Change member password","description":"Rotate a team member's password. Intended for systematic password rotation by integrations that still authenticate users with username/password. Admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string","minLength":8,"description":"The new password"}}}}}},"responses":{"200":{"description":"Password updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"userid":15264785}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/router-pool":{"get":{"tags":["v2/Router Pool"],"operationId":"v2ListRouterPool","summary":"List router pool","description":"Returns the router pool for this team. Admin only.","responses":{"200":{"description":"Router pool","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":{"totalLicenses":25,"usedLicenses":2,"licenseDetails":[{"referenceId":"Tz4nW8cYjK6bD3hS","productName":"speedify.pro.router.monthly.3000gb.subscription","quantity":5,"ownerUserid":15264784,"ownerEmail":"admin@example.com"}],"routers":[{"deviceUUID":"141E5361-61D7-9693-5A13-A0C8BD8FFB57","userid":15264784,"activatedByEmail":"admin@example.com","friendlyName":"office-router","vendor":"speedify","routerReferenceId":"Tz4nW8cYjK6bD3hS","lastActiveTime":"2026-03-19T21:09:23.000Z","platform":"Linux"}]}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/router-pool/reassign":{"patch":{"tags":["v2/Router Pool"],"operationId":"v2ReassignRouter","summary":"Reassign router","description":"Reassign a router to a different subscription. Admin only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["deviceUUID","referenceId"],"properties":{"deviceUUID":{"type":"string"},"referenceId":{"type":"string"}}}}}},"responses":{"200":{"description":"Router reassigned","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"reassigned"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/router-pool/unlink":{"patch":{"tags":["v2/Router Pool"],"operationId":"v2UnlinkRouter","summary":"Unlink router","description":"Unlink a router from the team pool. Admin only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["deviceUUID"],"properties":{"deviceUUID":{"type":"string"}}}}}},"responses":{"200":{"description":"Router unlinked","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"unlinked"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/servers":{"get":{"tags":["v2/Servers"],"operationId":"v2ListServers","summary":"List available servers","description":"Returns Speedify servers available to your team, including public servers, assigned private servers, and self-hosted servers owned by team members. All roles can access this endpoint.","responses":{"200":{"description":"List of servers","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"id":"abc5e35ac08b...","pVersion":"4","currentState":"ONLINE","publicIP":["10.0.2.2"],"longName":"Speedify Speed Server","country":"us","city":"town","num":"1","private":"no","connectedUsers":1}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/servers/deployment-options":{"get":{"tags":["v2/Servers"],"operationId":"v2GetDeploymentOptions","summary":"Get deployment options","description":"Returns available server deployment options for provisioning. Admin only.","responses":{"200":{"description":"Deployment options","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"id":1,"provider":"aws","country":"us","city":"nyc"},{"id":2,"provider":"aws","country":"de","city":"fra"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/servers/provisioning":{"post":{"tags":["v2/Servers"],"operationId":"v2RequestProvisioning","summary":"Request server provisioning","description":"Request a new dedicated server to be provisioned. Admin only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["deploymentOptionId"],"properties":{"deploymentOptionId":{"type":"integer"}}}}}},"responses":{"200":{"description":"Provisioning requested","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"id":42,"status":"pending"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/servers/provisioning/{id}":{"delete":{"tags":["v2/Servers"],"operationId":"v2CancelProvisioning","summary":"Cancel server provisioning","description":"Cancel a pending server provisioning request. Admin only.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Provisioning cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"cancelled"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/servers/provisioning/{id}/log":{"get":{"tags":["v2/Servers"],"operationId":"v2GetProvisioningLog","summary":"Get provisioning activity log","description":"Get the activity log for a provisioning request. Admin only.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Provisioning activity log","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[["2026-06-01","Provisioning started"],["2026-06-02","Server ready"]]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/stats/tunnel":{"get":{"tags":["v2/Stats"],"operationId":"v2TeamTunnelStats","summary":"Team tunnel stats","description":"Get tunnel statistics for the entire team. Admin only.","parameters":[{"in":"query","name":"from","required":true,"schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","required":true,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Tunnel stats","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"columns":[{"name":"datetime","type":"keyword"},{"name":"traffic","type":"long"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"},{"name":"server","type":"keyword"}],"values":[["2026-03-20T12:00:00Z",1048576,"CC37E3E8-...","admin@example.com","us-town-1"]]},{"columns":[{"name":"datetime","type":"keyword"},{"name":"type","type":"keyword"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"}],"values":[["2026-03-20T11:59:00Z","client-connects","CC37E3E8-...","admin@example.com"]]}]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/stats/network":{"get":{"tags":["v2/Stats"],"operationId":"v2TeamNetworkStats","summary":"Team network stats","description":"Get network statistics for the entire team. Admin only.","parameters":[{"in":"query","name":"from","required":true,"schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","required":true,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Network stats","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"columns":[{"name":"datetime","type":"keyword"},{"name":"traffic","type":"long"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"},{"name":"server","type":"keyword"}],"values":[["2026-03-20T12:00:00Z",1048576,"CC37E3E8-...","admin@example.com","us-town-1"]]},{"columns":[{"name":"datetime","type":"keyword"},{"name":"type","type":"keyword"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"}],"values":[["2026-03-20T11:59:00Z","client-connects","CC37E3E8-...","admin@example.com"]]}]}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/stats/tunnel":{"get":{"tags":["v2/Stats"],"operationId":"v2MemberTunnelStats","summary":"Member tunnel stats","description":"Get tunnel statistics for a specific member. Self: any role. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}},{"in":"query","name":"from","required":true,"schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","required":true,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Tunnel stats","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"columns":[{"name":"datetime","type":"keyword"},{"name":"traffic","type":"long"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"},{"name":"server","type":"keyword"}],"values":[["2026-03-20T12:00:00Z",1048576,"CC37E3E8-...","admin@example.com","us-town-1"]]},{"columns":[{"name":"datetime","type":"keyword"},{"name":"type","type":"keyword"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"}],"values":[["2026-03-20T11:59:00Z","client-connects","CC37E3E8-...","admin@example.com"]]}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/stats/network":{"get":{"tags":["v2/Stats"],"operationId":"v2MemberNetworkStats","summary":"Member network stats","description":"Get network statistics for a specific member. Self: any role. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}},{"in":"query","name":"from","required":true,"schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","required":true,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Network stats","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"columns":[{"name":"datetime","type":"keyword"},{"name":"traffic","type":"long"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"},{"name":"server","type":"keyword"}],"values":[["2026-03-20T12:00:00Z",1048576,"CC37E3E8-...","admin@example.com","us-town-1"]]},{"columns":[{"name":"datetime","type":"keyword"},{"name":"type","type":"keyword"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"}],"values":[["2026-03-20T11:59:00Z","client-connects","CC37E3E8-...","admin@example.com"]]}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/devices/{uuid}/stats/tunnel":{"get":{"tags":["v2/Stats"],"operationId":"v2DeviceTunnelStats","summary":"Device tunnel stats","description":"Get tunnel statistics for a specific device. Self: any role. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}},{"in":"path","name":"uuid","required":true,"schema":{"type":"string"}},{"in":"query","name":"from","required":true,"schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","required":true,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Device tunnel stats","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"columns":[{"name":"datetime","type":"keyword"},{"name":"traffic","type":"long"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"},{"name":"server","type":"keyword"}],"values":[["2026-03-20T12:00:00Z",1048576,"CC37E3E8-...","admin@example.com","us-town-1"]]},{"columns":[{"name":"datetime","type":"keyword"},{"name":"type","type":"keyword"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"}],"values":[["2026-03-20T11:59:00Z","client-connects","CC37E3E8-...","admin@example.com"]]}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/members/{email}/devices/{uuid}/stats/network":{"get":{"tags":["v2/Stats"],"operationId":"v2DeviceNetworkStats","summary":"Device network stats","description":"Get network statistics for a specific device. Self: any role. Other: admin only.","parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"}},{"in":"path","name":"uuid","required":true,"schema":{"type":"string"}},{"in":"query","name":"from","required":true,"schema":{"type":"string","format":"date-time"}},{"in":"query","name":"to","required":true,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Device network stats","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"columns":[{"name":"datetime","type":"keyword"},{"name":"traffic","type":"long"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"},{"name":"server","type":"keyword"}],"values":[["2026-03-20T12:00:00Z",1048576,"CC37E3E8-...","admin@example.com","us-town-1"]]},{"columns":[{"name":"datetime","type":"keyword"},{"name":"type","type":"keyword"},{"name":"device","type":"keyword"},{"name":"user","type":"keyword"}],"values":[["2026-03-20T11:59:00Z","client-connects","CC37E3E8-...","admin@example.com"]]}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Member not found"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/subscriptions":{"get":{"tags":["v2/Subscriptions"],"operationId":"v2ListSubscriptions","summary":"List subscriptions","description":"Returns the subscription(s) associated with this team. Admin only.","responses":{"200":{"description":"Team subscriptions","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}},"example":{"data":[{"referenceId":"8f3kQ7xmNp2wR9vL","active":1,"productName":"speedify.teams.monthly.unlimited","quantity":20,"nextPeriodDate":"2025-09-30T00:00:00.000Z","endDate":null,"recurring":1,"storeType":"INT","cancelable":1,"customerUrl":null}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/subscriptions/{referenceId}":{"delete":{"tags":["v2/Subscriptions"],"operationId":"v2CancelSubscription","summary":"Cancel subscription","description":"Cancel a subscription at end of term. Admin only.","parameters":[{"in":"path","name":"referenceId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Subscription cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"cancelled"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/subscriptions/{referenceId}/uncancel":{"put":{"tags":["v2/Subscriptions"],"operationId":"v2UncancelSubscription","summary":"Restore subscription","description":"Restore a previously cancelled subscription. Admin only.","parameters":[{"in":"path","name":"referenceId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Subscription restored","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"restored"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/seats":{"put":{"tags":["v2/Subscriptions"],"operationId":"v2UpdateSeats","summary":"Update seat count","description":"Change the number of seats. This changes billing. Quantity cannot be lower than current member count. Admin only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["quantity"],"properties":{"type":{"type":"string","description":"Set to \"headless\" for headless seat type"},"quantity":{"type":"integer","minimum":0}}}}}},"responses":{"200":{"description":"Seats updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"quantity":{"type":"integer"}}}}},"example":{"data":{"quantity":20}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"description":"Too many members for the requested seat count"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams":{"get":{"tags":["v2/Team"],"operationId":"v2GetTeam","summary":"Get team info","description":"Get basic information about your team including details about the subscription. All roles can access this endpoint.","responses":{"200":{"description":"Team information","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TeamInfoV2"}}},"example":{"data":{"teamId":3320,"dateGenerated":"2026-03-19T20:48:32.000Z","teamName":"Acme Corp","masterUserid":15264784,"subscription":{"referenceId":"8f3kQ7xmNp2wR9vL","active":1,"url":null,"seats":20,"nextPeriodDate":"2025-09-30T00:00:00.000Z","endDate":null}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"patch":{"tags":["v2/Team"],"operationId":"v2RenameTeam","summary":"Rename team","description":"Update the team name. Admin only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["teamName"],"properties":{"teamName":{"type":"string","description":"New team name"}}},"example":{"teamName":"My Team"}}}},"responses":{"200":{"description":"Team renamed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"teamName":"Acme Corp"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/settings":{"get":{"tags":["v2/Team Settings"],"operationId":"v2GetTeamSettings","summary":"Get team settings","description":"Returns the settings configured for your team. Admin only.","responses":{"200":{"description":"Team settings","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TeamSettings"}}},"example":{"data":{"entryId":21,"teamId":3320,"dateGenerated":"2026-03-23T22:29:42.000Z","dateUpdated":"2026-03-23T22:29:42.000Z","settings":{"encrypted":{"value":true,"locked":false},"transportMode":{"value":"auto","locked":true}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Team settings not found"},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["v2/Team Settings"],"operationId":"v2UpdateTeamSettings","summary":"Update team settings","description":"Create or update settings for the entire team. Admin only.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["settings"],"properties":{"settings":{"type":"object","description":"Settings object to apply to the team."}}}}}},"responses":{"200":{"description":"Settings updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}},"example":{"data":{"message":"Successfully updated team settings"}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["v2/Team Settings"],"operationId":"v2DeleteTeamSettings","summary":"Delete team settings","description":"Removes all settings configured for the team. Admin only.","responses":{"200":{"description":"Team settings deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"message":{"type":"string"}}}}},"example":{"data":{"message":"Successfully deleted team settings"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/v2/teams/settings/schema":{"get":{"tags":["v2/Team Settings"],"operationId":"v2GetSettingsSchema","summary":"Get settings schema","description":"Returns the JSON schema defining valid settings keys and value types. All roles can access this endpoint.","responses":{"200":{"description":"Settings schema","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/ping":{"get":{"tags":["Health"],"operationId":"ping","summary":"Health check","description":"Returns \"pong\" if the API is running. No authentication required.","security":[],"responses":{"200":{"description":"API is healthy","content":{"text/plain":{"schema":{"type":"string","example":"pong"}}}},"404":{"description":"Not found"}}}},"/openapi.json":{"get":{"tags":["Documentation"],"operationId":"getOpenApiSpec","summary":"OpenAPI specification","description":"Returns the OpenAPI 3.0.3 JSON specification for this API.","security":[],"responses":{"200":{"description":"OpenAPI specification","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/docs":{"get":{"tags":["Documentation"],"operationId":"getDocs","summary":"Interactive API documentation","description":"Serves a Scalar-powered interactive API reference UI.","security":[],"responses":{"200":{"description":"HTML page with interactive API documentation","content":{"text/html":{"schema":{"type":"string"}}}}}}}},"tags":[]}