Subscriptions

Base URL: https://api.cornerspot.net

Authentication: requests use a bearer token, for example Authorization: Bearer YOUR_API_KEY.

List subscriptions

GET /c/api/v1/subscriptions

Paginated, filterable subscriptions. Requires subscriptions_read + the Member Portal module.

Query parameters

FIELDTYPEDESCRIPTION
filter[status]stringComma-separated statuses (trialing, active, paused, past_due, cancelled, expired).
filter[account_id]stringComma-separated account ids.
filter[billing_frequency]stringComma-separated billing frequencies (monthly, quarterly, semi_annual, annual).
filter[deleted]string
one of true
Set to true to list only soft-deleted subscriptions.
filter[include_deleted]string
one of true
Set to true to include soft-deleted subscriptions alongside active ones.
sortstringOne of subscription_number_seq,status,billing_frequency,started_at,current_period_end,next_invoice_date,created_at,updated_at; - prefix for descending. Defaults to -updated_at.
pageinteger1-based page number.
per_pageintegerPage size (1-100, default 25).

Code samples

curl --request GET \
  --url 'https://api.cornerspot.net/c/api/v1/subscriptions' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.cornerspot.net/c/api/v1/subscriptions', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/subscriptions', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/subscriptions"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, headers=headers, method="GET")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/subscriptions")

request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/subscriptions',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer YOUR_API_KEY',
    ],
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
200 OKa page of subscriptions
401 Unauthorizedmissing or invalid API key
402 Payment Requiredthe team's plan doesn't include the Member Portal module
403 Forbiddenthe key lacks the subscriptions_read scope

Create a subscription

POST /c/api/v1/subscriptions

Creates a subscription. Line items reference catalog products (product_id, supplying description/unit_price defaults) or are fully custom (description + unit_price). Taxes and discounts may be attached by id (tax_rate_ids, discount_definition_ids) or inline, at the subscription level or per line item. At least one line item is required. Items/taxes/discounts are immutable after creation (there is no update endpoint). Requires subscriptions_write.

Request body

FIELDTYPEDESCRIPTION
subscriptionobject
subscription.account_idstring · requiredRequired — billed account.
subscription.currency_idstring · requiredRequired — billing currency (must match line items).
subscription.opportunity_idstring
subscription.descriptionstring
subscription.billing_frequencystring · required
one of monthly, quarterly, semi_annual, annual
Required.
subscription.billing_term_monthsintegerFixed term length; positive integer or null for open-ended.
subscription.current_period_startstring · requiredRequired.
subscription.current_period_endstring · requiredRequired.
subscription.started_atstring · requiredRequired.
subscription.next_invoice_datestringIf on or before today, a first invoice is generated immediately.
subscription.trial_endstring
subscription.auto_renewboolean
subscription.cancel_at_period_endboolean
subscription.auto_finalizeboolean
subscription.tax_rate_ids[]array of stringSubscription-level taxes by catalog id.
subscription.discount_definition_ids[]array of stringSubscription-level discounts by catalog id.
subscription.taxes[]array of objectInline subscription-level taxes.
subscription.taxes[].namestring
subscription.taxes[].ratenumber
subscription.discounts[]array of objectInline subscription-level discounts.
subscription.discounts[].namestring
subscription.discounts[].discount_typestring
one of percentage, fixed
subscription.discounts[].ratenumber
subscription.discounts[].amountstring
subscription.line_items[]array of object · requiredAt least one required.
subscription.line_items[].product_idstringCatalog product; supplies description/unit_price defaults.
subscription.line_items[].descriptionstring
subscription.line_items[].quantitynumber
subscription.line_items[].unit_pricestring
subscription.line_items[].positioninteger
subscription.line_items[].tax_rate_ids[]array of string
subscription.line_items[].discount_definition_ids[]array of string
subscription.line_items[].taxes[]array of object
subscription.line_items[].discounts[]array of object

Code samples

curl --request POST \
  --url 'https://api.cornerspot.net/c/api/v1/subscriptions' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
  "subscription": {
    "account_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "currency_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "opportunity_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "description": "string",
    "billing_frequency": "monthly",
    "billing_term_months": 1,
    "current_period_start": "2026-01-15",
    "current_period_end": "2026-01-15",
    "started_at": "2026-01-15",
    "next_invoice_date": "2026-01-15",
    "trial_end": "2026-01-15",
    "auto_renew": true,
    "cancel_at_period_end": true,
    "auto_finalize": true,
    "tax_rate_ids": [
      "abc123"
    ],
    "discount_definition_ids": [
      "abc123"
    ],
    "taxes": [
      {}
    ],
    "discounts": [
      {}
    ],
    "line_items": [
      {}
    ]
  }
}'
const response = await fetch('https://api.cornerspot.net/c/api/v1/subscriptions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: JSON.stringify({
    "subscription": {
      "account_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "currency_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "opportunity_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "description": "string",
      "billing_frequency": "monthly",
      "billing_term_months": 1,
      "current_period_start": "2026-01-15",
      "current_period_end": "2026-01-15",
      "started_at": "2026-01-15",
      "next_invoice_date": "2026-01-15",
      "trial_end": "2026-01-15",
      "auto_renew": true,
      "cancel_at_period_end": true,
      "auto_finalize": true,
      "tax_rate_ids": [
        "abc123"
      ],
      "discount_definition_ids": [
        "abc123"
      ],
      "taxes": [
        {}
      ],
      "discounts": [
        {}
      ],
      "line_items": [
        {}
      ]
    }
  })
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/subscriptions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: JSON.stringify({
    "subscription": {
      "account_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "currency_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "opportunity_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "description": "string",
      "billing_frequency": "monthly",
      "billing_term_months": 1,
      "current_period_start": "2026-01-15",
      "current_period_end": "2026-01-15",
      "started_at": "2026-01-15",
      "next_invoice_date": "2026-01-15",
      "trial_end": "2026-01-15",
      "auto_renew": true,
      "cancel_at_period_end": true,
      "auto_finalize": true,
      "tax_rate_ids": [
        "abc123"
      ],
      "discount_definition_ids": [
        "abc123"
      ],
      "taxes": [
        {}
      ],
      "discounts": [
        {}
      ],
      "line_items": [
        {}
      ]
    }
  })
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/subscriptions"
payload = json.dumps({
  "subscription": {
    "account_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "currency_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "opportunity_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "description": "string",
    "billing_frequency": "monthly",
    "billing_term_months": 1,
    "current_period_start": "2026-01-15",
    "current_period_end": "2026-01-15",
    "started_at": "2026-01-15",
    "next_invoice_date": "2026-01-15",
    "trial_end": "2026-01-15",
    "auto_renew": true,
    "cancel_at_period_end": true,
    "auto_finalize": true,
    "tax_rate_ids": [
      "abc123"
    ],
    "discount_definition_ids": [
      "abc123"
    ],
    "taxes": [
      {}
    ],
    "discounts": [
      {}
    ],
    "line_items": [
      {}
    ]
  }
}).encode("utf-8")
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, data=payload, headers=headers, method="POST")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/subscriptions")

request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer YOUR_API_KEY"
request.body = JSON.generate({
  "subscription": {
    "account_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "currency_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "opportunity_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "description": "string",
    "billing_frequency": "monthly",
    "billing_term_months": 1,
    "current_period_start": "2026-01-15",
    "current_period_end": "2026-01-15",
    "started_at": "2026-01-15",
    "next_invoice_date": "2026-01-15",
    "trial_end": "2026-01-15",
    "auto_renew": true,
    "cancel_at_period_end": true,
    "auto_finalize": true,
    "tax_rate_ids": [
      "abc123"
    ],
    "discount_definition_ids": [
      "abc123"
    ],
    "taxes": [
      {}
    ],
    "discounts": [
      {}
    ],
    "line_items": [
      {}
    ]
  }
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/subscriptions',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Authorization: Bearer YOUR_API_KEY',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'subscription' => [
        'account_id' => '1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d',
        'currency_id' => '1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d',
        'opportunity_id' => '1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d',
        'description' => 'string',
        'billing_frequency' => 'monthly',
        'billing_term_months' => 1,
        'current_period_start' => '2026-01-15',
        'current_period_end' => '2026-01-15',
        'started_at' => '2026-01-15',
        'next_invoice_date' => '2026-01-15',
        'trial_end' => '2026-01-15',
        'auto_renew' => true,
        'cancel_at_period_end' => true,
        'auto_finalize' => true,
        'tax_rate_ids' => [
            'abc123',
        ],
        'discount_definition_ids' => [
            'abc123',
        ],
        'taxes' => [
            [],
        ],
        'discounts' => [
            [],
        ],
        'line_items' => [
            [],
        ],
    ],
]),
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
201 Createdcreated
401 Unauthorizedmissing or invalid API key
402 Payment Requiredthe team's plan doesn't include the Member Portal module
403 Forbiddenthe key lacks the subscriptions_write scope
422 Unprocessable Contenta line item references a catalog id that does not exist in the team (unknown_catalog_reference)

Get a subscription

GET /c/api/v1/subscriptions/{id}

Path parameters

FIELDTYPEDESCRIPTION
idstring · requiredSubscription id.

Code samples

curl --request GET \
  --url 'https://api.cornerspot.net/c/api/v1/subscriptions/abc123' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.cornerspot.net/c/api/v1/subscriptions/abc123', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/subscriptions/abc123', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/subscriptions/abc123"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, headers=headers, method="GET")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/subscriptions/abc123")

request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/subscriptions/abc123',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer YOUR_API_KEY',
    ],
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
200 OKthe subscription
401 Unauthorizedmissing or invalid API key
403 Forbiddenthe key lacks the subscriptions_read scope
404 Not Foundno such subscription in this team

Delete a subscription

DELETE /c/api/v1/subscriptions/{id}

Soft-deletes the subscription (cascading its items). A subscription with associated invoices is blocked and returns 422 with an errors array. Optionally pass reason to record on the deletion event.

Path parameters

FIELDTYPEDESCRIPTION
idstring · requiredSubscription id.

Query parameters

FIELDTYPEDESCRIPTION
reasonstringOptional free-form reason captured on the deletion event.

Code samples

curl --request DELETE \
  --url 'https://api.cornerspot.net/c/api/v1/subscriptions/abc123' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.cornerspot.net/c/api/v1/subscriptions/abc123', {
  method: 'DELETE',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/subscriptions/abc123', {
  method: 'DELETE',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/subscriptions/abc123"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, headers=headers, method="DELETE")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/subscriptions/abc123")

request = Net::HTTP::Delete.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/subscriptions/abc123',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer YOUR_API_KEY',
    ],
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
204 No Contentdeleted
401 Unauthorizedmissing or invalid API key
403 Forbiddenthe key lacks the subscriptions_write scope
404 Not Foundno such subscription in this team

Was this article helpful?