Quick Start
List all recurring plans for a merchant:data array of plan objects and a pagination object. To fetch one specific plan instead, include planId in the query string.
The Basics
| What | Value |
|---|---|
| Method | GET |
| URL | https://payapi.v2.ozurapay.com/api/v1/recurring/plans |
| Called From | Your server (never from browser JavaScript) |
Never call this from the browser. Your API key must stay on the server.
Use a backend (Node.js, Python, PHP, etc.) to query plans and pass the results
to your frontend.
Required Headers
Merchant API Key (
x-api-key): Developers → API Keys.The key must have read access to recurring plans enabled.Single Plan vs. List
This endpoint operates in two modes, controlled by whetherplanId is in the query string:
- List mode — Omit
planId. Returns a paginated array of plans matching your filters. - Single-plan mode — Provide
planId. Returns one plan in the same shape as list mode. Returns404if no plan matches.
data is always an array, even when you query a single plan (it’ll contain exactly one element).
Hierarchy ID (Required)
Every request must include exactly one of the following IDs in the query string, scoping the query to a level of your hierarchy:| Parameter | Description |
|---|---|
merchantId | Query plans owned by a single merchant |
agentId | Query plans across all merchants under an agent |
isvId | Query plans across all merchants under an ISV |
isoId | Query plans across all merchants under an ISO |
groupId | Query plans across an entire group |
400 error. Which IDs you’re allowed to query depends on your role — see Who Can Query What below.
Who Can Query What
Your API key’s role determines which hierarchy IDs you can use:| Your role | Hierarchy IDs you can query |
|---|---|
merchant | merchantId (your own only) |
agent | merchantId, agentId (within your hierarchy) |
isv | merchantId, agentId, isvId (within your hierarchy) |
iso | merchantId, agentId, isvId, isoId (within your hierarchy) |
group | merchantId, agentId, isvId, isoId, groupId (within your hierarchy) |
403 error.
A future “Authentication & Access” guide will document hierarchy rules in
full. Until then, treat this section as the canonical reference.
Optional Query Parameters
All filters are optional and can be combined.Filters
| Parameter | Type | Description | Example |
|---|---|---|---|
planId | string | Look up one specific plan by ID. Switches the endpoint into single-plan mode. | "RP2606020000167A143" |
status | string | Filter by lifecycle state — see RecurringPlanStatus | "active" |
interval | string | Filter by billing cadence — see RecurringInterval | "monthly" |
processor | string | Filter by underlying processor (elavon, nuvei, worldpay) | "elavon" |
dateFrom | string | ISO 8601 — return plans created on or after this date | "2025-01-01T00:00:00.000Z" |
dateTo | string | ISO 8601 — return plans created on or before this date | "2025-12-31T23:59:59.999Z" |
nextChargeBefore | string | ISO 8601 — return plans with their next scheduled charge on or before this date | "2026-06-09T00:00:00.000Z" |
nextChargeAfter | string | ISO 8601 — return plans with their next scheduled charge on or after this date | "2026-06-02T00:00:00.000Z" |
Pagination & Sorting
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Which page of results to return |
limit | number | 50 | Results per page. Maximum 100 |
sortBy | string | createdAt | Field to sort by |
sortOrder | string | desc | asc (oldest first) or desc (newest first) |
Field Selection
| Parameter | Type | Description |
|---|---|---|
fields | string | Comma-separated list of fields to return. See Custom Fields. |
Custom Fields
By default, the endpoint returns a curated set of fields depending on whether you’re in list mode or single-plan mode. To request only specific fields, passfields as a comma-separated list:
Some fields are restricted to administrators and will be silently omitted if
you request them. If every field you request is restricted, the response is a
400 error.Enums
RecurringPlanStatus
The lifecycle state of a plan, returned in every plan response.| Value | Meaning |
|---|---|
active | Plan is running and will bill on schedule |
paused | Billing is temporarily halted; can be resumed |
cancelled | Plan has been permanently stopped |
completed | All scheduled cycles have been charged, or maxCycles was reached |
failed | Exhausted all retries on a cycle. Needs merchant attention |
RecurringInterval
| Value | Description |
|---|---|
daily | Charge every day |
weekly | Charge every week |
monthly | Charge every month |
yearly | Charge every year |
Response
The response shape is the same in both list and single-plan modes:Response Shape
The response shape is identical for list mode and single-plan mode —data is always an array of plan objects. Single-plan mode just returns one element.
Example
A query for a single plan, returning the full plan object:Field Notes
| Field | What It Is |
|---|---|
status | Current lifecycle state — see RecurringPlanStatus |
nextChargeAt | When the worker will next attempt to charge — may be a retry time after a failed attempt |
nextCycleAt | The true next billing date — never moves during retries within a cycle |
cycleCount | How many successful cycles have charged so far |
totalCharged | Cumulative sum of all successful cycles |
totalRefunded | Cumulative sum of all refunds against this plan’s transactions |
lastAttemptId | The ID of the most recent attempt (success or failure) |
initialPricingConfig | If set, the trial/setup-fee config defined at plan creation; null otherwise |
citTransactionId | Transaction ID of the initial CIT charge made at plan creation |
pausedAt / cancelledAt / failedAt / completedAt | Lifecycle timestamps — populated only when the plan reaches the corresponding state |
Common Use Cases
Fetch a single plan
List only active plans
List plans charging in the next 7 days
Useful for “upcoming charges” dashboard views. Combinestatus=active with a nextChargeBefore cutoff: