Account
All path parameters are required. User IDs accept @me or a numeric string of up to 19 digits.
These endpoints handle the full account lifecycle: creating and authenticating accounts, verifying email addresses, recovering passwords, managing profile and security settings, and setting up two-factor authentication.
The lifecycle endpoints (/v1/login, /v1/register, /v1/reset-password, /v1/verify-email, /v1/lock-account) do not require a bearer token. They are open to any caller but carry tighter rate limits than the rest of the API.
Authentication + lifecycle
Log in
/v1/loginAuthenticate and mint a SESSION tokenValidates the email and password (and a TOTP code if 2FA is enabled), sends a login notification email, and returns a SESSION-origin token with the full set of USER-scope capabilities. The plaintext code is only returned once. Save it securely.
No authentication required.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | yes | Account email address |
password | string | yes | Account password |
mfa | string or null | TOTP code (required when 2FA is enabled on the account. Pass the emergency reset token here to disable 2FA) |
curl -X POST https://api.galaxygate.net/v1/login \
-A 'curl/8.5' \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "password": "hunter2", "mfa": "123456" }'Returns 200 OK with a token creation response. The code field is the bearer token to use in subsequent requests. It is the only time the plaintext is exposed.
Register
/v1/registerCreate a new accountCreates a new user account and starts the onboarding workflow (email verification email, default workspace, optional coupon redemption). If a user with the same email already exists, the server sends a password-reset email to that address and returns 201 without revealing that the account exists.
No authentication required.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name (3-32 characters) |
email | string | yes | Email address |
password | string | yes | Password (minimum 8 characters) |
coupon | string or null | Promotional coupon code | |
invite_code | string or null | Workspace invite code. Accepting an invite addressed to this email also verifies it |
Returns 200 OK with a session token when an invite addressed to the same email verifies the account. Otherwise returns 201 Created with an empty body. Without verification, sign-in is refused until the confirmation link is followed.
Request or confirm a password reset
/v1/reset-passwordRequest or confirm a password resetThis endpoint handles both steps of the reset flow in a single path. Send code to confirm, or email to request a link. When code is present, we ignore email.
No authentication required.
Request body (step 1 - request a reset link)
| Field | Type | Required | Description |
|---|---|---|---|
email | string | yes (this step) | Email address to send the reset link to |
Request body (step 2 - set the new password)
| Field | Type | Required | Description |
|---|---|---|---|
code | string | yes (this step) | Token from the reset link |
password | string | yes (this step) | New password (minimum 8 characters) |
Returns 202 Accepted with an empty body for both steps.
Request or confirm email verification
/v1/verify-emailRequest or confirm email verificationHandles both steps of the email verification flow. Send code to confirm, or email to request a link. When code is present, we ignore email.
No authentication required.
Request body (step 1 - resend the verification email)
| Field | Type | Required | Description |
|---|---|---|---|
email | string | yes (this step) | Account email address |
Request body (step 2 - confirm the code)
| Field | Type | Required | Description |
|---|---|---|---|
code | string | yes (this step) | Token from the verification email |
Returns 202 Accepted with an empty body.
Lock an account
/v1/lock-accountLock an account using its lock codeStarts the workflow that locks the account identified by its lock code. Lock codes are included in login-notification emails as a one-click security action. A locked account cannot log in. Idempotent: locking an already-locked account returns 202 without error.
No authentication required.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
code | string | yes | Account lock code (from the login notification email) |
Returns 202 Accepted with an empty body.
Profile + security
Fetch a user profile
/v1/users/{uid}Fetch user profilePath parameters
| Name | Type | Description |
|---|---|---|
uid | string | User ID, or @me for the authenticated user |
curl https://api.galaxygate.net/v1/users/@me \
-A 'curl/8.5' \
-H "Authorization: Bearer $GALAXYGATE_TOKEN"Returns 200 OK with the user object: id, name, email, flags, and nullable whmcs_id.
Update a user profile
/v1/users/{uid}Update account profileUpdates the user's display name or email address. All fields are optional. Send only what you are changing. An email change triggers a confirmation link to the new address before it takes effect.
Path parameters
| Name | Type | Description |
|---|---|---|
uid | string | User ID, or @me |
Request body
| Field | Type | Description |
|---|---|---|
name | string | Display name (3-32 characters) |
email | string | New email address. A confirmation link is sent before the change is applied |
Returns 200 OK with the updated user object in the same shape as the fetch response.
Delete an account
/v1/users/{uid}Permanently deactivate an accountStarts the workflow that permanently deactivates the account and revokes all active sessions. The account must not own any workspaces. Transfer or delete them first.
Path parameters
| Name | Type | Description |
|---|---|---|
uid | string | User ID, or @me |
Returns 202 Accepted with an empty body.
Change password
/v1/users/{uid}/passwordChange account passwordUpdates the account password. Invalidates all active sessions, including the one used to make this call.
Path parameters
| Name | Type | Description |
|---|---|---|
uid | string | User ID, or @me |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
old_password | string | yes | Current password (minimum 8 characters) |
password | string | yes | New password (minimum 8 characters) |
Returns 202 Accepted with an empty body.
Begin 2FA setup
/v1/users/{uid}/totpBegin two-factor authentication setupGenerates a TOTP secret and returns the provisioning URI, the raw secret, and an emergency reset token. Call PUT /v1/users/{uid}/totp with a valid code to confirm and activate 2FA.
Path parameters
| Name | Type | Description |
|---|---|---|
uid | string | User ID, or @me |
Returns 200 OK
| Field | Type | Description |
|---|---|---|
uri | string | otpauth:// URI ready to scan with an authenticator app |
code | string | Raw TOTP secret |
reset | string | Emergency reset token. Store it somewhere safe. Pass it as mfa at login to disable 2FA. |
Finalize 2FA setup
/v1/users/{uid}/totpConfirm and activate two-factor authenticationConfirms a TOTP code generated by the authenticator app and activates 2FA. All active sessions are invalidated.
Path parameters
| Name | Type | Description |
|---|---|---|
uid | string | User ID, or @me |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
code | string | yes | Current TOTP code from the authenticator app |
Returns 202 Accepted with an empty body.
Disable 2FA
/v1/users/{uid}/totpDisable two-factor authenticationRemoves the TOTP secret and disables 2FA on the account. Requires the current TOTP code passed in the X-MFA header.
Path parameters
| Name | Type | Description |
|---|---|---|
uid | string | User ID, or @me |
Headers
| Name | Required | Description |
|---|---|---|
X-MFA | yes | Current TOTP code |
Returns 202 Accepted with an empty body.
List invites addressed to a user
See Search user invites for GET /v1/users/{uid}/invites, its filters, and response.
External provider sign-in
Begin external provider sign-in
/v1/auth/startBegin external provider sign-inWe return a provider URL and a single-use state. Redirect the browser to url, then submit the returned code and matching state to the callback. The coupon applies only to new accounts. An unconfigured provider returns 404.
No authentication required.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | yes | Provider to sign in with. Values: google, github. |
redirect_uri | string | Which of the configured redirect URIs the provider should return to. Defaults to the first configured URI. | |
coupon | string | Coupon code to redeem if this sign-in creates a new account. |
Returns 200 OK with the following fields.
| Field | Type | Description |
|---|---|---|
state | string | Opaque single-use value echoed back by the provider. Pass it to the callback exactly as received, and reject a callback whose state does not match this value. |
url | string | Provider URL to redirect the browser to |
Complete external provider sign-in
/v1/auth/callbackComplete external provider sign-inWe exchange the provider code for a session token. On first use, a verified provider email matches an existing account or creates one. Later sign-ins use the linked provider identity. If two-factor authentication returns 403 with code: "missing_mfa", retry with the same state and mfa, omitting the already-spent code.
No authentication required.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
code | string or null | Authorization code from the provider redirect. Required on the first call, and omitted when retrying with a 2FA code. | |
mfa | string or null | 2FA code, when the account has 2FA enabled | |
provider | string | yes | Provider that issued the code. Values: google, github. |
state | string | yes | The state value issued when the flow started |
{"provider": "github", "state": "<state>", "code": "<code>"}Returns 200 OK with a token creation response.
Linked external accounts
List linked external accounts
/v1/users/{uid}/identitiesList linked external accountsWe list provider accounts that can sign in to this account. This response is an array without pagination.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
uid | string | yes | User ID, or @me for the current user |
Returns 200 OK with an array of linked identity objects.
| Field | Type | Description |
|---|---|---|
created | string (ISO 8601) | When this identity was linked |
email | string or null | Email address reported by the provider |
id | string | Identity ID |
last_used | string (ISO 8601) or null | When this identity was last used to log in |
provider | string | External identity provider. Values: google, github. |
Begin linking an external account
/v1/users/{uid}/identities/startBegin linking an external accountRequires a login session and two-factor authentication when enabled. We bind the request to this account and return a provider URL and state. The provider email may differ from the account email.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
uid | string | yes | User ID, or @me for the current user |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | yes | Provider to link. Values: google, github. |
redirect_uri | string or null | Which of the configured redirect URIs the provider should return to. Defaults to the first configured URI. |
{"provider": "github"}Returns 200 OK with the following fields.
| Field | Type | Description |
|---|---|---|
state | string | Opaque single-use value echoed back by the provider. Pass it to the callback exactly as received, and reject a callback whose state does not match this value. |
url | string | Provider URL to redirect the browser to |
Complete linking an external account
/v1/users/{uid}/identitiesComplete linking an external accountSubmit the provider code and state from the linking flow. We reject provider accounts already linked elsewhere and duplicate providers on the same account.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
uid | string | yes | User ID, or @me for the current user |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
code | string | yes | Authorization code from the provider redirect |
provider | string | yes | Provider that issued the code. Values: google, github. |
state | string | yes | The state value issued when the link flow started |
{"provider": "github", "state": "<state>", "code": "<code>"}Returns 201 Created with the following fields.
| Field | Type | Description |
|---|---|---|
created | string (ISO 8601) | When this identity was linked |
email | string or null | Email address reported by the provider |
id | string | Identity ID |
last_used | string (ISO 8601) or null | When this identity was last used to log in |
provider | string | External identity provider. Values: google, github. |
Unlink an external account
/v1/users/{uid}/identities/{iid}Unlink an external accountWe remove the linked provider account. An account without a password can set one through password recovery.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
uid | string | yes | User ID, or @me for the current user |
iid | string | yes | Linked identity ID |
Returns 202 Accepted with an empty body.
Submit feedback
/v1/feedbackSubmit feedbackWe record the authenticated account alongside its platform feedback. The JSON body is required.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
message | string | yes | Feedback message Length: 10 to 2000. |
{"message": "Please add a tag filter to the instance list."}Returns 204 No Content with an empty body.