---
title: Subscriptions and Apps API
menu_group: REST API
menu_order: 30
tab: Apps
tab_order: 30
requires_subscriptions: true
summary: Auth tokens, viewer profile, tiers, Stripe checkout, webhooks, and admin stats.
---

# Subscriptions and Apps API

These routes extend `/wp-json/mediablaster/v3` when:

1. `WPST_SUBSCRIPTIONS_ENABLED` is `true` in `wp-config.php`, and  
2. **Enable REST/API access** is on under **MediaBlaster → Subscriptions → General**.

Configure token and login options under **Subscriptions → API/Auth**. See [Subscriptions API and Auth](subscriptions-api-auth.md) for admin settings.

## Authentication

Send bearer tokens on protected routes:

```
Authorization: Bearer {token}
```

Obtain a token with `POST /auth/login` (when enabled). WordPress cookie sessions also work for same-site browser apps on routes that allow it.

## Auth endpoints

| Method | Route | Auth | Description |
|--------|-------|------|-------------|
| POST | `/auth/register` | Public | Create account (if headless registration enabled) |
| POST | `/auth/login` | Public | Email/password login; returns token |
| POST | `/auth/logout` | Bearer | Revoke current token |
| POST | `/auth/refresh` | Bearer | Issue new token (if refresh enabled) |

### Login request

```json
{
  "username": "viewer@example.com",
  "password": "your-password",
  "device_name": "iOS App",
  "device_type": "mobile"
}
```

Successful login returns `token`, `expires_at`, `user`, and subscription/entitlement summaries.

## Viewer profile

### `GET /me`

Public route; returns authentication state without exposing sensitive token details.

**Logged out:**

```json
{
  "authenticated": false,
  "user": null
}
```

**Logged in:**

```json
{
  "authenticated": true,
  "user": {
    "id": 1,
    "name": "Display Name",
    "email": "user@example.com"
  },
  "subscription": {
    "active": true,
    "tier": {
      "id": 2,
      "name": "Premium",
      "slug": "premium"
    }
  }
}
```

Email is included only for the authenticated user making the request.

### `GET /subscription/status`

Requires authentication (session or Bearer).

Returns subscription summary for the current user (active state, tier, entitlements). Use for account screens after login.

### `GET /subscription/tiers`

Public when REST is enabled. Lists active subscription tiers with pricing and `stripe_available` flags.

## App configuration

`GET /app/config`

Public. Returns client-safe configuration for headless apps:

| Field | Description |
|-------|-------------|
| `site_name` | Blog name |
| `subscriptions_enabled` | Module active |
| `registration_enabled` | Headless register allowed |
| `login_enabled` | Login endpoint allowed |
| `payment_providers` | Enabled provider metadata |
| `stripe` | Publishable key, mode, checkout/portal endpoint URLs |
| `tiers` | Active tiers (public fields) |
| `frontend_mode` | Configured frontend mode |
| `rest_api_enabled` | REST gate |
| `api_namespace` | `mediablaster/v3` |
| `feature_flags` | Token refresh, device registration |

Secret keys are never included.

Stripe endpoint URLs in this payload point to `mediablaster/v3` paths.

## Stripe payments

Requires authenticated user (session or Bearer) unless noted.

| Method | Route | Description |
|--------|-------|-------------|
| POST | `/payments/stripe/create-checkout-session` | Start Stripe Checkout for a `tier_id` |
| POST | `/payments/stripe/create-portal-session` | Stripe Customer Portal for billing management |
| GET | `/payments/stripe/checkout-session` | Lookup session by `session_id` query param |
| POST | `/payments/stripe/webhook` | Stripe webhooks (signature verified; no login) |

Configure the Stripe Dashboard webhook URL to:

```
https://YOUR-SITE.com/wp-json/mediablaster/v3/payments/stripe/webhook
```

Other providers (PayPal, Apple, Google, Amazon) use `POST /payments/{provider}/webhook` or receipt routes as configured in admin.

See [Stripe Checkout Setup](stripe-checkout-setup.md) for Dashboard and tier Price ID setup.

## Admin statistics

Requires `manage_options`.

| Method | Route | Description |
|--------|-------|-------------|
| GET | `/stats/content` | Post counts by type and status |
| GET | `/stats/subscriptions` | Subscription totals when tables exist |
| GET | `/stats/revenue` | Placeholder (`available: false`) until revenue analytics ship |

### Content stats example

```json
{
  "counts": {
    "movies": {
      "publish": 10,
      "draft": 2,
      "pending": 0,
      "private": 0
    },
    "videos": { "publish": 5, "draft": 0, "pending": 0, "private": 0 }
  }
}
```

Revenue stats do not return fabricated amounts.

## Content access and REST

Premium rules apply to [Content API](rest-api-content.md) responses:

- `access.is_locked` and `access.user_can_access` describe entitlement state.
- `media.url` may be `null` when the viewer cannot play the item.
- Items with “hide completely” behavior may be omitted from lists unless `include_locked=true`.

Configure per-post access in the [Subscription Access metabox](metabox-subscription-access.md).

## Related guides

- [REST API Overview](rest-api-overview.md)
- [Content API and Fields](rest-api-content.md)
- [Subscriptions API and Auth](subscriptions-api-auth.md)
- [Stripe Checkout](stripe-checkout.md)
