Revenue Intelligence

Subscriptions

The Subscriptions API lets you create, update, and delete recurring billing subscriptions in ThriveStack. Subscriptions drive MRR tracking, churn detection, and renewal signals across your customer base.

Create a subscription

POST https://api.app.thrivestack.ai/revenue/subscriptions

Authentication

Pass your API key in the x-api-key header. Your key must have the Revenue APIs scope enabled.

x-api-key: <Your API Key with Revenue APIs Scope>

Request body

FieldTypeRequiredDescription
subscription_idstringYesYour unique identifier for this subscription.
customer_idstringYesCustomer ID in your billing system.
group_idstringYesGroup ID from product telemetry (links billing to product events).
statusstringYesSubscription status: "active", "trialing", "cancelled", "past_due", or "unpaid".
currencystringNoISO 4217 currency code: "USD", "EUR", "GBP". Default: "USD".
start_datestringYesISO 8601 timestamp when the subscription started.
ended_atstringNoISO 8601 timestamp when the subscription ended or is scheduled to end.
trial_start_datestringNoISO 8601 start of the trial period.
trial_end_datestringNoISO 8601 end of the trial period.
current_period_startstringNoISO 8601 start of the current billing period.
current_period_endstringNoISO 8601 end of the current billing period.
cancelled_atstring|nullNoISO 8601 timestamp when the subscription was cancelled, or null.
cancellation_commentstringNoOptional reason for cancellation.
create_datestringNoISO 8601 timestamp when the record was created.
updated_datestringNoISO 8601 timestamp when the record was last updated.

Example

curl -X POST https://api.app.thrivestack.ai/revenue/subscriptions \
  -H "x-api-key: <Your API Key with Revenue APIs Scope>" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription_id": "sub_123",
    "customer_id": "cust_123",
    "group_id": "group_456",
    "status": "active",
    "currency": "USD",
    "start_date": "2024-01-15T00:00:00Z",
    "ended_at": "2025-01-15T00:00:00Z",
    "trial_start_date": "2024-01-01T00:00:00Z",
    "trial_end_date": "2024-01-14T23:59:59Z",
    "current_period_start": "2024-01-15T00:00:00Z",
    "current_period_end": "2024-02-14T23:59:59Z",
    "cancelled_at": null,
    "cancellation_comment": "",
    "create_date": "2024-01-15T00:00:00Z",
    "updated_date": "2024-01-15T00:00:00Z"
  }'
const response = await fetch(
  'https://api.app.thrivestack.ai/revenue/subscriptions',
  {
    method: 'POST',
    headers: {
      'x-api-key': '<Your API Key with Revenue APIs Scope>',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      subscription_id: 'sub_123',
      customer_id: 'cust_123',
      group_id: 'group_456',
      status: 'active',
      currency: 'USD',
      start_date: '2024-01-15T00:00:00Z',
      ended_at: '2025-01-15T00:00:00Z',
      trial_start_date: '2024-01-01T00:00:00Z',
      trial_end_date: '2024-01-14T23:59:59Z',
      current_period_start: '2024-01-15T00:00:00Z',
      current_period_end: '2024-02-14T23:59:59Z',
      cancelled_at: null,
      cancellation_comment: '',
      create_date: '2024-01-15T00:00:00Z',
      updated_date: '2024-01-15T00:00:00Z'
    })
  }
);
const data = await response.json();
console.log(data);
package main

import (
  "bytes"
  "encoding/json"
  "fmt"
  "io"
  "net/http"
)

func main() {
  payload := map[string]interface{}{
    "subscription_id":      "sub_123",
    "customer_id":          "cust_123",
    "group_id":             "group_456",
    "status":               "active",
    "currency":             "USD",
    "start_date":           "2024-01-15T00:00:00Z",
    "ended_at":             "2025-01-15T00:00:00Z",
    "trial_start_date":     "2024-01-01T00:00:00Z",
    "trial_end_date":       "2024-01-14T23:59:59Z",
    "current_period_start": "2024-01-15T00:00:00Z",
    "current_period_end":   "2024-02-14T23:59:59Z",
    "cancelled_at":         nil,
    "cancellation_comment": "",
    "create_date":          "2024-01-15T00:00:00Z",
    "updated_date":         "2024-01-15T00:00:00Z",
  }
  body, _ := json.Marshal(payload)

  req, _ := http.NewRequest("POST",
    "https://api.app.thrivestack.ai/revenue/subscriptions",
    bytes.NewBuffer(body))
  req.Header.Set("x-api-key", "<Your API Key with Revenue APIs Scope>")
  req.Header.Set("Content-Type", "application/json")

  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer resp.Body.Close()
  result, _ := io.ReadAll(resp.Body)
  fmt.Println(string(result))
}

Response

{
  "success": true,
  "subscription_id": "sub_123"
}

Update a subscription

PUT https://api.app.thrivestack.ai/revenue/subscriptions

Request body

FieldTypeRequiredDescription
subscription_idstringYesID of the subscription to update.
statusstringNoUpdated status: "active", "trialing", "cancelled", "past_due", or "unpaid".
currencystringNoISO 4217 currency code. Default: "USD".
current_period_startstringNoUpdated ISO 8601 start of the current billing period.
current_period_endstringNoUpdated ISO 8601 end of the current billing period.
cancelled_atstring|nullNoISO 8601 timestamp when the subscription was cancelled.
ended_atstringNoISO 8601 timestamp when the subscription ended.
cancellation_commentstringNoReason for cancellation.
updated_datestringNoISO 8601 timestamp of this update.

Example

curl -X PUT https://api.app.thrivestack.ai/revenue/subscriptions \
  -H "x-api-key: <Your API Key with Revenue APIs Scope>" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription_id": "sub_123",
    "status": "cancelled",
    "currency": "USD",
    "current_period_start": "2024-01-15T00:00:00Z",
    "current_period_end": "2024-02-14T23:59:59Z",
    "cancelled_at": "2024-02-01T12:00:00Z",
    "ended_at": "2024-02-01T12:00:00Z",
    "cancellation_comment": "Customer requested cancellation",
    "updated_date": "2024-02-01T12:00:00Z"
  }'
const response = await fetch(
  'https://api.app.thrivestack.ai/revenue/subscriptions',
  {
    method: 'PUT',
    headers: {
      'x-api-key': '<Your API Key with Revenue APIs Scope>',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      subscription_id: 'sub_123',
      status: 'cancelled',
      currency: 'USD',
      current_period_start: '2024-01-15T00:00:00Z',
      current_period_end: '2024-02-14T23:59:59Z',
      cancelled_at: '2024-02-01T12:00:00Z',
      ended_at: '2024-02-01T12:00:00Z',
      cancellation_comment: 'Customer requested cancellation',
      updated_date: '2024-02-01T12:00:00Z'
    })
  }
);
const data = await response.json();
console.log(data);
package main

import (
  "bytes"
  "encoding/json"
  "fmt"
  "io"
  "net/http"
)

func main() {
  payload := map[string]interface{}{
    "subscription_id":      "sub_123",
    "status":               "cancelled",
    "currency":             "USD",
    "current_period_start": "2024-01-15T00:00:00Z",
    "current_period_end":   "2024-02-14T23:59:59Z",
    "cancelled_at":         "2024-02-01T12:00:00Z",
    "ended_at":             "2024-02-01T12:00:00Z",
    "cancellation_comment": "Customer requested cancellation",
    "updated_date":         "2024-02-01T12:00:00Z",
  }
  body, _ := json.Marshal(payload)

  req, _ := http.NewRequest("PUT",
    "https://api.app.thrivestack.ai/revenue/subscriptions",
    bytes.NewBuffer(body))
  req.Header.Set("x-api-key", "<Your API Key with Revenue APIs Scope>")
  req.Header.Set("Content-Type", "application/json")

  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer resp.Body.Close()
  result, _ := io.ReadAll(resp.Body)
  fmt.Println(string(result))
}

Response

{
  "success": true,
  "subscription_id": "sub_123"
}

Delete a subscription

DELETE https://api.app.thrivestack.ai/revenue/subscriptions

Request body

FieldTypeRequiredDescription
subscription_idstringYesID of the subscription to delete.

Example

curl -X DELETE https://api.app.thrivestack.ai/revenue/subscriptions \
  -H "x-api-key: <Your API Key with Revenue APIs Scope>" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription_id": "sub_123"
  }'
const response = await fetch(
  'https://api.app.thrivestack.ai/revenue/subscriptions',
  {
    method: 'DELETE',
    headers: {
      'x-api-key': '<Your API Key with Revenue APIs Scope>',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      subscription_id: 'sub_123'
    })
  }
);
const data = await response.json();
console.log(data);
package main

import (
  "bytes"
  "encoding/json"
  "fmt"
  "io"
  "net/http"
)

func main() {
  payload := map[string]string{
    "subscription_id": "sub_123",
  }
  body, _ := json.Marshal(payload)

  req, _ := http.NewRequest("DELETE",
    "https://api.app.thrivestack.ai/revenue/subscriptions",
    bytes.NewBuffer(body))
  req.Header.Set("x-api-key", "<Your API Key with Revenue APIs Scope>")
  req.Header.Set("Content-Type", "application/json")

  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer resp.Body.Close()
  result, _ := io.ReadAll(resp.Body)
  fmt.Println(string(result))
}

Response

{
  "success": true,
  "subscription_id": "sub_123"
}

Error codes

StatusMeaning
400Bad Request — invalid JSON or missing required fields
401Unauthorized — invalid or missing API key, or key lacks Revenue APIs scope
404Not Found — subscription ID does not exist
429Rate Limit Exceeded
500Server Error — try again later