REST API
The ForgeStore API lets you query your store data, verify purchases, and check player status programmatically. Perfect for custom game plugins and integrations.
https://forgestore.net/api/v1Format: All responses are JSON. All requests must include your API key.
Authentication
All API endpoints require authentication via your Store API Key. Find it in Store Settings → Details (the long alphanumeric string).
Pass the key in the X-Api-Key header with every request:
GET https://forgestore.net/api/v1/store X-Api-Key: your_store_api_key_here
Endpoints
Example Response
{
"id": 42,
"name": "Nexus Gaming",
"subdomain": "nexus",
"game": "minecraft",
"currency": "EUR",
"url": "https://forgestore.net/s/nexus"
}
Example Response
{
"packages": [
{
"id": 1,
"name": "VIP Rank",
"description": "Access to VIP perks and kit",
"type": "single",
"price_cents": 999,
"webhook_product_id": "67afaa53ac949f9d80f31a08",
"is_hidden": false,
"image_url": "/uploads/images/abc123.jpg"
}
],
"count": 1
}
| Parameter | Type | Description |
|---|---|---|
| id | integer | Package ID (URL parameter) |
| Parameter | Type | Description |
|---|---|---|
| username | string | The in-game username (URL parameter) |
Example Response
{
"player": "Notch",
"orders": [
{
"id": 101,
"amount_cents": 999,
"currency": "EUR",
"status": "paid",
"created_at": "2025-05-07 14:22:00",
"package_name": "VIP Rank",
"package_type": "single",
"webhook_product_id": "67afaa53ac949f9d80f31a08"
}
],
"count": 1
}
Example Response
{
"player": "Notch",
"package_id": 1,
"has_purchased": true,
"purchase_count": 2
}
Example Response
{
"id": 101,
"player_id": "Notch",
"player_email": "[email protected]",
"amount_cents": 999,
"currency": "EUR",
"status": "paid",
"payment_method": "crypto",
"external_id": "cm_uuid-here",
"created_at": "2025-05-07 14:22:00",
"package_name": "VIP Rank",
"webhook_product_id": "67afaa53ac949f9d80f31a08"
}
Example Response
{
"player": "griefer123",
"is_banned": true,
"ban": {
"id": 5,
"reason": "Chargeback abuse",
"expires_at": null,
"created_at": "2025-04-01 10:00:00"
}
}
Webhooks
ForgeStore sends an HTTP POST to your server when specific events occur. Configure your webhook URL in Store Settings → Developers → Webhooks.
Supported Events
purchase— A player completed a paymentrefund— An order was refundedchargeback— A chargeback was filedgoal_complete— A community goal was reachedplayer_ban— A player was banned
Webhook Payload — purchase
{
"event": "purchase",
"storeSlug": "nexus",
"orderId": 101,
"playerData": {
"playerName": "Notch",
"playerEmail": "[email protected]",
"verified": true
},
"lineItems": [
{
"productId": "67afaa53ac949f9d80f31a08",
"quantity": 1,
"name": "VIP Rank",
"priceCents": 999,
"currency": "EUR"
}
]
}
Verifying Webhook Signatures
Every webhook includes a signature in the X-ForgeStore-Signature header. Verify it to ensure the request is genuine:
// PHP example
$payload = file_get_contents('php://input');
$sig = $_SERVER['HTTP_X_FORGESTORE_SIGNATURE'] ?? '';
$secret = 'your_webhook_secret'; // From Store Settings → Developers
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $sig)) {
http_response_code(401);
exit('Unauthorized');
}
$data = json_decode($payload, true);
// Process event...
if ($data['event'] === 'purchase') {
$player = $data['playerData']['playerName'];
$product = $data['lineItems'][0]['productId'];
// Grant items to player
}
Node.js Example (Express)
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.raw({ type: 'application/json' }));
app.post('/webhook', (req, res) => {
const sig = req.headers['x-forgestore-signature'];
const secret = process.env.WEBHOOK_SECRET;
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(req.body)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return res.status(401).send('Unauthorized');
}
const event = JSON.parse(req.body);
if (event.event === 'purchase') {
const player = event.playerData.playerName;
const product = event.lineItems[0].productId;
console.log(`Grant ${product} to ${player}`);
// Your delivery logic here
}
res.json({ received: true });
});
app.listen(3000);
Error Codes
| HTTP Status | Code | Description |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Missing or invalid parameters |
| 401 | Unauthorized | Missing or invalid X-Api-Key |
| 403 | Forbidden | You don't have access to this resource |
| 404 | Not Found | Resource doesn't exist or doesn't belong to your store |
| 429 | Too Many Requests | Rate limit exceeded — 120 requests/minute |
| 500 | Server Error | Something went wrong on our end — try again |
Error Response Format
{
"error": "Invalid API key"
}
Rate Limits
The API is rate limited to 120 requests per minute per API key. If you exceed this, you'll receive a 429 Too Many Requests response. The response includes a Retry-After header with the number of seconds to wait.
POST /api/v1/checkout
Create a checkout session for one or multiple packages. Returns a hosted checkout URL to redirect the player to.
{
"player_id": "Steve",
"package_ids": [1, 2, 3],
"email": "[email protected]"
}
{
"checkout_url": "https://forgestore.net/checkout/basket?...",
"player_id": "Steve",
"packages": [
{ "id": 1, "name": "VIP", "price": 999 }
],
"total_cents": 999,
"currency": "EUR",
"expires_at": "2026-06-09T14:00:00Z"
}
GET /api/v1/stats
Store statistics. Use ?days=30 to filter by period.
{
"total_orders": 142,
"total_revenue": 189900,
"period_orders": 18,
"period_revenue": 24500,
"currency": "EUR",
"period_days": 30
}
GET /api/v1/goals
List active community goals.
{
"data": [
{
"id": 1,
"title": "New Map",
"target_cents": 50000,
"current_cents": 23400,
"currency": "EUR",
"deadline": "2026-07-01",
"is_active": 1
}
]
}