E-commerce API
POST /services/webshop/v1/dashboard/stats Auth

Webshop admin dashboard stats

Single endpoint that returns all sections for the webshop dashboard: KPIs (with compare deltas), revenue chart series, order status counts, recent orders, top products, low stock, abandoned carts, payment methods, order type split, and top discounts. Period anchors: - Revenue / AOV / paid metrics: `paid_at` (money collected) - Order count / type split / recent orders / chart: `created_at` (demand placed) - Refunds: `updated_at` (status change time; no dedicated refunded_at column)

Request Body

FieldTypeRequiredDescriptionExample
start_date string|null (date-time) No 2026-04-15
end_date string|null (date-time) No 2026-05-15
compare_start_date string|null (date-time) No 2026-03-15
compare_end_date string|null (date-time) No 2026-04-14
interval string|null
daily, weekly, monthly
No daily
low_stock_threshold integer|null
min: 1 max: 1000
No 5
abandoned_threshold_hours integer|null
min: 1 max: 720
No 10

Responses

500
200
422
401
403
429
Internal server error
Headers
HeaderTypeDescriptionExample
X-RateLimit-Limit integer Maximum number of requests allowed per minute 60
X-RateLimit-Remaining integer Number of requests remaining in the current window 57
FieldTypeDescription
error boolean
message string
data mixed[]
Dashboard stats bundle
Headers
HeaderTypeDescriptionExample
X-RateLimit-Limit integer Maximum number of requests allowed per minute 60
X-RateLimit-Remaining integer Number of requests remaining in the current window 57
FieldTypeDescription
error boolean
message string
data object
data.period object
data.compare object|null
data.kpis object
data.revenue_series mixed[]
data.revenue_series_previous array|null Parallel bucketed series for the chart overlay. The frontend unions labels (date-axis) and renders this as a dashed line in the same color family — the Shopify/BigCommerce pattern.
data.order_status_counts object
data.recent_orders mixed[]
data.top_products object Return BOTH rankings in one request so the dashboard's units/revenue toggle is pure local state — no re-fetch on flip, no visible jank while the new order computes. Two cheap aggregations against the same join cost less than the round-trip a toggle re-fetch would add.
data.low_stock mixed[]
data.abandoned_carts object Threshold + reminder-flag travel WITH the widget data so the frontend can render the correct "Idle Nh+" hint and decide whether to show the soft "enable reminders" prompt without a second round-trip to the settings endpoint.
data.payment_methods mixed[]
data.payment_methods_previous array|null
data.order_type_split mixed[]
data.order_type_split_previous array|null
data.top_discounts mixed[]
Validation error
FieldTypeDescription
message string Errors overview.
errors object A detailed description of each field that failed validation.
Unauthenticated — missing or invalid Bearer token
Headers
HeaderTypeDescriptionExample
X-RateLimit-Limit integer Maximum number of requests allowed per minute 60
X-RateLimit-Remaining integer Number of requests remaining in the current window 57
FieldTypeDescription
error boolean
message string
Forbidden — insufficient permissions for this resource
Headers
HeaderTypeDescriptionExample
X-RateLimit-Limit integer Maximum number of requests allowed per minute 60
X-RateLimit-Remaining integer Number of requests remaining in the current window 57
FieldTypeDescription
error boolean
message string
Too Many Requests — rate limit exceeded
Headers
HeaderTypeDescriptionExample
X-RateLimit-Limit integer Maximum number of requests allowed per minute 60
X-RateLimit-Remaining integer Number of requests remaining in the current window 57
Retry-After integer Seconds until the rate limit resets 60
FieldTypeDescription
error boolean
message string
Base URL
https://api.wemasy.nl/api
Authentication

Request Sample
cURL
JS
PHP
Python
curl -X POST "https://api.wemasy.nl/api/services/webshop/v1/dashboard/stats" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "start_date": "2026-04-15",
    "end_date": "2026-05-15",
    "compare_start_date": "2026-03-15",
    "compare_end_date": "2026-04-14",
    "interval": "daily",
    "low_stock_threshold": 5,
    "abandoned_threshold_hours": 10
}'
fetch('https://api.wemasy.nl/api/services/webshop/v1/dashboard/stats', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "start_date": "2026-04-15",
    "end_date": "2026-05-15",
    "compare_start_date": "2026-03-15",
    "compare_end_date": "2026-04-14",
    "interval": "daily",
    "low_stock_threshold": 5,
    "abandoned_threshold_hours": 10
})})
.then(r => r.json())
.then(data => console.log(data));
$response = Http::withToken('YOUR_API_TOKEN')
    ->accept('application/json')
    ->post('https://api.wemasy.nl/api/services/webshop/v1/dashboard/stats', {
    "start_date": "2026-04-15",
    "end_date": "2026-05-15",
    "compare_start_date": "2026-03-15",
    "compare_end_date": "2026-04-14",
    "interval": "daily",
    "low_stock_threshold": 5,
    "abandoned_threshold_hours": 10
});
$data = $response->json();
import requests

headers = {
    "Authorization": "Bearer YOUR_API_TOKEN",
    "Accept": "application/json"
}
data = {
    "start_date": "2026-04-15",
    "end_date": "2026-05-15",
    "compare_start_date": "2026-03-15",
    "compare_end_date": "2026-04-14",
    "interval": "daily",
    "low_stock_threshold": 5,
    "abandoned_threshold_hours": 10
}
r = requests.post("https://api.wemasy.nl/api/services/webshop/v1/dashboard/stats", headers=headers, json=data)
print(r.json())
Response Example
{
    "error": false,
    "data": {
        "period": {
            "from": "2026-04-15 00:00:00",
            "to": "2026-05-15 23:59:59"
        },
        "compare": {
            "from": "2026-03-16 00:00:00",
            "to": "2026-04-14 23:59:59"
        },
        "kpis": {
            "current": {
                "revenue": 12340.5,
                "orders": 142,
                "aov": 86.9,
                "refunds_count": 3,
                "refunds_amount": 230
            },
            "previous": {
                "revenue": 10700,
                "orders": 131,
                "aov": 88.4,
                "refunds_count": 5,
                "refunds_amount": 410
            },
            "stats_chart": {
                "revenue": {
                    "values": [
                        10700,
                        12340.5
                    ],
                    "trend": "up",
                    "percentage": "15.33"
                },
                "orders": {
                    "values": [
                        131,
                        142
                    ],
                    "trend": "up",
                    "percentage": "8.40"
                },
                "aov": {
                    "values": [
                        88.4,
                        86.9
                    ],
                    "trend": "down",
                    "percentage": "1.70"
                },
                "refunds_amount": {
                    "values": [
                        410,
                        230
                    ],
                    "trend": "up",
                    "percentage": "43.90"
                }
            }
        },
        "revenue_series": [
            {
                "bucket": "2026-04-15",
                "revenue": 420,
                "orders": 5
            }
        ],
        "revenue_series_previous": [
            {
                "bucket": "2026-03-16",
                "revenue": 380,
                "orders": 4
            }
        ],
        "order_status_counts": {
            "on_hold": 5,
            "awaiting_payment": 3,
            "processing": 8,
            "refunding": 1
        },
        "recent_orders": [],
        "top_products": {
            "by_units": [],
            "by_revenue": [],
            "previous": {
                "by_units": [],
                "by_revenue": []
            }
        },
        "low_stock": [],
        "abandoned_carts": {
            "count": 0,
            "list": []
        },
        "payment_methods": [],
        "payment_methods_previous": [],
        "order_type_split": {
            "checkout": 0,
            "quote": 0
        },
        "order_type_split_previous": {
            "checkout": 0,
            "quote": 0
        },
        "top_discounts": []
    }
}

Try It
Request Body Optional

Export