Attach an already-verified Stripe payment method and start a subscription, no browser required
POST
/
v1
/
billing
/
stripe
/
subscriptions
/
headless
Attach an already-verified Stripe payment method and start a subscription, no browser required
curl --request POST \
--url https://api.kerne.io/v1/billing/stripe/subscriptions/headless \
--header 'Content-Type: application/json' \
--header 'x-app-id: <api-key>' \
--data '
{
"customer": "<string>",
"plan_price_id": "<string>",
"stripe_payment_method_id": "<string>",
"stripe_test_card_token": "<string>",
"email": "<string>"
}
'import requests
url = "https://api.kerne.io/v1/billing/stripe/subscriptions/headless"
payload = {
"customer": "<string>",
"plan_price_id": "<string>",
"stripe_payment_method_id": "<string>",
"stripe_test_card_token": "<string>",
"email": "<string>"
}
headers = {
"x-app-id": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-app-id': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
customer: '<string>',
plan_price_id: '<string>',
stripe_payment_method_id: '<string>',
stripe_test_card_token: '<string>',
email: '<string>'
})
};
fetch('https://api.kerne.io/v1/billing/stripe/subscriptions/headless', 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.kerne.io/v1/billing/stripe/subscriptions/headless",
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([
'customer' => '<string>',
'plan_price_id' => '<string>',
'stripe_payment_method_id' => '<string>',
'stripe_test_card_token' => '<string>',
'email' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-app-id: <api-key>"
],
]);
$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.kerne.io/v1/billing/stripe/subscriptions/headless"
payload := strings.NewReader("{\n \"customer\": \"<string>\",\n \"plan_price_id\": \"<string>\",\n \"stripe_payment_method_id\": \"<string>\",\n \"stripe_test_card_token\": \"<string>\",\n \"email\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-app-id", "<api-key>")
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.kerne.io/v1/billing/stripe/subscriptions/headless")
.header("x-app-id", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customer\": \"<string>\",\n \"plan_price_id\": \"<string>\",\n \"stripe_payment_method_id\": \"<string>\",\n \"stripe_test_card_token\": \"<string>\",\n \"email\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kerne.io/v1/billing/stripe/subscriptions/headless")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-app-id"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"customer\": \"<string>\",\n \"plan_price_id\": \"<string>\",\n \"stripe_payment_method_id\": \"<string>\",\n \"stripe_test_card_token\": \"<string>\",\n \"email\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"tenant_id": "<string>",
"customer": {
"id": "<string>",
"external_id": "<string>",
"email": "<string>",
"name": "<string>"
},
"plan_price_id": "<string>",
"pack_id": "<string>",
"pending_plan_price_id": "<string>",
"pending_pack_id": "<string>",
"provider": "STRIPE",
"provider_subscription_id": "<string>",
"provider_customer_id": "<string>",
"status": "ACTIVE",
"current_period_start": "2023-11-07T05:31:56Z",
"current_period_end": "2023-11-07T05:31:56Z",
"trial_start": "2023-11-07T05:31:56Z",
"trial_end": "2023-11-07T05:31:56Z",
"canceled_at": "2023-11-07T05:31:56Z",
"ended_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"plan": {
"id": "<string>",
"slug": "<string>",
"name": "<string>"
},
"plan_price": {
"id": "<string>",
"amount": 123,
"currency": "<string>",
"interval": "<string>",
"price_label_name": "<string>",
"price_label_slug": "<string>"
},
"product": {
"id": "<string>",
"slug": "<string>",
"name": "<string>"
},
"pack": {
"id": "<string>",
"version": 123,
"status": "DRAFT"
},
"entitlements": [
{
"feature_id": "<string>",
"feature_key": "<string>",
"feature_name": "<string>",
"feature_type": "<string>",
"feature_unit_label": "<string>",
"limit": 123,
"value": "<string>",
"overage": "BLOCK",
"limit_binding": "CUSTOMER",
"cap_binding": "CUSTOMER",
"max_dimensions": 123,
"overage_ceiling": "<string>",
"overage_cap_amount": 123,
"billed_amount": 123,
"currency": "<string>",
"cap_reached": true
}
]
}Authorizations
AppIdentifierJWT
App identifier (App.id, sent as the x-app-id header)
Body
application/json
A Stripe test card token (e.g. "tok_visa") to mint a fresh payment method server-side - the cold-start path for CI/seed scripts with no browser. Stripe test mode only; rejected otherwise. See stripe_payment_method_id for the normal path.
Required the first time this customer is named with no email on file yet.
Response
201 - application/json
Show child attributes
Show child attributes
Available options:
STRIPE, POLAR Available options:
ACTIVE, TRIALING, PAST_DUE, CANCELED, UNPAID, PAUSED Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
⌘I
Attach an already-verified Stripe payment method and start a subscription, no browser required
curl --request POST \
--url https://api.kerne.io/v1/billing/stripe/subscriptions/headless \
--header 'Content-Type: application/json' \
--header 'x-app-id: <api-key>' \
--data '
{
"customer": "<string>",
"plan_price_id": "<string>",
"stripe_payment_method_id": "<string>",
"stripe_test_card_token": "<string>",
"email": "<string>"
}
'import requests
url = "https://api.kerne.io/v1/billing/stripe/subscriptions/headless"
payload = {
"customer": "<string>",
"plan_price_id": "<string>",
"stripe_payment_method_id": "<string>",
"stripe_test_card_token": "<string>",
"email": "<string>"
}
headers = {
"x-app-id": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-app-id': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
customer: '<string>',
plan_price_id: '<string>',
stripe_payment_method_id: '<string>',
stripe_test_card_token: '<string>',
email: '<string>'
})
};
fetch('https://api.kerne.io/v1/billing/stripe/subscriptions/headless', 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.kerne.io/v1/billing/stripe/subscriptions/headless",
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([
'customer' => '<string>',
'plan_price_id' => '<string>',
'stripe_payment_method_id' => '<string>',
'stripe_test_card_token' => '<string>',
'email' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-app-id: <api-key>"
],
]);
$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.kerne.io/v1/billing/stripe/subscriptions/headless"
payload := strings.NewReader("{\n \"customer\": \"<string>\",\n \"plan_price_id\": \"<string>\",\n \"stripe_payment_method_id\": \"<string>\",\n \"stripe_test_card_token\": \"<string>\",\n \"email\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-app-id", "<api-key>")
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.kerne.io/v1/billing/stripe/subscriptions/headless")
.header("x-app-id", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customer\": \"<string>\",\n \"plan_price_id\": \"<string>\",\n \"stripe_payment_method_id\": \"<string>\",\n \"stripe_test_card_token\": \"<string>\",\n \"email\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kerne.io/v1/billing/stripe/subscriptions/headless")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-app-id"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"customer\": \"<string>\",\n \"plan_price_id\": \"<string>\",\n \"stripe_payment_method_id\": \"<string>\",\n \"stripe_test_card_token\": \"<string>\",\n \"email\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"tenant_id": "<string>",
"customer": {
"id": "<string>",
"external_id": "<string>",
"email": "<string>",
"name": "<string>"
},
"plan_price_id": "<string>",
"pack_id": "<string>",
"pending_plan_price_id": "<string>",
"pending_pack_id": "<string>",
"provider": "STRIPE",
"provider_subscription_id": "<string>",
"provider_customer_id": "<string>",
"status": "ACTIVE",
"current_period_start": "2023-11-07T05:31:56Z",
"current_period_end": "2023-11-07T05:31:56Z",
"trial_start": "2023-11-07T05:31:56Z",
"trial_end": "2023-11-07T05:31:56Z",
"canceled_at": "2023-11-07T05:31:56Z",
"ended_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"plan": {
"id": "<string>",
"slug": "<string>",
"name": "<string>"
},
"plan_price": {
"id": "<string>",
"amount": 123,
"currency": "<string>",
"interval": "<string>",
"price_label_name": "<string>",
"price_label_slug": "<string>"
},
"product": {
"id": "<string>",
"slug": "<string>",
"name": "<string>"
},
"pack": {
"id": "<string>",
"version": 123,
"status": "DRAFT"
},
"entitlements": [
{
"feature_id": "<string>",
"feature_key": "<string>",
"feature_name": "<string>",
"feature_type": "<string>",
"feature_unit_label": "<string>",
"limit": 123,
"value": "<string>",
"overage": "BLOCK",
"limit_binding": "CUSTOMER",
"cap_binding": "CUSTOMER",
"max_dimensions": 123,
"overage_ceiling": "<string>",
"overage_cap_amount": 123,
"billed_amount": 123,
"currency": "<string>",
"cap_reached": true
}
]
}
