Docs

Get Subscription

Retrieve the current subscription status and details.

Get Subscription

Retrieves the current subscription status, plan details, and billing information for the authenticated user.

Endpoint

GET /api/billing/subscription

Authentication

Required. Bearer token in Authorization header.

Request

No request body required.

Example Request

curl -X GET https://api.example.com/api/billing/subscription \
  -H "Authorization: Bearer <session_token>"

TypeScript Example

const response = await fetch('/api/billing/subscription', {
  headers: {
    'Authorization': `Bearer ${sessionToken}`
  }
});

const { data } = await response.json();
console.log('Current plan:', data.plan);
console.log('Status:', data.status);

Response

Active Subscription (200)

{
  "success": true,
  "data": {
    "id": "sub_1234567890",
    "status": "active",
    "plan": {
      "id": "price_1ABC123XYZ",
      "name": "Pro",
      "description": "For growing teams",
      "price": 29.00,
      "currency": "usd",
      "interval": "month"
    },
    "currentPeriodStart": "2024-01-01T00:00:00Z",
    "currentPeriodEnd": "2024-02-01T00:00:00Z",
    "cancelAtPeriodEnd": false,
    "features": [
      "unlimited_projects",
      "priority_support",
      "advanced_analytics"
    ],
    "usage": {
      "seats": {
        "included": 10,
        "used": 7
      },
      "apiCalls": {
        "included": 100000,
        "used": 45230
      }
    }
  }
}

No Subscription (200)

{
  "success": true,
  "data": {
    "status": "inactive",
    "plan": null,
    "features": ["basic_access"]
  }
}

Cancelled Subscription (200)

{
  "success": true,
  "data": {
    "id": "sub_1234567890",
    "status": "canceled",
    "plan": {
      "id": "price_1ABC123XYZ",
      "name": "Pro",
      "price": 29.00,
      "currency": "usd",
      "interval": "month"
    },
    "currentPeriodEnd": "2024-02-01T00:00:00Z",
    "cancelAtPeriodEnd": true,
    "canceledAt": "2024-01-15T10:30:00Z"
  }
}

Response Fields

FieldTypeDescription
idstringStripe subscription ID
statusstringSubscription status: active, canceled, past_due, unpaid, incomplete, inactive
planobjectPlan details including name, price, and interval
currentPeriodStartstringISO 8601 timestamp of current billing period start
currentPeriodEndstringISO 8601 timestamp of current billing period end
cancelAtPeriodEndbooleanWhether subscription cancels at period end
canceledAtstringISO 8601 timestamp when subscription was cancelled
featuresstring[]List of enabled features for the plan
usageobjectCurrent usage against plan limits

Status Values

StatusDescription
activeSubscription is active and in good standing
inactiveNo active subscription (free tier or never subscribed)
canceledSubscription was cancelled, may still be active until period end
past_duePayment failed, grace period active
unpaidPayment failed, subscription suspended
incompleteCheckout started but not completed

Error Responses

Unauthorized (401)

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Authentication required"
  }
}

React Hook Example

import { useEffect, useState } from 'react';

interface Subscription {
  status: 'active' | 'inactive' | 'canceled';
  plan: {
    name: string;
    price: number;
  } | null;
}

function useSubscription() {
  const [subscription, setSubscription] = useState<Subscription | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('/api/billing/subscription', {
      headers: { 'Authorization': `Bearer ${getToken()}` }
    })
      .then(res => res.json())
      .then(({ data }) => setSubscription(data))
      .finally(() => setLoading(false));
  }, []);

  return { subscription, loading };
}

// Usage
function PlanBadge() {
  const { subscription, loading } = useSubscription();
  
  if (loading) return <span>Loading...</span>;
  
  if (subscription?.status === 'inactive') {
    return <span>Free Plan</span>;
  }
  
  return <span>{subscription?.plan?.name} Plan</span>;
}

Notes

  • Returns cached data with a 5-minute TTL
  • Force refresh by adding ?refresh=true query parameter
  • Usage data is real-time for metered billing
  • Feature flags should be checked server-side for security

On this page