Notifications

Notifications, logs, dashboard metrics, and per-user email prefs

GET /admin/api/notifications

List notifications with unread count. All authenticated admins can see notifications (no permission check).

PATCH /admin/api/notifications/{id}/read

Mark a single notification as read.

POST /admin/api/notifications/read-all

Mark all notifications as read. Returns the count of notifications that were marked.

GET /admin/api/logs

List admin log entries (webhook events, MCP tool invocations, etc.) with optional source filter and pagination.

GET /admin/api/dashboard

Returns key shop metrics: totals, recent orders, low stock alerts, and operational status counts.

GET /admin/api/dashboard/trends

Returns time-series trend data (daily revenue and order counts) plus a today-vs-yesterday comparison.

GET /admin/api/dashboard/insights

Returns business insights: top products by revenue, top customers by lifetime value, repeat customer rate, MRR, and recently cancelled subscriptions.

GET /admin/api/subscriptions

List subscriptions with pagination. Optionally filter by status, customer, or product.

GET /admin/api/subscriptions/{id}

Get full details of a single subscription including the linked initial order.

GET /admin/api/subscriptions/{id}/invoices

List all invoices for a subscription, newest first.

POST /admin/api/subscriptions/{id}/cancel

Force-cancel a subscription immediately (admin override). If Stripe credentials are configured, the subscription is also cancelled on Stripe.

GET /admin/api/dashboard/subscriptions

Returns at-a-glance counts of subscriptions grouped by status, plus the grand total.

GET /admin/api/me/notification-preferences

List the calling user's notification preferences for every event type they have permission to see. Default-on for missing rows is applied here so callers do not need to know about the absence-as-subscribed convention.

PUT /admin/api/me/notification-preferences/{event_type}

Set the calling user's email-enabled flag for a single event type. Returns 404 for unknown event types and 403 if the caller lacks the gating permission for that event.

GET /admin/api/notifications

List notifications with unread count. All authenticated admins can see notifications (no permission check).

Parameters

Name Type Required Description
limit integer optional Maximum notifications to return, 1-100 (default: 20)
offset integer optional Offset for pagination (default: 0)

Response 200

{
  "unread_count": 3,
  "notifications": [
    {
      "id": 5,
      "type": "smtp_error",
      "severity": "error",
      "title": "SMTP delivery failed",
      "message": "Order confirmation email to customer@example.com could not be delivered.",
      "metadata": {
        "order_id": 42
      },
      "read": false,
      "created_at": "2025-11-20T14:30:00Z"
    },
    {
      "id": 4,
      "type": "low_stock",
      "severity": "warning",
      "title": "Low stock alert",
      "message": "Classic Cotton Tee has only 3 units remaining.",
      "metadata": {
        "product_id": 1,
        "stock": 3
      },
      "read": false,
      "created_at": "2025-11-20T10:00:00Z"
    },
    {
      "id": 3,
      "type": "personal_access_token_created",
      "severity": "info",
      "title": "Personal access token created",
      "message": "Token \"CI pipeline\" was created.",
      "metadata": null,
      "read": true,
      "created_at": "2025-11-19T08:00:00Z"
    }
  ]
}

Example

curl "https://yourshop.zeroshop.io/admin/api/notifications?limit=20&offset=0" \
  -H "Authorization: Bearer zspat_..."
PATCH /admin/api/notifications/{id}/read

Mark a single notification as read.

Parameters

Name Type Required Description
id integer required Notification ID

Response 204

Example

curl -X PATCH "https://yourshop.zeroshop.io/admin/api/notifications/5/read" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/notifications/read-all

Mark all notifications as read. Returns the count of notifications that were marked.

Response 200

{
  "marked": 3
}

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/notifications/read-all" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/logs

List admin log entries (webhook events, MCP tool invocations, etc.) with optional source filter and pagination.

Parameters

Name Type Required Description
source string optional Filter by source (e.g. "webhook", "mcp"). Omit for all sources.
page integer optional Page number, 1-indexed (default: 1)

Response 200

{
  "logs": [
    {
      "id": 100,
      "source": "webhook",
      "action": "checkout.session.completed",
      "status": "success",
      "summary": "Processed Stripe checkout for order #ORD-0042",
      "detail": null,
      "created_at": "2025-11-20T14:30:00Z"
    },
    {
      "id": 99,
      "source": "mcp",
      "action": "create_product",
      "status": "success",
      "summary": "Created product \"Classic Cotton Tee\"",
      "detail": null,
      "created_at": "2025-11-20T14:25:00Z"
    }
  ],
  "total": 250,
  "page": 1,
  "total_pages": 13
}

Example

curl "https://yourshop.zeroshop.io/admin/api/logs?source=webhook&page=1" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/dashboard

Returns key shop metrics: totals, recent orders, low stock alerts, and operational status counts.

Response 200

{
  "total_orders": 142,
  "total_revenue": 1450000,
  "total_products": 35,
  "recent_orders": [
    {
      "id": 142,
      "status": "pending",
      "customer_name": "Jane Doe",
      "total": 5998,
      "created_at": "2025-11-20T14:30:00Z"
    },
    {
      "id": 141,
      "status": "shipped",
      "customer_name": "Bob Smith",
      "total": 2999,
      "created_at": "2025-11-20T10:15:00Z"
    }
  ],
  "low_stock_products": [
    {
      "id": 5,
      "name": "Limited Edition Hoodie",
      "stock": 2
    },
    {
      "id": 12,
      "name": "Vintage T-Shirt",
      "stock": 4
    }
  ],
  "orders_by_status": {
    "pending": 12,
    "processing": 5,
    "shipped": 98,
    "delivered": 25,
    "cancelled": 2
  },
  "orders_needing_attention": 8,
  "failed_payment_orders": 1,
  "out_of_stock_count": 3,
  "unanswered_inquiries": 4,
  "total_customers": 89,
  "new_customers_this_month": 12
}

Example

curl "https://yourshop.zeroshop.io/admin/api/dashboard" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/dashboard/insights

Returns business insights: top products by revenue, top customers by lifetime value, repeat customer rate, MRR, and recently cancelled subscriptions.

Response 200

{
  "top_products": [
    {
      "product_id": 1,
      "name": "Classic Cotton Tee",
      "revenue": 89970,
      "quantity": 30
    },
    {
      "product_id": 3,
      "name": "Premium Hoodie",
      "revenue": 74850,
      "quantity": 15
    }
  ],
  "top_customers": [
    {
      "customer_id": 12,
      "name": "Jane Doe",
      "email": "jane@example.com",
      "total_spent": 45000,
      "order_count": 5
    },
    {
      "customer_id": 8,
      "name": "Bob Smith",
      "email": "bob@example.com",
      "total_spent": 32000,
      "order_count": 3
    }
  ],
  "repeat_customer_rate": 0.34,
  "mrr": 99900,
  "recently_canceled": [
    {
      "id": 5,
      "public_id": "SUB-0005",
      "product_name": "Monthly Coffee Box",
      "canceled_at": "2025-11-18T09:00:00Z"
    }
  ]
}

Example

curl "https://yourshop.zeroshop.io/admin/api/dashboard/insights" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/subscriptions

List subscriptions with pagination. Optionally filter by status, customer, or product.

Parameters

Name Type Required Description
page integer optional Page number, 1-indexed (default: 1)
per_page integer optional Items per page, 1-100 (default: 20)
status string optional Filter by lifecycle status: "active", "past_due", "canceled", "incomplete", "incomplete_expired", "trialing", "unpaid"
customer_id integer optional Filter by local customer ID
product_id integer optional Filter by local product ID

Response 200

{
  "data": [
    {
      "id": 1,
      "public_id": "SUB-0001",
      "status": "active",
      "product_name": "Monthly Coffee Box",
      "variant_label": "Standard",
      "customer_id": 12,
      "customer_name": "Jane Doe",
      "customer_email": "jane@example.com",
      "provider": "stripe",
      "external_subscription_id": "sub_1N7abc",
      "billing_interval": "month",
      "billing_interval_count": 1,
      "cancellation_policy": "end_of_period",
      "max_billing_cycles": null,
      "unit_amount": "$19.99",
      "unit_amount_cents": 1999,
      "currency": "USD",
      "quantity": 1,
      "current_period_start": "2025-11-01T00:00:00Z",
      "current_period_end": "2025-12-01T00:00:00Z",
      "cancel_at_period_end": false,
      "canceled_at": null,
      "created_at": "2025-10-01T10:00:00Z"
    }
  ],
  "page": 1,
  "per_page": 20,
  "total": 15,
  "total_pages": 1
}

Example

curl "https://yourshop.zeroshop.io/admin/api/subscriptions?page=1&status=active" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/subscriptions/{id}

Get full details of a single subscription including the linked initial order.

Parameters

Name Type Required Description
id integer required Subscription ID

Response 200

{
  "id": 1,
  "public_id": "SUB-0001",
  "status": "active",
  "product_name": "Monthly Coffee Box",
  "variant_label": "Standard",
  "customer_id": 12,
  "customer_name": "Jane Doe",
  "customer_email": "jane@example.com",
  "provider": "stripe",
  "external_subscription_id": "sub_1N7abc",
  "billing_interval": "month",
  "billing_interval_count": 1,
  "cancellation_policy": "end_of_period",
  "max_billing_cycles": null,
  "unit_amount": "$19.99",
  "unit_amount_cents": 1999,
  "currency": "USD",
  "quantity": 1,
  "current_period_start": "2025-11-01T00:00:00Z",
  "current_period_end": "2025-12-01T00:00:00Z",
  "cancel_at_period_end": false,
  "canceled_at": null,
  "ended_at": null,
  "initial_order_id": 42,
  "initial_order_public_id": "ORD-0042",
  "created_at": "2025-10-01T10:00:00Z",
  "updated_at": "2025-11-01T00:00:00Z"
}

Example

curl "https://yourshop.zeroshop.io/admin/api/subscriptions/1" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/subscriptions/{id}/invoices

List all invoices for a subscription, newest first.

Parameters

Name Type Required Description
id integer required Subscription ID

Response 200

[
  {
    "id": 3,
    "external_invoice_id": "in_1N7xyz",
    "external_payment_intent": "pi_1N7xyz",
    "amount_total": "$19.99",
    "amount_total_cents": 1999,
    "amount_paid": "$19.99",
    "amount_paid_cents": 1999,
    "currency": "USD",
    "status": "paid",
    "period_start": "2025-11-01T00:00:00Z",
    "period_end": "2025-12-01T00:00:00Z",
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1N7abc/inv_abc123",
    "created_at": "2025-11-01T00:05:00Z"
  },
  {
    "id": 2,
    "external_invoice_id": "in_1N6xyz",
    "external_payment_intent": "pi_1N6xyz",
    "amount_total": "$19.99",
    "amount_total_cents": 1999,
    "amount_paid": "$19.99",
    "amount_paid_cents": 1999,
    "currency": "USD",
    "status": "paid",
    "period_start": "2025-10-01T00:00:00Z",
    "period_end": "2025-11-01T00:00:00Z",
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1N7abc/inv_def456",
    "created_at": "2025-10-01T00:05:00Z"
  }
]

Example

curl "https://yourshop.zeroshop.io/admin/api/subscriptions/1/invoices" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/subscriptions/{id}/cancel

Force-cancel a subscription immediately (admin override). If Stripe credentials are configured, the subscription is also cancelled on Stripe.

Parameters

Name Type Required Description
id integer required Subscription ID

Response 204

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/subscriptions/1/cancel" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/dashboard/subscriptions

Returns at-a-glance counts of subscriptions grouped by status, plus the grand total.

Response 200

{
  "total": 15,
  "by_status": {
    "active": 10,
    "past_due": 2,
    "canceled": 3
  }
}

Example

curl "https://yourshop.zeroshop.io/admin/api/dashboard/subscriptions" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/me/notification-preferences

List the calling user's notification preferences for every event type they have permission to see. Default-on for missing rows is applied here so callers do not need to know about the absence-as-subscribed convention.

Response 200

[
  {
    "event_type": "order_placed",
    "label": "New order placed",
    "email_enabled": true
  },
  {
    "event_type": "inquiry_received",
    "label": "Buyer inquiry received",
    "email_enabled": false
  }
]

Example

curl "https://yourshop.zeroshop.io/admin/api/me/notification-preferences" \
  -H "Authorization: Bearer zspat_..."
PUT /admin/api/me/notification-preferences/{event_type}

Set the calling user's email-enabled flag for a single event type. Returns 404 for unknown event types and 403 if the caller lacks the gating permission for that event.

Request Body

{
  "email_enabled": false
}

Response 200

{
  "email_enabled": false
}

Example

curl -X PUT "https://yourshop.zeroshop.io/admin/api/me/notification-preferences/order_placed" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"email_enabled": false}'

We value your privacy

We use cookies for essential site functionality and, with your consent, analytics to understand how our platform is used. No personal data is shared with third parties. See our Privacy Policy for details.