curl --request POST \
--url https://api.spotflow.co/api/v1/plans \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "Standard Monthly Plan",
"cycleCount": "3",
"retrial": "3",
"endDate": "2026-10-29",
"internalReference": "PLAN-STD-001",
"pricingOptions": [
{
"amount": 123,
"currency": "NGN"
}
],
"trial": {
"periodInDays": 0,
"pricingList": [
{
"amount": 123,
"currency": "NGN"
}
]
}
}
'import requests
url = "https://api.spotflow.co/api/v1/plans"
payload = {
"title": "Standard Monthly Plan",
"cycleCount": "3",
"retrial": "3",
"endDate": "2026-10-29",
"internalReference": "PLAN-STD-001",
"pricingOptions": [
{
"amount": 123,
"currency": "NGN"
}
],
"trial": {
"periodInDays": 0,
"pricingList": [
{
"amount": 123,
"currency": "NGN"
}
]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
title: 'Standard Monthly Plan',
cycleCount: '3',
retrial: '3',
endDate: '2026-10-29',
internalReference: 'PLAN-STD-001',
pricingOptions: [{amount: 123, currency: 'NGN'}],
trial: {periodInDays: 0, pricingList: [{amount: 123, currency: 'NGN'}]}
})
};
fetch('https://api.spotflow.co/api/v1/plans', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.spotflow.co/api/v1/plans",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Standard Monthly Plan',
'cycleCount' => '3',
'retrial' => '3',
'endDate' => '2026-10-29',
'internalReference' => 'PLAN-STD-001',
'pricingOptions' => [
[
'amount' => 123,
'currency' => 'NGN'
]
],
'trial' => [
'periodInDays' => 0,
'pricingList' => [
[
'amount' => 123,
'currency' => 'NGN'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.spotflow.co/api/v1/plans"
payload := strings.NewReader("{\n \"title\": \"Standard Monthly Plan\",\n \"cycleCount\": \"3\",\n \"retrial\": \"3\",\n \"endDate\": \"2026-10-29\",\n \"internalReference\": \"PLAN-STD-001\",\n \"pricingOptions\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ],\n \"trial\": {\n \"periodInDays\": 0,\n \"pricingList\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.spotflow.co/api/v1/plans")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"Standard Monthly Plan\",\n \"cycleCount\": \"3\",\n \"retrial\": \"3\",\n \"endDate\": \"2026-10-29\",\n \"internalReference\": \"PLAN-STD-001\",\n \"pricingOptions\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ],\n \"trial\": {\n \"periodInDays\": 0,\n \"pricingList\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.spotflow.co/api/v1/plans")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"title\": \"Standard Monthly Plan\",\n \"cycleCount\": \"3\",\n \"retrial\": \"3\",\n \"endDate\": \"2026-10-29\",\n \"internalReference\": \"PLAN-STD-001\",\n \"pricingOptions\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ],\n \"trial\": {\n \"periodInDays\": 0,\n \"pricingList\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body[
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"title": "string",
"frequency": "DAILY",
"amount": 123,
"currency": "NGN",
"status": "ACTIVE",
"createdAt": "2023-11-07T05:31:56Z",
"internalReference": "string",
"regions": [
"<string>"
],
"subscribers": 123,
"subscriptions": 123,
"trial": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"planId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"periodInDays": 123,
"pricingList": [
{
"type": "FLAT",
"amount": 123,
"currency": "NGN"
}
]
},
"pricingOptions": [
{
"amount": 123,
"currency": "NGN"
}
]
}
]{
"error": "Missing Parameter",
"message": "missing_parameter",
"status": 400
}{
"message": "Authorization token is required.",
"statusCode": 401,
"code": "AUTH_ERROR",
"requestMarker": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}Create Single Plan
Create a subscription plan under your integration.
curl --request POST \
--url https://api.spotflow.co/api/v1/plans \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "Standard Monthly Plan",
"cycleCount": "3",
"retrial": "3",
"endDate": "2026-10-29",
"internalReference": "PLAN-STD-001",
"pricingOptions": [
{
"amount": 123,
"currency": "NGN"
}
],
"trial": {
"periodInDays": 0,
"pricingList": [
{
"amount": 123,
"currency": "NGN"
}
]
}
}
'import requests
url = "https://api.spotflow.co/api/v1/plans"
payload = {
"title": "Standard Monthly Plan",
"cycleCount": "3",
"retrial": "3",
"endDate": "2026-10-29",
"internalReference": "PLAN-STD-001",
"pricingOptions": [
{
"amount": 123,
"currency": "NGN"
}
],
"trial": {
"periodInDays": 0,
"pricingList": [
{
"amount": 123,
"currency": "NGN"
}
]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
title: 'Standard Monthly Plan',
cycleCount: '3',
retrial: '3',
endDate: '2026-10-29',
internalReference: 'PLAN-STD-001',
pricingOptions: [{amount: 123, currency: 'NGN'}],
trial: {periodInDays: 0, pricingList: [{amount: 123, currency: 'NGN'}]}
})
};
fetch('https://api.spotflow.co/api/v1/plans', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.spotflow.co/api/v1/plans",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Standard Monthly Plan',
'cycleCount' => '3',
'retrial' => '3',
'endDate' => '2026-10-29',
'internalReference' => 'PLAN-STD-001',
'pricingOptions' => [
[
'amount' => 123,
'currency' => 'NGN'
]
],
'trial' => [
'periodInDays' => 0,
'pricingList' => [
[
'amount' => 123,
'currency' => 'NGN'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.spotflow.co/api/v1/plans"
payload := strings.NewReader("{\n \"title\": \"Standard Monthly Plan\",\n \"cycleCount\": \"3\",\n \"retrial\": \"3\",\n \"endDate\": \"2026-10-29\",\n \"internalReference\": \"PLAN-STD-001\",\n \"pricingOptions\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ],\n \"trial\": {\n \"periodInDays\": 0,\n \"pricingList\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.spotflow.co/api/v1/plans")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"Standard Monthly Plan\",\n \"cycleCount\": \"3\",\n \"retrial\": \"3\",\n \"endDate\": \"2026-10-29\",\n \"internalReference\": \"PLAN-STD-001\",\n \"pricingOptions\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ],\n \"trial\": {\n \"periodInDays\": 0,\n \"pricingList\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.spotflow.co/api/v1/plans")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"title\": \"Standard Monthly Plan\",\n \"cycleCount\": \"3\",\n \"retrial\": \"3\",\n \"endDate\": \"2026-10-29\",\n \"internalReference\": \"PLAN-STD-001\",\n \"pricingOptions\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ],\n \"trial\": {\n \"periodInDays\": 0,\n \"pricingList\": [\n {\n \"amount\": 123,\n \"currency\": \"NGN\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body[
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"title": "string",
"frequency": "DAILY",
"amount": 123,
"currency": "NGN",
"status": "ACTIVE",
"createdAt": "2023-11-07T05:31:56Z",
"internalReference": "string",
"regions": [
"<string>"
],
"subscribers": 123,
"subscriptions": 123,
"trial": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"planId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"periodInDays": 123,
"pricingList": [
{
"type": "FLAT",
"amount": 123,
"currency": "NGN"
}
]
},
"pricingOptions": [
{
"amount": 123,
"currency": "NGN"
}
]
}
]{
"error": "Missing Parameter",
"message": "missing_parameter",
"status": 400
}{
"message": "Authorization token is required.",
"statusCode": 401,
"code": "AUTH_ERROR",
"requestMarker": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}Mobile Money
mobile_moneypayment and a planId is included, Spotflow will automatically send a mandate approval request to the customer’s phone. The subscription will only activate once the mandate is approved.See the full guide on Mobile Money Subscriptions.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Name or title of the plan
"Standard Monthly Plan"
Maximum billing cycles before the plan completes
"3"
Note that retrial only applies to card subscriptions, not mobile money. Retry count for failed card payments.
"3"
The date all subscription cycles end
"2026-10-29"
Billing frequency for the plan
DAILY, WEEKLY, MONTHLY, QUARTERLY, ANNUAL Internal reference code for the plan
"PLAN-STD-001"
Pricing options for the plan
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Response
A JSON array of subscription objects.
Unique identifier of the subscription plan (UUID).
The title or name of the subscription plan.
"string"
Billing frequency for the subscription plan.
DAILY, WEEKLY, MONTHLY, QUARTERLY, BIANNUAL, ANNUAL The cost amount for the subscription plan.
The currency of the subscription plan (e.g., NGN, USD).
"NGN"
The current status of the subscription plan.
ACTIVE, INACTIVE, ARCHIVED Date and time when the plan was created.
Internal reference code or identifier for the plan.
"string"
List of regions where this plan is available.
Total number of active subscribers under this plan.
Total number of subscriptions created for this plan.
Details about the trial period associated with this plan.
Show child attributes
Show child attributes
Different pricing options available for the plan.
Show child attributes
Show child attributes

