Customer Management
Customer accounts represent organizations or teams in ThreatWinds. Each customer has a subscription tier, team members with roles, and associated usage limits. User management is handled by the Auth API. Admin user operations are available in the Auth Admin API.
Create Customer
Create a new customer account. The authenticated user automatically becomes the account owner. All fields in the request body are required.
Endpoint: https://apis.threatwinds.com/api/billing/v1/customer
Method: POST
Parameters
Headers
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Optional* | Bearer token from an active session. |
| api-key | string | Optional* | API key for key-based authentication |
| api-secret | string | Optional* | API secret for key-based authentication |
Note: You must use either Authorization header OR API key/secret combination.
Request Body
{
"email": "john@doe.com",
"name": "Acme Corp",
"billingAddress": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"country": "US"
}
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | Yes | Customer email address | |
| name | string | Yes | Organization or company name |
| billingAddress | object | Yes | Billing address object (see sub-fields below) |
| billingAddress.street | string | Yes | Street address |
| billingAddress.city | string | Yes | City |
| billingAddress.state | string | Yes | State, province, or region |
| billingAddress.postalCode | string | Yes | Postal / ZIP code |
| billingAddress.country | string | Yes | 2-letter ISO 3166-1 alpha-2 country code (e.g. US, GB) |
Request
To create a customer account, use a POST request:
curl -X 'POST' \
'https://apis.threatwinds.com/api/billing/v1/customer' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"email": "john@doe.com",
"name": "Acme Corp",
"billingAddress": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"country": "US"
}
}'
Or using API key and secret:
curl -X 'POST' \
'https://apis.threatwinds.com/api/billing/v1/customer' \
-H 'accept: application/json' \
-H 'api-key: <YOUR_API_KEY>' \
-H 'api-secret: <YOUR_API_SECRET>' \
-H 'Content-Type: application/json' \
-d '{
"email": "john@doe.com",
"name": "Acme Corp",
"billingAddress": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"country": "US"
}
}'
Response
A successful response will return the created customer information.
Success Response (201 Created)
{
"message": "acknowledged"
}
Response Schema
| Field | Type | Description |
|---|---|---|
| message | string | Acknowledgement message |
Error Codes
| Status Code | Description | Possible Cause |
|---|---|---|
| 201 | Created | Customer created successfully |
| 400 | Bad Request | Missing or invalid fields (email, name, billing address), invalid country code |
| 401 | Unauthorized | Missing or invalid authentication |
| 412 | Precondition Failed | User is already a member of another customer |
| 500 | Internal Server Error | Server error during customer creation |
Note: Each user may only be a member of a single customer account. This is enforced by the API. Attempts to create a customer when the user already belongs to another customer will return
412 Precondition Failed. Admin attempts to add an already-member user to a different customer will return409 Conflict.
Get Customer
Retrieve customer account details for the authenticated user.
Endpoint: https://apis.threatwinds.com/api/billing/v1/customer
Method: GET
Parameters
Headers
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Optional* | Bearer token from an active session. |
| api-key | string | Optional* | API key for key-based authentication |
| api-secret | string | Optional* | API secret for key-based authentication |
Note: You must use either Authorization header OR API key/secret combination.
Required Roles
Required role: owner, admin, or user
Request
To retrieve customer information, use a GET request:
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/customer' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
Or using API key and secret:
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/customer' \
-H 'accept: application/json' \
-H 'api-key: <YOUR_API_KEY>' \
-H 'api-secret: <YOUR_API_SECRET>'
Response
Success Response (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"stripeCustomerId": "cus-abc123"
}
Response Schema
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Customer unique identifier |
| stripeCustomerId | string | Payment provider customer ID |
Error Codes
| Status Code | Description | Possible Cause |
|---|---|---|
| 200 | OK | Request successful |
| 404 | Not Found | User not found or no customer |
| 400 | Bad Request | Invalid request |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Insufficient permissions |
Delete Customer
Permanently delete a customer account. Only the account owner can perform this action.
Endpoint: https://apis.threatwinds.com/api/billing/v1/customer
Method: DELETE
Parameters
Headers
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Optional* | Bearer token from an active session. |
| api-key | string | Optional* | API key for key-based authentication |
| api-secret | string | Optional* | API secret for key-based authentication |
Note: You must use either Authorization header OR API key/secret combination.
Required Roles
Required role: owner
This endpoint requires the owner role. Only the account owner can delete the customer.
Behavior
Synchronous cascade. On success:
- All active subscriptions are cancelled.
- All team members are removed from the customer.
- The customer record is deleted; customer usage data is cleared.
- A lifecycle event is published; downstream services clean up the customer’s resources.
Returns 204 No Content on success. See Account Deletion Cascade for the full behavior across services.
Request
To delete a customer account, use a DELETE request:
curl -X 'DELETE' \
'https://apis.threatwinds.com/api/billing/v1/customer' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
Or using API key and secret:
curl -X 'DELETE' \
'https://apis.threatwinds.com/api/billing/v1/customer' \
-H 'accept: application/json' \
-H 'api-key: <YOUR_API_KEY>' \
-H 'api-secret: <YOUR_API_SECRET>'
Response
Success Response (204 No Content)
Note: Despite the
204 No Contentstatus code, the API returns a JSON response body:{ "message": "acknowledged" }Clients should handle both the status code and the response body.
Error Codes
| Status Code | Description | Possible Cause |
|---|---|---|
| 204 | No Content | Customer deleted successfully |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | User is not the owner or insufficient permissions |
| 404 | Not Found | Customer not found |
| 500 | Internal Server Error | Server error during customer deletion |
Leave Customer
Remove yourself from a customer account. Owners cannot use this endpoint and must transfer ownership first.
Endpoint: https://apis.threatwinds.com/api/billing/v1/customer/leave
Method: DELETE
Parameters
Headers
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Optional* | Bearer token from an active session. |
| api-key | string | Optional* | API key for key-based authentication |
| api-secret | string | Optional* | API secret for key-based authentication |
Note: You must use either Authorization header OR API key/secret combination.
Required Roles
Required role: admin or user
This endpoint requires the admin or user role. Owners cannot leave and must transfer ownership first.
Request
To leave a customer account, use a DELETE request:
curl -X 'DELETE' \
'https://apis.threatwinds.com/api/billing/v1/customer/leave' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
Or using API key and secret:
curl -X 'DELETE' \
'https://apis.threatwinds.com/api/billing/v1/customer/leave' \
-H 'accept: application/json' \
-H 'api-key: <YOUR_API_KEY>' \
-H 'api-secret: <YOUR_API_SECRET>'
Response
Success Response (204 No Content)
Note: Despite the
204 No Contentstatus code, the API returns a JSON response body:{ "message": "acknowledged" }Clients should handle both the status code and the response body.
Error Codes
| Status Code | Description | Possible Cause |
|---|---|---|
| 204 | No Content | Successfully left customer account |
| 400 | Bad Request | User is owner and cannot leave |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Customer not found |
Get Customer Tier Information
Get detailed subscription tier information and status for the authenticated user’s customer account.
Endpoint: https://apis.threatwinds.com/api/billing/v1/customer/tier
Method: GET
Parameters
Headers
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Optional* | Bearer token from an active session. |
| api-key | string | Optional* | API key for key-based authentication |
| api-secret | string | Optional* | API secret for key-based authentication |
Note: You must use either Authorization header OR API key/secret combination.
Required Roles
Required role: owner, admin, or user
Request
To retrieve tier information, use a GET request:
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/customer/tier' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
Or using API key and secret:
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/customer/tier' \
-H 'accept: application/json' \
-H 'api-key: <YOUR_API_KEY>' \
-H 'api-secret: <YOUR_API_SECRET>'
Response
Success Response (200 OK)
{
"customerId": "550e8400-e29b-41d4-a716-446655440000",
"tierId": "770e8400-e29b-41d4-a716-446655440000",
"tierName": "Professional",
"description": "Professional tier with advanced features",
"isActive": true,
"subscriptionStatus": "active",
"stacks": 1,
"trialUsed": false
}
Response Schema
| Field | Type | Description |
|---|---|---|
| customerId | string (UUID) | Customer unique identifier |
| tierId | string (UUID) | Subscription tier unique identifier |
| tierName | string | Tier name (e.g., “Free”, “Professional”, “Enterprise”) |
| description | string | Tier description |
| isActive | boolean | Whether the tier is active |
| subscriptionStatus | string | Current subscription status |
| stacks | integer | Number of stacks/units for this subscription |
| trialUsed | boolean | Whether the customer has already used their free trial |
Subscription Status Values
| Status | Description |
|---|---|
| active | Active subscription, all features available |
| past_due | Payment overdue, features may be restricted |
| canceled | Subscription cancelled, access limited |
| paused | Temporarily paused |
| unpaid | Unpaid invoice, requires payment |
| incomplete | Incomplete payment setup |
| trialing | Free trial period |
Error Codes
| Status Code | Description | Possible Cause |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid request |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Customer not found or no active subscription |
Role format: The API accepts role as a string (preferred):
"owner","admin", or"user". For backwards compatibility, the legacy integer values0,1,2are also accepted on input. All responses use the canonical string names.