Skip to content

Create Subscription

POST
/api/Subscriptions
curl --request POST \
--url https://example.com/api/Subscriptions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: example' \
--data '{ "merchantId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "memberId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "planId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "paymentMethodId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "startDate": "2026-04-15T12:00:00Z", "partnerRef": "example" }'

Enrols a member in a plan and creates the recurring subscription at the payment gateway. If the plan has trial days, the subscription starts in Trial status. Otherwise it starts Active.

Not needed after hosted checkout. Checkout already creates the member, payment method and subscription; store data.subscriptionId from the checkout.completed webhook instead. Calling this for a member who already has a live subscription to the plan with the same partnerRef returns 409.

partnerRef is optional: your own id for who the subscription is for (e.g. a child). One member may hold one live subscription per plan and partner ref, so two siblings can share a plan under different refs.

POST /api/subscriptions
{
    "merchantId": "...",
    "memberId": "...",
    "planId": "...",
    "paymentMethodId": "...",
    "partnerRef": "child-123"
}
Idempotency-Key
required
string
<= 255 characters

Required. A unique value (a UUID is ideal) per logical operation; reuse it when retrying that operation. A retry with the same key and body replays the original response instead of running twice. A 4xx frees the key, so the operation can be corrected and retried on it. A 5xx does not: the attempt may already have moved money, so retries with that key replay a problem+json saying the outcome is unknown, and a genuinely fresh attempt needs a new key. Missing → 400.

Subscription creation payload.

object
merchantId
required
string format: uuid
memberId
required
string format: uuid
planId
required
string format: uuid
paymentMethodId
string format: uuid
nullable
startDate
string format: date-time
nullable
partnerRef
string
nullable <= 200 characters
Example generated
{
"merchantId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"memberId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"planId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"paymentMethodId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"startDate": "2026-04-15T12:00:00Z",
"partnerRef": "example"
}

Subscription created successfully.

Media type application/json
object
id
string format: uuid
merchantId
string format: uuid
memberId
string format: uuid
memberName
string
nullable
planId
string format: uuid
planName
string
nullable
planFrequency
string
Allowed values: OneOff Daily Weekly Fortnightly Monthly Quarterly Yearly
planPrice
number format: double
paymentMethodId
string format: uuid
nullable
status
string
Allowed values: Trial Active PastDue Paused Cancelled
startDate
string format: date-time
trialEndsAt
string format: date-time
nullable
nextBillingDate
string format: date-time
nullable
nextBillingAmount
number format: double
nullable
pausedAt
string format: date-time
nullable
cancelledAt
string format: date-time
nullable
cancellationReason
string
nullable
createdAt
string format: date-time
updatedAt
string format: date-time
recentCycles
Array<object>
nullable
object
id
string format: uuid
periodStart
string format: date-time
periodEnd
string format: date-time
amount
number format: double
currency
string
nullable
status
string
Allowed values: Pending AwaitingSettlement Paid Failed WrittenOff OverCollected
attemptNumber
integer format: int32
nextActionAt
string format: date-time
nullable
lastDeclineCode
string
nullable
createdAt
string format: date-time
partnerRef
string
nullable
Example
{
"planFrequency": "OneOff",
"status": "Trial",
"recentCycles": [
{
"status": "Pending"
}
]
}

Validation failed - check the errors object - or the Idempotency-Key header is missing.

Media type application/json
object
type
string
nullable
title
string
nullable
status
integer format: int32
nullable
detail
string
nullable
instance
string
nullable
key
additional properties
Example generated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

The plan’s setup fee was declined. Nothing was created and no money moved; retry with another payment method.

Media type application/json
object
type
string
nullable
title
string
nullable
status
integer format: int32
nullable
detail
string
nullable
instance
string
nullable
key
additional properties
Example generated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

The member already has a live (non-cancelled) subscription to this plan with the same partnerRef; existingSubscriptionId identifies it. Hosted checkout creates the subscription itself, so don’t call this on checkout.completed.

Media type application/json
object
type
string
nullable
title
string
nullable
status
integer format: int32
nullable
detail
string
nullable
instance
string
nullable
key
additional properties
Example generated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}