Store Management API
Programmatically manage your store — create packages, manage coupons, query orders, and more.
The Store Management API is a Pro plan feature. API key creation and usage requires an active Pro subscription.
Authentication
All Store Management API endpoints require an API key passed in the X-Api-Key header:
curl -H "X-Api-Key: flx_XXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
https://api.fluxstore.net/api/v1/packagesGetting Your API Key
- Navigate to Dashboard > Configuration > API Keys
- Click Create API Key
- Enter a name, choose permissions, and optionally set an expiration date
- Copy the key immediately — it is shown once and cannot be recovered
Key Format
flx_{storeId}_{secret}- The
storeIdis embedded in the key for efficient lookup - Only the secret portion is hashed and stored
- The full key is displayed exactly once at creation time
Key Management
Manage keys via the dashboard or the management API:
| Action | Dashboard | API |
|---|---|---|
| Create key | Configuration > API Keys > Create | POST /api/stores/{storeId}/api-keys |
| List keys | Configuration > API Keys | GET /api/stores/{storeId}/api-keys |
| Revoke key | Click Revoke on key row | DELETE /api/stores/{storeId}/api-keys/{id} |
| Regenerate key | Click Regenerate on key row | POST /api/stores/{storeId}/api-keys/{id}/regenerate |
Management API endpoints require JWT authentication and Stores:Edit permission.
Base URL
https://api.fluxstore.net/api/v1/The store is determined automatically from your API key — no store ID needed in the URL.
Response Format
All endpoints return a standard response wrapper:
{
"success": true,
"data": { ... },
"message": null,
"errors": []
}Error responses:
{
"success": false,
"data": null,
"message": "Error description",
"errors": ["Detail 1", "Detail 2"]
}Rate Limiting
- 30 requests per minute per API key (fixed window)
- Rate limit headers are included on every response:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per window (30) |
X-RateLimit-Remaining | Remaining requests in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
When exceeded, the API returns 429 Too Many Requests with a Retry-After header.
Permissions
Each API key has scoped permissions. Set permissions when creating the key — they cannot be changed after creation. To change scopes, revoke the key and create a new one.
Permissions are defined as a dictionary of resource areas to permission types:
{
"Packages": ["View", "Edit", "Delete"],
"Orders": ["View"],
"Coupons": ["View", "Edit"]
}Permission Areas
| Area | View | Edit | Delete | Description |
|---|---|---|---|---|
| Packages | ✓ | ✓ | ✓ | Package CRUD |
| Categories | ✓ | ✓ | ✓ | Category CRUD |
| Coupons | ✓ | ✓ | ✓ | Coupon CRUD |
| Sales | ✓ | ✓ | ✓ | Sale CRUD |
| GiftCards | ✓ | ✓ | ✓ | Gift card CRUD |
| Orders | ✓ | ✓ | — | Order listing + manual creation |
| Customers | ✓ | — | — | Customer listing (read-only) |
| Bans | ✓ | ✓ | ✓ | Ban CRUD |
| Subscriptions | ✓ | — | — | Subscription listing (read-only) |
If a key lacks the required permission, the API returns 403 Forbidden.
Endpoints
Packages
Base path: /api/v1/packages
| Method | Endpoint | Permission | Description |
|---|---|---|---|
| GET | /packages | Packages:View | List all packages |
| GET | /packages/{id} | Packages:View | Get package by ID |
| POST | /packages | Packages:Edit | Create a package |
| PATCH | /packages/{id} | Packages:Edit | Update a package |
| DELETE | /packages/{id} | Packages:Delete | Delete a package |
Create Package
POST /api/v1/packages
{
"name": "VIP Rank",
"description": "Get VIP status with special perks",
"price": 9.99,
"isActive": true,
"sortOrder": 0,
"categoryId": "category-guid",
"serverIds": ["server-guid-1"]
}Update Package
All fields are optional — only include fields you want to change:
PATCH /api/v1/packages/{id}
{
"price": 14.99,
"isActive": false
}Package Response
{
"success": true,
"data": {
"id": "a1b2c3d4-...",
"name": "VIP Rank",
"description": "Get VIP status with special perks",
"price": 9.99,
"salePrice": null,
"imageUrl": null,
"isActive": true,
"sortOrder": 0,
"categoryId": "c1d2e3f4-...",
"categoryName": "Ranks",
"allowCustomPrice": false,
"globalLimit": null,
"perUserLimit": null,
"isCumulative": false,
"isTiered": false,
"isSubscription": false,
"serverIds": ["server-guid-1"],
"createdAt": "2026-01-15T10:00:00Z",
"updatedAt": "2026-01-15T10:00:00Z"
}
}Categories
Base path: /api/v1/categories
| Method | Endpoint | Permission | Description |
|---|---|---|---|
| GET | /categories | Categories:View | List all categories |
| GET | /categories/{id} | Categories:View | Get category by ID |
| POST | /categories | Categories:Edit | Create a category |
| PATCH | /categories/{id} | Categories:Edit | Update a category |
| DELETE | /categories/{id} | Categories:Delete | Delete a category |
Create Category
POST /api/v1/categories
{
"name": "Premium Ranks",
"description": "Premium rank packages",
"isEnabled": true
}Coupons
Base path: /api/v1/coupons
| Method | Endpoint | Permission | Description |
|---|---|---|---|
| GET | /coupons | Coupons:View | List coupons (paginated) |
| GET | /coupons/{id} | Coupons:View | Get coupon by ID |
| POST | /coupons | Coupons:Edit | Create a coupon |
| PATCH | /coupons/{id} | Coupons:Edit | Update a coupon |
| DELETE | /coupons/{id} | Coupons:Delete | Delete a coupon |
Query parameters: ?search=CODE&status=active&skip=0&take=20
Create Coupon
POST /api/v1/coupons
{
"code": "SUMMER25",
"discountType": "percentage",
"discountValue": 25,
"applicationScope": "packages",
"packageScope": "all",
"maxUses": 100,
"maxUsesPerUser": 1,
"validFrom": "2026-06-01T00:00:00Z",
"validUntil": "2026-09-01T00:00:00Z",
"isActive": true
}Update Coupon
PATCH /api/v1/coupons/{id}
{
"discountValue": 30,
"maxUses": 200,
"isActive": false
}Sales
Base path: /api/v1/sales
| Method | Endpoint | Permission | Description |
|---|---|---|---|
| GET | /sales | Sales:View | List sales (paginated) |
| GET | /sales/{id} | Sales:View | Get sale by ID |
| POST | /sales | Sales:Edit | Create a sale |
| PATCH | /sales/{id} | Sales:Edit | Update a sale |
| DELETE | /sales/{id} | Sales:Delete | Delete a sale |
Create Sale
POST /api/v1/sales
{
"name": "Summer Sale",
"discountPercentage": 30,
"applicationScope": "store",
"isEnabled": true,
"startDate": "2026-06-01T00:00:00Z",
"endDate": "2026-06-30T23:59:59Z"
}Gift Cards
Base path: /api/v1/gift-cards
| Method | Endpoint | Permission | Description |
|---|---|---|---|
| GET | /gift-cards | GiftCards:View | List gift cards (paginated) |
| GET | /gift-cards/{id} | GiftCards:View | Get gift card by ID |
| POST | /gift-cards | GiftCards:Edit | Create a gift card |
| PATCH | /gift-cards/{id} | GiftCards:Edit | Update a gift card |
| DELETE | /gift-cards/{id} | GiftCards:Delete | Delete a gift card |
Security: Gift card redemption codes are never exposed through the API. Responses include the ID, amount, balance, and status — but not the code. This prevents code enumeration attacks.
Create Gift Card
POST /api/v1/gift-cards
{
"amount": 25.00,
"applicationScope": "store",
"recipientName": "John",
"recipientEmail": "[email protected]",
"message": "Happy Birthday!",
"expiresAt": "2027-01-01T00:00:00Z"
}Orders
Base path: /api/v1/orders
| Method | Endpoint | Permission | Description |
|---|---|---|---|
| GET | /orders | Orders:View | List orders (paginated + filtered) |
| GET | /orders/{id} | Orders:View | Get order by ID |
| POST | /orders | Orders:Edit | Create a manual order |
Query parameters: ?playerUsername=Steve&playerUuid=uuid&status=paid&skip=0&take=20
Privacy: Customer email addresses are masked in API responses (e.g.,
j***@example.com) to protect personally identifiable information.
Create Manual Order
Manual orders are created as paid and fulfilled immediately — commands are executed on the game server.
POST /api/v1/orders
{
"playerUsername": "Steve",
"playerUuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5",
"email": "[email protected]",
"items": [
{
"packageId": "package-guid",
"quantity": 1,
"serverId": "server-guid"
}
]
}Order Response
{
"success": true,
"data": {
"id": "e5f6a7b8-...",
"playerUsername": "Steve",
"playerUuid": "069a79f4-...",
"email": "s***@example.com",
"status": "Paid",
"totalAmount": 9.99,
"paymentProvider": "Manual",
"paymentCurrency": "USD",
"couponId": null,
"couponDiscountAmount": null,
"giftCardId": null,
"giftCardAmount": null,
"items": [
{
"id": "f1a2b3c4-...",
"packageId": "package-guid",
"packageName": "VIP Rank",
"quantity": 1,
"priceAtPurchase": 9.99
}
],
"createdAt": "2026-01-15T10:00:00Z",
"updatedAt": "2026-01-15T10:00:00Z"
}
}Customers
Base path: /api/v1/customers
| Method | Endpoint | Permission | Description |
|---|---|---|---|
| GET | /customers | Customers:View | List customers (paginated) |
| GET | /customers/{id} | Customers:View | Get customer by ID |
Read-only. Query parameters: ?search=steve&sortBy=totalSpent&sortDesc=true&skip=0&take=20
Privacy: Personally identifiable information is not exposed through the Store Management API.
Bans
Base path: /api/v1/bans
| Method | Endpoint | Permission | Description |
|---|---|---|---|
| GET | /bans | Bans:View | List bans (paginated) |
| GET | /bans/{id} | Bans:View | Get ban by ID |
| POST | /bans | Bans:Edit | Create a ban |
| PATCH | /bans/{id} | Bans:Edit | Update a ban |
| DELETE | /bans/{id} | Bans:Delete | Delete a ban |
Ban by Username
POST /api/v1/bans
{
"playerUsername": "griefer123",
"reason": "Chargeback fraud",
"expiresAt": null
}Ban by IP Address
POST /api/v1/bans
{
"ipAddress": "192.168.1.100",
"reason": "Abuse"
}Subscriptions
Base path: /api/v1/subscriptions
| Method | Endpoint | Permission | Description |
|---|---|---|---|
| GET | /subscriptions | Subscriptions:View | List subscriptions |
| GET | /subscriptions/{id} | Subscriptions:View | Get subscription by ID |
Read-only. Query parameters: ?playerUsername=Steve
Error Codes
| HTTP Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request — validation error or malformed input |
| 401 | Authentication failed — missing, invalid, or expired API key |
| 403 | Forbidden — insufficient permissions or Pro subscription lapsed |
| 404 | Resource not found |
| 429 | Rate limit exceeded — wait and retry |
Examples
List Packages
curl -H "X-Api-Key: flx_XXXX_XXXXXXXX" \
https://api.fluxstore.net/api/v1/packagesCreate a Coupon
curl -X POST \
-H "X-Api-Key: flx_XXXX_XXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"code": "WELCOME10",
"discountType": "percentage",
"discountValue": 10,
"applicationScope": "packages",
"packageScope": "all",
"maxUses": 500,
"isActive": true
}' \
https://api.fluxstore.net/api/v1/couponsCreate a Manual Order
curl -X POST \
-H "X-Api-Key: flx_XXXX_XXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"playerUsername": "Steve",
"items": [{"packageId": "pkg-guid", "quantity": 1, "serverId": "srv-guid"}]
}' \
https://api.fluxstore.net/api/v1/ordersBan a Player
curl -X POST \
-H "X-Api-Key: flx_XXXX_XXXXXXXX" \
-H "Content-Type: application/json" \
-d '{"playerUsername": "griefer", "reason": "Fraud"}' \
https://api.fluxstore.net/api/v1/bansDelete a Package
curl -X DELETE \
-H "X-Api-Key: flx_XXXX_XXXXXXXX" \
https://api.fluxstore.net/api/v1/packages/{packageId}Security
- Key secrets are hashed — Secrets are never stored in plain text and cannot be recovered.
- Pro gating — Creating and using API keys requires an active Pro subscription. If your subscription lapses, existing keys return
403until renewed. - Rate limiting — 30 requests per minute per key.
- Input validation — All request fields are validated server-side.
- Data privacy — Gift card codes are never exposed. Customer emails are masked.
- Permissions are immutable — To change scopes, revoke the key and create a new one.