curl -X GET https://www.wiseyield.co/api/billing/subscription \
-H "Authorization: Bearer wy_YOUR_API_KEY"
{
"subscription": {
"id": "sub_abc123",
"userId": "user_xyz789",
"subscriptionId": "sub_1234567890",
"customerId": "cus_9876543210",
"priceId": "price_harvest_monthly",
"plan": "harvest",
"status": "active",
"currentPeriodStart": "2025-11-01T00:00:00.000Z",
"currentPeriodEnd": "2025-12-01T00:00:00.000Z",
"cancelAtPeriodEnd": false,
"createdAt": "2025-10-01T10:00:00.000Z",
"updatedAt": "2025-11-01T00:00:00.000Z"
}
}
Get the current user’s subscription status and plan details
curl -X GET https://www.wiseyield.co/api/billing/subscription \
-H "Authorization: Bearer wy_YOUR_API_KEY"
{
"subscription": {
"id": "sub_abc123",
"userId": "user_xyz789",
"subscriptionId": "sub_1234567890",
"customerId": "cus_9876543210",
"priceId": "price_harvest_monthly",
"plan": "harvest",
"status": "active",
"currentPeriodStart": "2025-11-01T00:00:00.000Z",
"currentPeriodEnd": "2025-12-01T00:00:00.000Z",
"cancelAtPeriodEnd": false,
"createdAt": "2025-10-01T10:00:00.000Z",
"updatedAt": "2025-11-01T00:00:00.000Z"
}
}
Documentation Index
Fetch the complete documentation index at: https://docs.wiseyield.co/llms.txt
Use this file to discover all available pages before exploring further.
GET https://www.wiseyield.co/api/billing/subscription
billing:read scope.
Show Subscription Object
seed, sprout, harvest, grove, summitactive, canceled, past_due, trialing, incompletecurl -X GET https://www.wiseyield.co/api/billing/subscription \
-H "Authorization: Bearer wy_YOUR_API_KEY"
{
"subscription": {
"id": "sub_abc123",
"userId": "user_xyz789",
"subscriptionId": "sub_1234567890",
"customerId": "cus_9876543210",
"priceId": "price_harvest_monthly",
"plan": "harvest",
"status": "active",
"currentPeriodStart": "2025-11-01T00:00:00.000Z",
"currentPeriodEnd": "2025-12-01T00:00:00.000Z",
"cancelAtPeriodEnd": false,
"createdAt": "2025-10-01T10:00:00.000Z",
"updatedAt": "2025-11-01T00:00:00.000Z"
}
}
async function getSubscriptionStatus() {
const response = await fetch('/api/billing/subscription', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { subscription } = await response.json();
if (!subscription) {
return { hasSubscription: false, plan: 'expired' };
}
return {
hasSubscription: true,
plan: subscription.plan,
status: subscription.status,
isActive: subscription.status === 'active',
renewsAt: subscription.currentPeriodEnd
};
}
// Usage
const status = await getSubscriptionStatus();
if (!status.hasSubscription) {
showUpgradePrompt();
}
async function canAccessFeature(feature) {
const response = await fetch('/api/billing/subscription', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { subscription } = await response.json();
const plan = subscription?.plan || 'expired';
const features = {
expired: ['basic_analytics'],
seed: ['basic_analytics', 'single_farm'],
sprout: ['basic_analytics', 'multiple_farms', 'export', 'farm_budgeting'],
harvest: ['advanced_analytics', 'vision_ai', 'market_intelligence', 'task_templates'],
grove: ['advanced_analytics', 'financial_ai', 'pnl_reports', 'invoices'],
summit: ['advanced_analytics', 'api_access', 'dedicated_support', 'sla']
};
return features[plan]?.includes(feature) || false;
}
// Usage
if (await canAccessFeature('advanced_analytics')) {
showAdvancedAnalytics();
}
async function getDaysUntilRenewal() {
const response = await fetch('/api/billing/subscription', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { subscription } = await response.json();
if (!subscription) return null;
const renewDate = new Date(subscription.currentPeriodEnd);
const now = new Date();
const daysRemaining = Math.ceil((renewDate - now) / (1000 * 60 * 60 * 24));
return {
renewDate,
daysRemaining,
willCancel: subscription.cancelAtPeriodEnd
};
}
async function isPaymentHealthy() {
const response = await fetch('/api/billing/subscription', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { subscription } = await response.json();
if (!subscription) return true; // No subscription (expired)
const healthyStatuses = ['active', 'trialing'];
return healthyStatuses.includes(subscription.status);
}
// Usage
const healthy = await isPaymentHealthy();
if (!healthy) {
showPaymentWarning();
}
subscription: null means no active subscription (expired). Don’t treat it as an error.currentPeriodEnd to users so they know when they’ll be charged.status: "past_due" still have access but payment failed. Prompt user to update payment method.cancelAtPeriodEnd: true, subscription will end at currentPeriodEnd. Show this clearly to user.function SubscriptionStatusCard() {
const [subscription, setSubscription] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadSubscription() {
try {
const response = await fetch('/api/billing/subscription', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { subscription } = await response.json();
setSubscription(subscription);
} finally {
setLoading(false);
}
}
loadSubscription();
}, []);
if (loading) return <div>Loading...</div>;
const plan = subscription?.plan || 'expired';
const status = subscription?.status || 'active';
return (
<div className="subscription-card">
<h2>Current Plan</h2>
<PlanBadge plan={plan} />
<StatusBadge status={status} />
{subscription && (
<>
<p>Renews: {new Date(subscription.currentPeriodEnd).toLocaleDateString()}</p>
{subscription.cancelAtPeriodEnd && (
<div className="warning">
Your subscription will end on {new Date(subscription.currentPeriodEnd).toLocaleDateString()}
</div>
)}
{status === 'past_due' && (
<div className="error">
Payment failed. Please update your payment method.
</div>
)}
</>
)}
{!subscription && (
<button onClick={() => router.push('/pricing')}>
Upgrade Plan
</button>
)}
</div>
);
}
function FeatureGate({ feature, plan, children, fallback }) {
const [hasAccess, setHasAccess] = useState(false);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function checkAccess() {
try {
const response = await fetch('/api/billing/subscription', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { subscription } = await response.json();
const userPlan = subscription?.plan || 'expired';
const planHierarchy = ['expired', 'seed', 'sprout', 'harvest', 'grove', 'summit'];
const requiredIndex = planHierarchy.indexOf(plan);
const userIndex = planHierarchy.indexOf(userPlan);
setHasAccess(userIndex >= requiredIndex);
} finally {
setLoading(false);
}
}
checkAccess();
}, [plan]);
if (loading) return <div>Loading...</div>;
return hasAccess ? children : (fallback || <UpgradePrompt requiredPlan={plan} />);
}
// Usage
<FeatureGate feature="advanced_analytics" plan="grove">
<AdvancedAnalyticsDashboard />
</FeatureGate>
function useSubscription() {
const [subscription, setSubscription] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchSubscription() {
try {
const response = await fetch('/api/billing/subscription', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { subscription } = await response.json();
setSubscription(subscription);
} finally {
setLoading(false);
}
}
fetchSubscription();
}, []);
const plan = subscription?.plan || 'expired';
return {
subscription,
loading,
plan,
isPro: ['harvest', 'grove', 'summit'].includes(plan),
isEnterprise: plan === 'summit',
hasAccess: (requiredPlan) => {
const hierarchy = ['expired', 'seed', 'sprout', 'harvest', 'grove', 'summit'];
return hierarchy.indexOf(plan) >= hierarchy.indexOf(requiredPlan);
}
};
}
// Usage in component
function Dashboard() {
const { plan, isPro, hasAccess } = useSubscription();
return (
<div>
<h1>Dashboard - {plan} Plan</h1>
{hasAccess('grove') && <AdvancedFeatures />}
{isPro && <PrioritySupport />}
</div>
);
}