Admin Analytics API
The Admin Analytics API provides comprehensive gallery-wide metrics for platform administrators. View sales data, artist performance, cart metrics, and referral conversions.
Authentication
Requires Supabase authentication with admin role:
Authorization: Bearer <access_token>
Endpoint
Get Gallery Analytics
Retrieves comprehensive gallery-wide analytics.
Endpoint: GET /api/admin/analytics
Authentication: Required (admin only)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
start_date | string | Start date (ISO 8601, default: 30 days ago) |
end_date | string | End date (ISO 8601, default: now) |
Response:
{
"analytics": {
"overview": {
"totalOrders": 156,
"totalRevenue": 18750.00,
"galleryRevenue": 2250.00,
"artistPayouts": 16500.00,
"averageOrderValue": 120.19,
"totalItemsSold": 284
},
"ordersByStatus": {
"pending": 2,
"paid": 8,
"processing": 12,
"partially_shipped": 15,
"shipped": 89,
"delivered": 30
},
"topArtists": [
{
"orgId": "org_abc",
"artistName": "Jane Smith Studio",
"totalOrders": 42,
"totalRevenue": 5250.00,
"artistPayout": 4620.00,
"itemsSold": 78
},
{
"orgId": "org_def",
"artistName": "Bob's Pottery",
"totalOrders": 38,
"totalRevenue": 3800.00,
"artistPayout": 3344.00,
"itemsSold": 56
}
],
"cartMetrics": {
"activeCarts": 45,
"averageCartValue": 225.50,
"abandonmentRate": 32.5,
"averageItemsPerCart": 3.2
},
"referralMetrics": {
"totalReferrals": 342,
"conversions": 68,
"conversionRate": 19.88,
"attributedRevenue": 6840.00
},
"timeline": [
{
"date": "2024-01-01",
"orders": 8,
"revenue": 960.00,
"newCarts": 24
},
{
"date": "2024-01-02",
"orders": 12,
"revenue": 1440.00,
"newCarts": 31
}
],
"dateRange": {
"start": "2024-01-01T00:00:00Z",
"end": "2024-01-31T23:59:59Z"
}
}
}
Response Fields:
Overview
| Field | Type | Description |
|---|---|---|
totalOrders | number | Total gallery orders placed |
totalRevenue | number | Total product revenue (before commission) |
galleryRevenue | number | 12% gallery commission earned |
artistPayouts | number | 88% paid out to artists |
averageOrderValue | number | Average revenue per order |
totalItemsSold | number | Total quantity of items sold |
Orders by Status
Count of orders in each status:
pending: Payment not completedpaid: Awaiting fulfillmentprocessing: Artists preparing itemspartially_shipped: Some artists shippedshipped: All artists shippeddelivered: All items delivered
Top Artists
Top 10 artists by revenue:
| Field | Type | Description |
|---|---|---|
orgId | string | Artist organization ID |
artistName | string | Artist display name |
totalOrders | number | Orders containing their products |
totalRevenue | number | Total product revenue |
artistPayout | number | Amount paid to artist |
itemsSold | number | Quantity of items sold |
Cart Metrics
| Field | Type | Description |
|---|---|---|
activeCarts | number | Non-empty carts in last 30 days |
averageCartValue | number | Average value of active carts |
abandonmentRate | number | % of carts not converted to orders |
averageItemsPerCart | number | Average quantity per cart |
Referral Metrics
| Field | Type | Description |
|---|---|---|
totalReferrals | number | Gallery → artist store clicks |
conversions | number | Referrals who purchased within 30 days |
conversionRate | number | Conversion percentage |
attributedRevenue | number | Revenue from attributed conversions |
Note: Attributed revenue is from individual artist stores (not gallery sales). Artists keep 100% minus Stripe fees on attributed sales.
Timeline
Daily breakdown of activity:
| Field | Type | Description |
|---|---|---|
date | string | Date (YYYY-MM-DD) |
orders | number | Orders placed |
revenue | number | Revenue generated |
newCarts | number | New cart sessions created |
Example Request:
curl "https://gallery.artbase.studio/api/admin/analytics" \
-H "Authorization: Bearer <admin_token>"
Example with Date Range:
curl "https://gallery.artbase.studio/api/admin/analytics?start_date=2024-01-01&end_date=2024-01-31" \
-H "Authorization: Bearer <admin_token>"
Error Responses:
| Status | Error | Description |
|---|---|---|
| 401 | Unauthorized | Not logged in |
| 403 | Forbidden | Not an admin |
Key Metrics Explained
Gallery Revenue vs Artist Payouts
Gallery uses a transparent 88/12 split:
Product Price: $100
├─ Artist Payout (88%): $88
└─ Gallery Commission (12%): $12
Customer Pays: ~$115 (includes Stripe fees)
Gallery Revenue = 12% of all product sales Artist Payouts = 88% of all product sales
Cart Abandonment Rate
Abandonment Rate = (Carts - Orders) / Carts × 100
Example:
- 100 active carts
- 65 orders completed
- Abandonment rate = (100 - 65) / 100 = 35%
Industry benchmarks:
- ✅ Below 30%: Excellent
- 👍 30-50%: Good
- ⚠️ 50-70%: Needs improvement
- ❌ Above 70%: Critical issue
Referral Conversion Rate
Conversion Rate = Conversions / Total Referrals × 100
Measures how well the gallery drives sales to individual artist stores.
Benchmarks:
- ✅ Above 20%: Excellent
- 👍 10-20%: Good
- ⚠️ 5-10%: Fair
- ❌ Below 5%: Poor
Use Cases
Admin Dashboard
Display key metrics:
import { useEffect, useState } from 'react';
export function AdminDashboard({ token }) {
const [analytics, setAnalytics] = useState(null);
useEffect(() => {
async function fetchAnalytics() {
const res = await fetch('/api/admin/analytics', {
headers: { Authorization: `Bearer ${token}` },
});
const data = await res.json();
setAnalytics(data.analytics);
}
fetchAnalytics();
}, [token]);
if (!analytics) return <div>Loading...</div>;
const { overview, ordersByStatus, topArtists, cartMetrics } = analytics;
return (
<div>
<h1>Gallery Analytics</h1>
<div className="metrics-grid">
<div className="metric">
<h3>Total Revenue</h3>
<p>${overview.totalRevenue.toFixed(2)}</p>
</div>
<div className="metric">
<h3>Gallery Commission</h3>
<p>${overview.galleryRevenue.toFixed(2)}</p>
</div>
<div className="metric">
<h3>Total Orders</h3>
<p>{overview.totalOrders}</p>
</div>
<div className="metric">
<h3>Avg Order Value</h3>
<p>${overview.averageOrderValue.toFixed(2)}</p>
</div>
</div>
<h2>Top Artists</h2>
<table>
<thead>
<tr>
<th>Artist</th>
<th>Orders</th>
<th>Revenue</th>
<th>Items Sold</th>
</tr>
</thead>
<tbody>
{topArtists.map(artist => (
<tr key={artist.orgId}>
<td>{artist.artistName}</td>
<td>{artist.totalOrders}</td>
<td>${artist.totalRevenue.toFixed(2)}</td>
<td>{artist.itemsSold}</td>
</tr>
))}
</tbody>
</table>
<h2>Cart Metrics</h2>
<p>Active carts: {cartMetrics.activeCarts}</p>
<p>Abandonment rate: {cartMetrics.abandonmentRate.toFixed(1)}%</p>
</div>
);
}
Revenue Chart
Visualize daily revenue:
import { Line } from 'react-chartjs-2';
export function RevenueChart({ timeline }) {
const data = {
labels: timeline.map(day => day.date),
datasets: [
{
label: 'Daily Revenue',
data: timeline.map(day => day.revenue),
borderColor: 'rgb(75, 192, 192)',
tension: 0.1,
},
{
label: 'Daily Orders',
data: timeline.map(day => day.orders),
borderColor: 'rgb(255, 99, 132)',
tension: 0.1,
},
],
};
return <Line data={data} />;
}
Export Analytics Report
async function exportAnalytics(token: string, startDate: string, endDate: string) {
const res = await fetch(
`/api/admin/analytics?start_date=${startDate}&end_date=${endDate}`,
{
headers: { Authorization: `Bearer ${token}` },
}
);
const { analytics } = await res.json();
const csv = [
['Gallery Analytics Report'],
[`Date Range: ${startDate} to ${endDate}`],
[''],
['Overview'],
['Total Orders', analytics.overview.totalOrders],
['Total Revenue', analytics.overview.totalRevenue],
['Gallery Revenue', analytics.overview.galleryRevenue],
['Artist Payouts', analytics.overview.artistPayouts],
['Average Order Value', analytics.overview.averageOrderValue],
[''],
['Top Artists'],
['Artist', 'Orders', 'Revenue', 'Payout'],
...analytics.topArtists.map(a => [
a.artistName,
a.totalOrders,
a.totalRevenue,
a.artistPayout,
]),
]
.map(row => row.join(','))
.join('\n');
const blob = new Blob([csv], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `gallery-analytics-${startDate}-${endDate}.csv`;
a.click();
}
Performance Optimization
Reduce Cart Abandonment
If abandonment rate is high (>50%):
- Simplify checkout - Reduce steps, fewer form fields
- Show trust signals - Security badges, return policy
- Email reminders - Send abandoned cart emails
- Shipping transparency - Clear shipping costs and timelines
- Guest checkout - Don't require account creation
Improve Referral Conversions
If conversion rate is low (<10%):
- Better CTAs - "Visit Artist Store" more prominent
- Artist profiles - Richer artist pages on gallery
- Incentives - First-time buyer discounts on artist stores
- Email follow-up - "Liked this artist? Visit their store"
- Retargeting - Pixel-based remarketing
Boost Average Order Value
Increase AOV with:
- Bundles - "Complete the collection" suggestions
- Free shipping threshold - "Add $X for free shipping"
- Cross-sells - "Customers also bought..."
- Volume discounts - "Buy 2, save 10%"