Retrieve a subscription
curl --request GET \
--url https://bouclay.com/api/v1/subscriptions/{subscription} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://bouclay.com/api/v1/subscriptions/{subscription}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://bouclay.com/api/v1/subscriptions/{subscription}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://bouclay.com/api/v1/subscriptions/{subscription}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"data": {
"id": "<string>",
"planId": "<string>",
"status": "<string>",
"pauseReason": "requested",
"pauseResumesAt": "2023-11-07T05:31:56Z",
"currency": "<string>",
"collectionMode": "automatic",
"daysUntilDue": 123,
"reference": "<string>",
"invoicingThreshold": 1,
"minimumCommitment": 1,
"spendingCap": {
"amount": 1,
"covers": "usage",
"behavior": "cap",
"warnAt": [
123
],
"since": "2023-11-07T05:31:56Z"
},
"trialEndsAt": "2023-11-07T05:31:56Z",
"currentPeriodStart": "2023-11-07T05:31:56Z",
"currentPeriodEnd": "2023-11-07T05:31:56Z",
"canceledAt": "2023-11-07T05:31:56Z",
"endsAt": "2023-11-07T05:31:56Z",
"cancellationDetails": {
"reason": "<string>",
"comment": "<string>",
"source": "portal"
},
"customer": {
"id": "<string>",
"email": "jsmith@example.com",
"name": "<string>",
"taxId": "<string>"
},
"discount": {
"id": "<string>",
"code": "<string>",
"remainingIntervals": 123
},
"createdAt": "2023-11-07T05:31:56Z",
"trialEndBehavior": "<string>",
"paymentMethod": {
"id": "<string>"
},
"items": [
{
"id": "<string>",
"productId": "<string>",
"planId": "<string>",
"chargeId": "<string>",
"priceId": "<string>",
"quantity": 123,
"status": "<string>"
}
],
"scheduledChanges": [
{
"action": "cancel",
"effectiveAt": "2023-11-07T05:31:56Z",
"itemId": "si_123",
"quantity": 2,
"priceId": "<string>",
"remove": true,
"planId": "<string>",
"chargeId": "<string>",
"resumesAt": "2023-11-07T05:31:56Z"
}
],
"sharedMeters": [
{
"meterId": "<string>",
"meterName": "<string>",
"subscriptionIds": [
"<string>"
]
}
]
},
"meta": {
"requestId": "req_550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"type": "request_error",
"code": "authentication_failed",
"detail": "<string>",
"errors": [
{
"field": "<string>",
"message": "<string>"
}
]
},
"meta": {
"requestId": "req_550e8400-e29b-41d4-a716-446655440000"
}
}Subscriptions
Retrieve a subscription
GET
/
subscriptions
/
{subscription}
Retrieve a subscription
curl --request GET \
--url https://bouclay.com/api/v1/subscriptions/{subscription} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://bouclay.com/api/v1/subscriptions/{subscription}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://bouclay.com/api/v1/subscriptions/{subscription}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://bouclay.com/api/v1/subscriptions/{subscription}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"data": {
"id": "<string>",
"planId": "<string>",
"status": "<string>",
"pauseReason": "requested",
"pauseResumesAt": "2023-11-07T05:31:56Z",
"currency": "<string>",
"collectionMode": "automatic",
"daysUntilDue": 123,
"reference": "<string>",
"invoicingThreshold": 1,
"minimumCommitment": 1,
"spendingCap": {
"amount": 1,
"covers": "usage",
"behavior": "cap",
"warnAt": [
123
],
"since": "2023-11-07T05:31:56Z"
},
"trialEndsAt": "2023-11-07T05:31:56Z",
"currentPeriodStart": "2023-11-07T05:31:56Z",
"currentPeriodEnd": "2023-11-07T05:31:56Z",
"canceledAt": "2023-11-07T05:31:56Z",
"endsAt": "2023-11-07T05:31:56Z",
"cancellationDetails": {
"reason": "<string>",
"comment": "<string>",
"source": "portal"
},
"customer": {
"id": "<string>",
"email": "jsmith@example.com",
"name": "<string>",
"taxId": "<string>"
},
"discount": {
"id": "<string>",
"code": "<string>",
"remainingIntervals": 123
},
"createdAt": "2023-11-07T05:31:56Z",
"trialEndBehavior": "<string>",
"paymentMethod": {
"id": "<string>"
},
"items": [
{
"id": "<string>",
"productId": "<string>",
"planId": "<string>",
"chargeId": "<string>",
"priceId": "<string>",
"quantity": 123,
"status": "<string>"
}
],
"scheduledChanges": [
{
"action": "cancel",
"effectiveAt": "2023-11-07T05:31:56Z",
"itemId": "si_123",
"quantity": 2,
"priceId": "<string>",
"remove": true,
"planId": "<string>",
"chargeId": "<string>",
"resumesAt": "2023-11-07T05:31:56Z"
}
],
"sharedMeters": [
{
"meterId": "<string>",
"meterName": "<string>",
"subscriptionIds": [
"<string>"
]
}
]
},
"meta": {
"requestId": "req_550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"type": "request_error",
"code": "authentication_failed",
"detail": "<string>",
"errors": [
{
"field": "<string>",
"message": "<string>"
}
]
},
"meta": {
"requestId": "req_550e8400-e29b-41d4-a716-446655440000"
}
}Authorizations
Use a Bouclay secret key (sk_test_..., sk_live_...) or restricted key
(rk_test_..., rk_live_...).
A secret key can call every endpoint. A restricted key can only call the
endpoints its scopes cover. A scope is {resource}:{access}, for example
customers:read or refunds:write, and write includes read. GET
requests need read access and everything else needs write, except
POST /subscriptions/{id}/items/{item}/preview, which only needs
subscriptions:read. A request outside the key's scopes gets 403 permission_denied naming the missing scope, and its Idempotency-Key
is not used up.
| Resource | Endpoints | Access |
|---|---|---|
customers | customers, their addresses and payment methods | read, write |
entitlements | /customers/{id}/entitlements | read |
credits | /customers/{id}/credit-balance, credit purchases, credit grants, auto-reloads, credit holds (committing one records its usage) | read, write |
catalog | products, plans, prices | read, write |
meters | meters | read, write |
usage | meter events, /customers/{id}/usage | read, write |
discounts | discounts | read |
subscriptions | subscriptions | read, write |
invoices | invoices | read, write |
credit_notes | credit notes, POST /invoices/{id}/credit-notes (a refund to the card also needs refunds:write) | read, write |
payments | payments | read |
refunds | refunds, POST /payments/{id}/refunds, chargebacks and their outcome | read, write |
checkout_sessions | checkout sessions | read, write |
portal_sessions | portal sessions | write |
events | events | read |
webhook_endpoints | webhook endpoints | read, write |
metrics | metrics | read |
Publishable keys (pk_...) are rejected by server-side API endpoints. A
key's mode scopes what it can see and charge: a test key can never reach
a live card.
Path Parameters
⌘I