Leaky Paywall REST API
Leaky Paywall REST API
Base URL: https://your-site.com/wp-json/leaky-paywall/v1
Prerequisites: The REST API must be enabled at Leaky Paywall → Settings → Enable REST API. All admin endpoints require HTTP Basic Auth or Application Password authentication as a WordPress admin user.
Authentication
Admin endpoints ( /subscribers, /groups) require credentials with the manage_options capability (or whatever capability is set via the manage_leaky_paywall_settings filter).
Use WordPress Application Passwords (recommended for external integrations):
Authorization: Basic base64(username:application-password)
The /me endpoint requires the user to be logged in (session cookie or Application Password for their own account).
Subscribers
List Subscribers
GET /leaky-paywall/v1/subscribers
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
Page number |
per_page |
integer | 10 |
Results per page (max 100) |
status |
string | — | Filter by payment status (e.g. active, canceled) |
level_id |
string | — | Filter by subscription level ID |
search |
string | — | Search by email or username |
Response Headers
X-WP-Total— total number of matching subscribersX-WP-TotalPages— total pages
Example
GET /wp-json/leaky-paywall/v1/subscribers?status=active&per_page=25 Authorization: Basic ...
Get a Subscriber
GET /leaky-paywall/v1/subscribers/{id}
Returns a single subscriber by WordPress user ID, plus their notes and status_log.
Example
GET /wp-json/leaky-paywall/v1/subscribers/42 Authorization: Basic ...
Errors
| Status | Code | Meaning |
|---|---|---|
404 |
rest_subscriber_not_found |
No user with that ID |
Create a Subscriber
POST /leaky-paywall/v1/subscribers
Creates a new WordPress user and activates a subscription for them. If the email already has a subscription on any level, the request is rejected with 409.
Body Parameters
| Parameter | Required | Default | Description |
|---|---|---|---|
email |
Yes | — | Valid email address |
level_id |
Yes | — | Subscription level ID (from LP Settings → Subscription Levels) |
first_name |
No | "" |
First name |
last_name |
No | "" |
Last name |
payment_status |
No | active |
available payment statuses |
payment_gateway |
No | manual |
e.g. stripe, paypal, manual |
subscriber_id |
No | "" |
Gateway-side customer/subscription ID |
plan |
No | "" |
Plan identifier (e.g. monthly, annual) |
Example
POST /wp-json/leaky-paywall/v1/subscribers Authorization: Basic ... Content-Type: application/json { "email": "[email protected]", "level_id": "1", "first_name": "John", "last_name": "Doe", "payment_gateway": "stripe", "subscriber_id": "sub_xyz789" }
Response: 201 Created with the subscriber object (same shape as Get Subscriber, including notes and status_log).
Errors
| Status | Code | Meaning |
|---|---|---|
409 |
rest_subscriber_exists |
Email already has a subscription |
400 |
rest_invalid_level |
level_id does not match any subscription level |
500 |
rest_subscriber_create_failed |
Unexpected failure creating the user |
Update a Subscriber
PUT /leaky-paywall/v1/subscribers/{id}
Updates one or more fields on an existing subscriber. Only send the fields you want to change — omitted fields are left untouched.
Body Parameters
| Parameter | Description |
|---|---|
level_id |
Move subscriber to a different level |
payment_status |
See Payment Statuses |
expires |
Expiry date/time string (e.g. 2027-01-01 00:00:00) |
subscriber_id |
Gateway-side ID |
payment_gateway |
e.g. stripe, paypal, manual |
plan |
Plan identifier |
Example
— cancel a subscriber:
PUT /wp-json/leaky-paywall/v1/subscribers/42 Authorization: Basic ... Content-Type: application/json { "payment_status": "canceled" }
Response: 200 OK with the updated subscriber object (including notes and status_log).
Errors
| Status | Code | Meaning |
|---|---|---|
404 |
rest_subscriber_not_found |
No user with that ID |
Get Current User's Subscription
GET /leaky-paywall/v1/me
Returns the subscription data for the currently authenticated user. Useful for logged-in users checking their own access from an external app.
Authentication: Requires a logged-in user (not necessarily an admin).
Response: 200 OK with the subscriber object (without notes/status_log).
Group Accounts
Requires the Leaky Paywall Group Accounts add-on (v1.7.0+).
Get a Group by Owner Email
GET /leaky-paywall/v1/groups?owner_email={email}
Looks up the group account owned by a given user.
Query Parameters
| Parameter | Required | Description |
|---|---|---|
owner_email |
Yes | Email address of the group owner |
Example
GET /wp-json/leaky-paywall/v1/[email protected] Authorization: Basic ...
Errors
| Status | Code | Meaning |
|---|---|---|
404 |
user_not_found |
No WordPress user with that email |
404 |
group_not_found |
User exists but has no group account |
Update Group Seats
PUT /leaky-paywall/v1/groups/{id}/seats
Adds to or sets the total seat count for a group account. Use the group's numeric post ID (returned by Get Group as id).
Body Parameters
| Parameter | Required | Default | Description |
|---|---|---|---|
seats |
Yes | — | Number of seats (must be > 0) |
mode |
No | add |
add — increase current seats by this amount; set — replace the total |
Example
— add 5 seats to group 101:
PUT /wp-json/leaky-paywall/v1/groups/101/seats Authorization: Basic ... Content-Type: application/json { "seats": 5 }
Example — set group 101 to exactly 30 seats:
PUT /wp-json/leaky-paywall/v1/groups/101/seats Authorization: Basic ... Content-Type: application/json { "seats": 30, "mode": "set" }
Response: 200 OK with the updated group object
Errors
| Status | Code | Meaning |
|---|---|---|
404 |
group_not_found |
No lp_group_account post with that ID |
Common Patterns
Create a subscriber and add them to a group
There's no single endpoint that does both. The typical flow from an external site:
- POST
/subscribers— create the subscriber with the group-levellevel_id - GET
/groups?owner_email=...— retrieve the group ID - PUT
/groups/{id}/seats— add a seat if needed (group account membership itself is managed within WordPress/LP once the user logs in and claims their seat)
Check available payment statuses
Valid values for payment_status:
activepending_canceltrialtrialingpast_dueunpaidincompleteincomplete_expiredpausedcanceledexpiredpending_activationrenewal_dueon_holdgrace_perioddeactivated
Error Response Format
All errors follow the standard WordPress REST API format:
{ "code": "rest_subscriber_not_found", "message": "Subscriber not found.", "data": { "status": 404 } }