Admin
Administrative endpoints for managing users and their role assignments. All endpoints require the caller to hold the users_admin role.
Table of Content:
- Create user
- Delete user
- List users
- Get user details
- Disable user
- Enable user
- Verify user (admin)
- Unverify user (admin)
- Assign role to user
- Unassign role from user
- List user’s roles
- List active sessions
- Create session for user
- Verify session (admin)
- Close session (admin)
- List keypairs
- Create keypair for user
- Verify keypair (admin)
- Delete keypair (admin)
- Create email for user
- Verify email (admin)
- Set preferred email (admin)
- Delete email (admin)
- Get user verification
- Reset user verification
- Revoke user verification
Create user
Create a new user account on behalf of someone else. Two modes:
- Default (
notifyomitted orfalse) — the admin receives a fresh API key pair in the response, intended for programmatic setup. No email is sent. - Invite mode (
notify: true) — the server emails the recipient a welcome message with a link to the portal where they can sign in with email + OTP. The response omits the API key pair fields, since no programmatic credential is created in this path.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| body | string | Yes | Email address for the new user. | “john@doe.net” | |
| fullName | body | string | Yes | The user’s full name. | “John Doe” |
| alias | body | string | Yes | Unique alias / username. | “johny” |
| roles | body | string[] | No | Roles to grant on create. Allowed: "user", "reporter", "trusted". Defaults to config DefaultRoles (typically "user"). | ["user"] |
| notify | body | bool | No | When true, send an invite email instead of returning an API key pair. | false |
| portalURL | body | string | No | Required when notify is true. Absolute HTTP(S) URL for the invite link. | "https://app.threatwinds.com" |
Headers
| Header | Required | Description |
|---|---|---|
| Authorization | Yes | Bearer token. |
| api-key | No | API key (alternative). |
| api-secret | No | API secret. |
To create a user with an API key pair:
curl -X 'POST' \
'https://apis.threatwinds.com/api/auth/v2/admin/user' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"email": "john@doe.net",
"fullName": "John Doe",
"alias": "johny",
"roles": ["user"]
}'
To invite a user via email:
curl -X 'POST' \
'https://apis.threatwinds.com/api/auth/v2/admin/user' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"email": "john@doe.net",
"fullName": "John Doe",
"alias": "johny",
"roles": ["user"],
"notify": true,
"portalURL": "https://app.threatwinds.com/signin"
}'
Returns
Default mode (keypair response):
{
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"email": "john@doe.net",
"apiKey": "fq6JoEFTsxiXAl1cVxPDnK4emIQCwaUB",
"apiSecret": "fq6JoEFTsxiXAl1cVxPDnK4emIQCwaUBfq6JoEFTsxiXAl1cVxPDnK4emIQCwaUB",
"keyID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"keyName": "johny",
"expireAt": 1674492894,
"verified": true
}
Invite mode (notify: true):
{
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"email": "john@doe.net"
}
Note: In invite mode, the response omits
apiKey,apiSecret,keyID,keyName,expireAt, andverifiedbecause these are all pointer fields withomitemptyand are not set when no keypair is created.
Delete user
Delete a user account by ID.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The ID of the user to delete. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
Headers as above.
curl -X 'DELETE' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with an acknowledgement body:
{
"message": "acknowledged"
}
Error Codes
| Code | Description |
|---|---|
| 400 | Invalid user ID format |
| 404 | User not found |
| 500 | Database error |
Deletion cascade
Admin-initiated user deletion uses the same cascade as user self-delete. See Account Deletion Cascade.
List users
List all users in the system with optional pagination and filters. Results are ordered by creation date (newest first).
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/users
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| page | query | int | No | Page number (default 1). | 1 |
| limit | query | int | No | Items per page (default 10, max 100). | 10 |
| enabled | query | bool | No | Filter by enabled status. Omit to return both enabled and disabled users. | true |
| role | query | string | No | Filter by role name (e.g. user, reporter, trusted, users_admin, partner). | trusted |
curl -X 'GET' \
'https://apis.threatwinds.com/api/auth/v2/admin/users?page=1&limit=10&enabled=true' \
-H 'Authorization: Bearer <token>'
Returns
{
"users": [
{
"id": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"fullName": "John Doe",
"alias": "johny",
"enabled": true,
"verified": true,
"createdAt": "2026-01-15T10:23:41Z",
"roles": ["user", "trusted"],
"country": "US",
"dateOfBirth": "1990-01-15T00:00:00Z",
"addressLine1": "123 Main St",
"addressLine2": "",
"city": "New York",
"state": "NY",
"postalCode": "10001",
"nationality": "USA"
}
],
"items": 1,
"pages": 1
}
Note: The
dateOfBirthfield is omitted when not set.
Get user details
Get full administrative detail for a single user: profile, roles, emails, active session count, last session time, and API keypairs. Sensitive fields (password hash, plaintext secrets) are never returned.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'GET' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e' \
-H 'Authorization: Bearer <token>'
Returns
{
"id": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"fullName": "John Doe",
"alias": "johny",
"enabled": true,
"verified": true,
"createdAt": "2026-01-15T10:23:41Z",
"expireAt": "2027-01-15T10:23:41Z",
"roles": ["user", "trusted"],
"country": "US",
"dateOfBirth": "1990-01-15T00:00:00Z",
"addressLine1": "123 Main St",
"addressLine2": "",
"city": "New York",
"state": "NY",
"postalCode": "10001",
"nationality": "USA",
"emails": [
{
"id": "a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e",
"address": "john@doe.net",
"status": 2
}
],
"activeSessions": 2,
"lastSessionAt": "2026-04-19T17:42:11Z",
"keypairs": [
{
"id": "c1d2e3f4-5633-4b16-bbf0-5ca22ef8ea2e",
"name": "johny",
"createdAt": "2026-01-15T10:23:41Z",
"expireAt": "2027-01-15T10:23:41Z",
"verified": true
}
]
}
Note:
lastSessionAtis nullable — it will benullwhen the user has never had a session. All other timestamp fields are always present.Email status enum:
1= PENDING,2= VERIFIED,3= PREFERRED.
404 if no user with the given ID exists.
Disable user
Disable a user account. Sets enabled=false and terminates existing sessions. The user record is preserved — use Delete user to remove it entirely.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/disable
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/disable' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with an acknowledgement body:
{
"message": "acknowledged"
}
404 if the user doesn’t exist; 409 if the user is already disabled.
Enable user
Re-enable a previously disabled user account. Sets enabled=true. Does not restore terminated sessions — the user must sign in again.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/enable
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/enable' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with an acknowledgement body:
{
"message": "acknowledged"
}
404 if the user doesn’t exist; 409 if the user is already enabled.
Verify user (admin)
Mark a user’s identity as verified through an out-of-band channel (e.g. manual document review). Sets User.Verified=true.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/verify
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/verify' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with an acknowledgement body:
{
"message": "acknowledged"
}
404 if the user doesn’t exist; 409 if the user is already verified.
Unverify user (admin)
Clear the identity-verified flag on a user. Use to revoke a verification that was issued in error. Sets User.Verified=false.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/unverify
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/unverify' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with an acknowledgement body:
{
"message": "acknowledged"
}
404 if the user doesn’t exist; 409 if the user is already unverified.
Assign role to user
Grant an app-level role to an existing user. Assignable role names: user, reporter, trusted, users_admin, billing_admin, routes_admin, partner, compute_admin.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/roles
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
| role | body | string | Yes | Role name to assign. | “trusted” |
curl -X 'POST' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/roles' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{"role": "trusted"}'
Returns
HTTP 201 on success:
{
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"role": "trusted"
}
Error Codes
| Code | Description |
|---|---|
| 400 | Invalid role name |
| 404 | User not found |
| 409 | User already has the role |
| 500 | Database error |
Unassign role from user
Remove a role from a user.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/roles/{name}
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
| name | path | string | Yes | Role name to remove. | “trusted” |
curl -X 'DELETE' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/roles/trusted' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 204 No Content on success. No response body is returned.
Error Codes
| Code | Description |
|---|---|
| 400 | Invalid role name |
| 404 | User not found |
| 409 | User doesn’t hold that role |
| 500 | Database error |
List user’s roles
List every app-level role a user currently holds.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/roles
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'GET' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/roles' \
-H 'Authorization: Bearer <token>'
Returns
{
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"roles": ["user", "trusted"]
}
List active sessions
List all currently active sessions across the platform, optionally scoped to a specific user. Useful for auditing active logins and investigating suspicious activity.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/sessions
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| page | query | int | No | Page number (default 1). | 1 |
| limit | query | int | No | Items per page (default 10, max 100). | 10 |
| userID | query | string | No | Restrict results to a single user. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'GET' \
'https://apis.threatwinds.com/api/auth/v2/admin/sessions?page=1&limit=10' \
-H 'Authorization: Bearer <token>'
Returns
{
"sessions": [
{
"id": "a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e",
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:135.0) Gecko/20100101 Firefox/135.0",
"ip": "203.0.113.42",
"createdAt": "2026-04-19T17:42:11Z",
"expireAt": "2026-04-20T17:42:11Z",
"kind": "standard"
},
{
"id": "b2c3d4e5-5633-4b16-bbf0-5ca22ef8ea2f",
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:135.0) Gecko/20100101 Firefox/135.0",
"ip": "203.0.113.42 (admin:5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e)",
"createdAt": "2026-04-19T18:00:00Z",
"expireAt": "2026-04-20T18:00:00Z",
"kind": "standard"
}
],
"items": 2,
"pages": 1
}
Note: Sessions created via the admin impersonation endpoint have the
ipfield stamped as"<admin_source_ip> (admin:<admin_user_id>)"so they can be distinguished from user-initiated sessions in audit logs.
Create session for user
Admin-only impersonation: mints a verified session for the target user and returns a usable bearer. This is useful for troubleshooting user issues or for administrative automation.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/session
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
| kind | body | string | No | The type of session to create. Can be “standard” or “programmatic”. Defaults to “standard”. | “standard” |
curl -X 'POST' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/session' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{"kind": "standard"}'
Returns
{
"sessionID": "a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e",
"bearer": "fq6JoEFTsxiXAl1cVxPDnK4emIQCwaUB",
"expireAt": 1674492894,
"kind": "standard"
}
HTTP 201 on success.
Verify session (admin)
Force-verify any session, regardless of its current verification state.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/session/{id}/verify
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The session’s ID. | “a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/session/a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e/verify' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with no body. 404 if the session doesn’t exist.
Close session (admin)
Close any session across any user.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/session/{id}
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The session’s ID. | “a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'DELETE' \
'https://apis.threatwinds.com/api/auth/v2/admin/session/a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with no body. 404 if the session doesn’t exist.
List keypairs
List all API keypairs across users, optionally scoped to a single user. Only metadata is returned — plaintext secrets are never exposed and are only shown once at keypair creation time.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/keypairs
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| page | query | int | No | Page number (default 1). | 1 |
| limit | query | int | No | Items per page (default 10, max 100). | 10 |
| userID | query | string | No | Restrict results to a single user. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'GET' \
'https://apis.threatwinds.com/api/auth/v2/admin/keypairs?page=1&limit=10' \
-H 'Authorization: Bearer <token>'
Returns
{
"keypairs": [
{
"id": "c1d2e3f4-5633-4b16-bbf0-5ca22ef8ea2e",
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"name": "johny",
"createdAt": "2026-01-15T10:23:41Z",
"expireAt": "2027-01-15T10:23:41Z",
"verified": true
}
],
"items": 1,
"pages": 1
}
Create keypair for user
Create a verified API keypair for a user. The keypair is pre-verified (no email verification code required). Plaintext credentials are only returned once.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/keypair
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
| name | body | string | No | Descriptive name. Defaults to admin-issued-{unix timestamp}. | “Admin Key” |
| days | body | int | No | Days until expiration. Defaults to 90. | 365 |
An empty request body is allowed (defaults apply).
curl -X 'POST' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/keypair' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{"name": "Admin Key", "days": 365}'
Returns
HTTP 201:
{
"keyID": "c1d2e3f4-5633-4b16-bbf0-5ca22ef8ea2e",
"key": "fq6JoEFTsxiXAl1cVxPDnK4emIQCwaUB",
"secret": "fq6JoEFTsxiXAl1cVxPDnK4emIQCwaUBfq6JoEFTsxiXAl1cVxPDnK4emIQCwaUB",
"name": "Admin Key",
"expireAt": "2125-07-07T10:00:00Z",
"verified": true
}
> **Note:** `key` and `secret` are the API key and secret. `expireAt` is an RFC 3339 timestamp. `verified` is always `true` for admin-created keypairs. Default expiration is 90 days. (Note: Key pairs created implicitly via [Create user](#adminCreateUser) in default mode have a 36500-day expiration.)
---
## Verify keypair (admin) {#adminVerifyKeyPair}
Force-verify any keypair across any user.
**Endpoint:** https://apis.threatwinds.com/api/auth/v2/admin/keypair/{id}/verify
### Parameters
| Parameter | Location | Type | Required | Description | Example |
|-----------|----------|--------|----------|--------------------|------------------------------------------|
| **id** | path | string | Yes | The keypair's ID. | "c1d2e3f4-5633-4b16-bbf0-5ca22ef8ea2e" |
```bash
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/keypair/c1d2e3f4-5633-4b16-bbf0-5ca22ef8ea2e/verify' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with no body. 404 if the keypair doesn’t exist.
Delete keypair (admin)
Delete any keypair across any user.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/keypair/{id}
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The keypair’s ID. | “c1d2e3f4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'DELETE' \
'https://apis.threatwinds.com/api/auth/v2/admin/keypair/c1d2e3f4-5633-4b16-bbf0-5ca22ef8ea2e' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with no body. 404 if the keypair doesn’t exist.
Create email for user
Create a pre-verified email address for a user (no verification code sent).
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/email
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
| address | body | string | Yes | Email address. | “john@doe.net” |
curl -X 'POST' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/email' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{"address": "john@doe.net"}'
Returns
HTTP 201:
{
"id": "a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e",
"address": "john@doe.net",
"status": 2
}
Verify email (admin)
Force-verify any email across any user.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/email/{id}/verify
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The email’s ID. | “a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/email/a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e/verify' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with no body.
Error Codes
| Code | Description |
|---|---|
| 400 | Email is already PREFERRED (verifying would demote it) |
| 404 | Email doesn’t exist |
Set preferred email (admin)
Set any email as the preferred address for its user.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/email/{id}/preferred
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The email’s ID. | “a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/email/a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e/preferred' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with no body. 404 if the email doesn’t exist.
Delete email (admin)
Delete any email across any user. Cannot delete a preferred email while other verified emails exist — HTTP 400 is returned. Set-preferred on another email first.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/email/{id}
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The email’s ID. | “a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'DELETE' \
'https://apis.threatwinds.com/api/auth/v2/admin/email/a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 202 with no body. 404 if the email doesn’t exist.
Get user verification
Get the full identity verification record for a user, including all historical attempts and current status.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/verification
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'GET' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/verification' \
-H 'Authorization: Bearer <token>'
Returns
{
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"verification": {
"id": "a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e",
"createdAt": "2026-05-02T14:00:00Z",
"updatedAt": "2026-05-02T14:30:00Z",
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"status": "passed",
"stripeSessionID": "vs_1234567890abcdef",
"attempts": 1,
"maxAttempts": 3,
"verifiedAt": "2026-05-02T14:30:00Z",
"expiresAt": "2026-06-15T10:23:41Z"
},
"attempts": [
{
"id": "b2c3d4e5-5633-4b16-bbf0-5ca22ef8ea2e",
"createdAt": "2026-05-02T14:30:00Z",
"updatedAt": "2026-05-02T14:30:00Z",
"verificationID": "a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e",
"stripeResult": "passed",
"stripeError": "",
"nameScanResult": "passed",
"nameScanError": "",
"failedReason": ""
}
]
}
Note:
stripeSessionID,stripeResult,stripeError,nameScanResult, andnameScanErrorare admin-internal fields used for debugging and audit. ThelastFailedReasonin user-facing endpoints is derived from these fields.
404 if no user with the given ID exists.
Reset user verification
Reset a user’s verification status to pending, resetting the attempt counter to zero. Historical attempt records are preserved for audit purposes. This allows the user to start the verification flow fresh. Useful when a user’s verification was rejected and they need a new attempt.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/verification/reset
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/verification/reset' \
-H 'Authorization: Bearer <token>'
Returns
HTTP 200 with the updated verification object:
{
"id": "a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e",
"createdAt": "2026-05-02T14:00:00Z",
"updatedAt": "2026-05-05T10:00:00Z",
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"status": "pending",
"stripeSessionID": "",
"attempts": 0,
"maxAttempts": 3,
"verifiedAt": null,
"expiresAt": null
}
Note: Response contains the pre-reset verification record. The
statusfield reflects the status BEFORE the operation. Query the verification again to confirm the change.
404 if the user doesn’t exist or has no verification record.
Revoke user verification
Revoke a user’s verified status. Sets the verification status to failed and unsets the User.Verified flag. Requires explicit confirmation in the request body to prevent accidental revocation.
Endpoint: https://apis.threatwinds.com/api/auth/v2/admin/user/{id}/verification/revoke
Parameters
| Parameter | Location | Type | Required | Description | Example |
|---|---|---|---|---|---|
| id | path | string | Yes | The user’s ID. | “5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e” |
| confirm | body | bool | Yes | Must be true to confirm the revocation. | true |
curl -X 'PUT' \
'https://apis.threatwinds.com/api/auth/v2/admin/user/5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e/verification/revoke' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{"confirm": true}'
Returns
HTTP 200 with the updated verification object.
{
"id": "a1b2c3d4-5633-4b16-bbf0-5ca22ef8ea2e",
"createdAt": "2026-05-02T14:00:00Z",
"updatedAt": "2026-05-05T10:00:00Z",
"userID": "5f35d2c4-5633-4b16-bbf0-5ca22ef8ea2e",
"status": "failed",
"stripeSessionID": "vs_1234567890abcdef",
"attempts": 1,
"maxAttempts": 3,
"verifiedAt": null,
"expiresAt": null
}
Note: Response contains the pre-revocation verification record. The
statusfield reflects the status BEFORE the operation. Query the verification again to confirm the change.
400 if confirm is not true. 404 if the user doesn’t exist or has no verification record.