Skip to main content
The Kulmi Pay Subscriptions API lets you automate recurring card billing for your customers. You define a billing plan, register the customers you want to bill, and create subscriptions that link each customer to a plan. Kulmi Pay then handles automatic charge attempts on the billing schedule, retries on failure, and fires webhook events as each billing cycle completes. Subscriptions work with three entities that you manage via the API:
  • Plans define the billing amount, currency, frequency, and total number of cycles.
  • Customers hold your end-user’s contact and billing details.
  • Subscriptions link a customer to a plan and track the current billing status.

Step 1: Create a plan

A plan defines what you charge, how often, and for how long. POST /api/v1/subscriptions/plans/
Request
{
  "name": "Pro Monthly",
  "amount": "2999.00",
  "currency": "KES",
  "frequency": 1,
  "frequency_unit": "M",
  "billing_cycles": 12
}
FieldTypeDescription
namestringUnique name for the plan within your account
amountdecimalAmount to charge each billing cycle
currencystring3-letter ISO currency code (e.g. KES, USD)
frequencyintegerHow many units between each billing cycle
frequency_unitstringD (day), W (week), M (month), or Y (year)
billing_cyclesintegerTotal number of times to bill the customer
Response
{
  "id": "pln_abc123",
  "name": "Pro Monthly",
  "amount": "2999.00",
  "currency": "KES",
  "frequency": 1,
  "frequency_unit": "M",
  "billing_cycles": 12,
  "created_at": "2024-01-15T10:00:00Z"
}
If you POST a plan with a name that already exists on your account, Kulmi Pay updates the existing plan instead of creating a duplicate.

Step 2: Create a customer

A customer record stores the details of the person you want to bill. POST /api/v1/subscriptions/customers/
Request
{
  "email": "jane.doe@example.com",
  "first_name": "Jane",
  "last_name": "Doe",
  "phone_number": "254712345678"
}
FieldTypeDescription
emailstringCustomer’s email address (unique per account)
first_namestringCustomer’s first name
last_namestringCustomer’s last name
phone_numberstringCustomer’s phone number (optional)
Response
{
  "id": "cus_xyz789",
  "email": "jane.doe@example.com",
  "first_name": "Jane",
  "last_name": "Doe",
  "phone_number": "254712345678",
  "created_at": "2024-01-15T10:05:00Z"
}
If you create a customer with an email that already exists on your account, Kulmi Pay updates the existing record rather than returning an error.

Step 3: Create a subscription

Link a customer to a plan to start the billing cycle. POST /api/v1/subscriptions/subscriptions/
Request
{
  "plan_id": "pln_abc123",
  "customer_id": "cus_xyz789",
  "start_date": "2024-02-01"
}
FieldTypeDescription
plan_idstringThe id of the plan to use
customer_idstringThe id of the customer to bill
start_datestringISO 8601 date for the first billing attempt (YYYY-MM-DD). Must not be in the past.
Response
{
  "id": "sub_def321",
  "status": "PENDING",
  "plan": {
    "id": "pln_abc123",
    "name": "Pro Monthly",
    "amount": "2999.00",
    "currency": "KES"
  },
  "customer": {
    "id": "cus_xyz789",
    "email": "jane.doe@example.com"
  },
  "start_date": "2024-02-01",
  "next_date": "2024-02-01",
  "completed_cycles": 0,
  "created_at": "2024-01-15T10:10:00Z"
}
The subscription starts in PENDING status. Once the customer completes the initial card enrollment step, the status moves to ACTIVE and Kulmi Pay begins billing automatically on the plan’s schedule. Subscription statuses:
StatusMeaning
PENDINGSubscription created, awaiting card enrollment
ACTIVECard enrolled, billing is running
COMPLETEAll billing cycles have been successfully charged
CANCELEDSubscription was cancelled by you or the customer
FAILEDThe most recent billing attempt failed

Step 4: Monitor payment history

Retrieve a list of all payment attempts for a subscription. GET /api/v1/subscriptions/subscriptions//transactions/
Response
[
  {
    "id": "pay_001",
    "status": "SUCCESS",
    "amount": "2999.00",
    "currency": "KES",
    "created_at": "2024-02-01T10:00:00Z"
  },
  {
    "id": "pay_002",
    "status": "SUCCESS",
    "amount": "2999.00",
    "currency": "KES",
    "created_at": "2024-03-01T10:00:00Z"
  }
]
Each entry corresponds to one billing cycle attempt. The status field is SUCCESS, PROCESSING, or FAILED.

Cancel a subscription

Send a POST request to cancel an active subscription immediately. No further billing cycles will be attempted. POST /api/v1/subscriptions/subscriptions//unsubscribe/
Response
{
  "id": "sub_def321",
  "status": "CANCELED",
  "completed_cycles": 3,
  "updated_at": "2024-04-15T09:00:00Z"
}
Cancellation is immediate and irreversible via the API. To resume billing you would need to create a new subscription.

List and manage resources

EndpointMethodDescription
/api/v1/subscriptions/plans/GETList all plans
/api/v1/subscriptions/plans/POSTCreate or update a plan
/api/v1/subscriptions/customers/GETList all customers
/api/v1/subscriptions/customers/POSTCreate or update a customer
/api/v1/subscriptions/subscriptions/GETList all subscriptions
/api/v1/subscriptions/subscriptions/POSTCreate a subscription
/api/v1/subscriptions/subscriptions/{id}/unsubscribe/POSTCancel a subscription
/api/v1/subscriptions/subscriptions/{id}/transactions/GETList payment history
Kulmi Pay fires a subscription_event webhook each time a subscription’s status changes or a billing cycle completes. Enable this event on your webhook to stay in sync without polling. See Webhook event types for payload details.