Skip to main content
GET
/
api
/
billing
/
usage
curl -X GET https://www.wiseyield.co/api/billing/usage \
  -H "Authorization: Bearer wy_YOUR_API_KEY"
{
  "farmsCount": 3,
  "aiRequestsThisMonth": 127
}

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.

Endpoint

GET https://www.wiseyield.co/api/billing/usage

Authentication

Requires a valid API key with billing:read scope.

Response

Returns usage statistics object.
farmsCount
number
Number of active farms owned by user
aiRequestsThisMonth
number
Number of successful AI requests made this billing period (current month)
curl -X GET https://www.wiseyield.co/api/billing/usage \
  -H "Authorization: Bearer wy_YOUR_API_KEY"
{
  "farmsCount": 3,
  "aiRequestsThisMonth": 127
}

Errors

401
error
Unauthorized - Missing or invalid API key
500
error
Internal Server Error - Failed to fetch usage statistics

Usage Metrics Explained

farmsCount

  • Definition: Number of active farms user owns (not deleted)
  • Excludes: Soft-deleted farms, farms user is member of but doesn’t own
  • Updates: Real-time (reflects current database state)

aiRequestsThisMonth

  • Definition: Count of successful AI requests made since billing period start
  • Billing Period: Calendar month (resets on 1st of month)
  • Includes: Only completed/successful requests
  • Excludes: Failed requests, pending requests, requests from previous months

Plan Limits

Usage limits by plan tier:

Seed Plan (€22/month)

  • Farms: 1 farm
  • AI Requests: 50/month

Sprout Plan (€49/month)

  • Farms: 3 farms
  • AI Requests: 200/month

Harvest Plan (€89/month) ⭐

  • Farms: 7 farms
  • AI Requests: 500/month

Grove Plan (€149/month)

  • Farms: 15 farms
  • AI Requests: 1,000/month

Summit Plan (€299+/month)

  • Farms: Unlimited
  • AI Requests: Unlimited

Use Cases

Check Usage Against Limits

async function checkUsageLimits() {
  const [usageResponse, subscriptionResponse] = await Promise.all([
    fetch('/api/billing/usage', {
      headers: { 'Authorization': `Bearer ${apiKey}` }
    }),
    fetch('/api/billing/subscription', {
      headers: { 'Authorization': `Bearer ${apiKey}` }
    })
  ]);

  const usage = await usageResponse.json();
  const { subscription } = await subscriptionResponse.json();

  const plan = subscription?.plan || 'expired';

  const limits = {
    expired: { farms: 1, aiRequests: 50 },
    seed: { farms: 1, aiRequests: 50 },
    sprout: { farms: 3, aiRequests: 200 },
    harvest: { farms: 7, aiRequests: 500 },
    grove: { farms: 15, aiRequests: 1000 },
    summit: { farms: Infinity, aiRequests: Infinity }
  };

  const planLimits = limits[plan];

  return {
    farms: {
      used: usage.farmsCount,
      limit: planLimits.farms,
      percentage: (usage.farmsCount / planLimits.farms) * 100,
      remaining: planLimits.farms - usage.farmsCount
    },
    aiRequests: {
      used: usage.aiRequestsThisMonth,
      limit: planLimits.aiRequests,
      percentage: (usage.aiRequestsThisMonth / planLimits.aiRequests) * 100,
      remaining: planLimits.aiRequests - usage.aiRequestsThisMonth
    }
  };
}

// Usage
const limits = await checkUsageLimits();
if (limits.farms.percentage >= 80) {
  showUpgradePrompt('farms');
}

Show Usage Dashboard

async function getUsageDashboard() {
  const response = await fetch('/api/billing/usage', {
    headers: { 'Authorization': `Bearer ${apiKey}` }
  });

  const usage = await response.json();

  return {
    farmsCount: usage.farmsCount,
    aiRequestsThisMonth: usage.aiRequestsThisMonth,
    aiRequestsRemaining: 500 - usage.aiRequestsThisMonth, // For harvest plan
    resetDate: new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1)
  };
}

Check Before Creating Resource

async function canCreateFarm() {
  const [usageResponse, subscriptionResponse] = await Promise.all([
    fetch('/api/billing/usage', {
      headers: { 'Authorization': `Bearer ${apiKey}` }
    }),
    fetch('/api/billing/subscription', {
      headers: { 'Authorization': `Bearer ${apiKey}` }
    })
  ]);

  const usage = await usageResponse.json();
  const { subscription } = await subscriptionResponse.json();

  const plan = subscription?.plan || 'expired';

  const farmLimits = {
    expired: 1,
    seed: 1,
    sprout: 3,
    harvest: 7,
    grove: 15,
    summit: Infinity
  };

  const limit = farmLimits[plan];
  const canCreate = usage.farmsCount < limit;

  if (!canCreate) {
    return {
      allowed: false,
      reason: `You've reached the ${plan} plan limit of ${limit} farm(s). Upgrade to create more farms.`,
      currentUsage: usage.farmsCount,
      limit
    };
  }

  return { allowed: true };
}

// Usage
const canCreate = await canCreateFarm();
if (!canCreate.allowed) {
  toast.error(canCreate.reason);
  showUpgradeDialog();
}

Monitor AI Request Usage

async function checkAiRequestQuota() {
  const response = await fetch('/api/billing/usage', {
    headers: { 'Authorization': `Bearer ${apiKey}` }
  });

  const usage = await response.json();

  const limit = 500; // Harvest plan
  const used = usage.aiRequestsThisMonth;
  const percentage = (used / limit) * 100;

  return {
    used,
    limit,
    remaining: limit - used,
    percentage,
    willResetOn: new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1),
    isNearLimit: percentage >= 80,
    isOverLimit: used >= limit
  };
}

// Usage
const quota = await checkAiRequestQuota();
if (quota.isNearLimit) {
  toast.warning(`You've used ${quota.percentage.toFixed(0)}% of your AI requests`);
}

Best Practices

Check Before Actions: Verify usage limits before allowing users to create farms or make AI requests.
Show Progress Bars: Display usage as percentage of limit with visual progress bars.
Warn at 80%: Alert users when they reach 80% of any limit to avoid surprises.
Display Reset Date: Show when AI request counter resets (1st of next month).
Monthly Reset: AI request count resets on 1st of each month, not on subscription anniversary.
Real-Time Data: Usage numbers are real-time. Cache carefully to avoid stale data blocking actions.
Soft Limits: Exceeding limits may trigger soft blocks. Always check before resource-intensive operations.

Integration Examples

Usage Dashboard Card

function UsageDashboardCard() {
  const [usage, setUsage] = useState(null);
  const [subscription, setSubscription] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function loadData() {
      try {
        const [usageRes, subRes] = await Promise.all([
          fetch('/api/billing/usage', {
            headers: { 'Authorization': `Bearer ${apiKey}` }
          }),
          fetch('/api/billing/subscription', {
            headers: { 'Authorization': `Bearer ${apiKey}` }
          })
        ]);

        const usageData = await usageRes.json();
        const { subscription } = await subRes.json();

        setUsage(usageData);
        setSubscription(subscription);
      } finally {
        setLoading(false);
      }
    }

    loadData();
  }, []);

  if (loading) return <div>Loading...</div>;

  const plan = subscription?.plan || 'expired';

  const limits = {
    expired: { farms: 1, aiRequests: 50 },
    seed: { farms: 1, aiRequests: 50 },
    sprout: { farms: 3, aiRequests: 200 },
    harvest: { farms: 7, aiRequests: 500 },
    grove: { farms: 15, aiRequests: 1000 },
    summit: { farms: Infinity, aiRequests: Infinity }
  };

  const planLimits = limits[plan];

  return (
    <div className="usage-card">
      <h3>Usage This Month</h3>

      <div className="usage-metric">
        <label>Farms</label>
        <ProgressBar
          value={usage.farmsCount}
          max={planLimits.farms}
          label={`${usage.farmsCount} / ${planLimits.farms === Infinity ? '∞' : planLimits.farms}`}
        />
      </div>

      <div className="usage-metric">
        <label>AI Requests</label>
        <ProgressBar
          value={usage.aiRequestsThisMonth}
          max={planLimits.aiRequests}
          label={`${usage.aiRequestsThisMonth} / ${planLimits.aiRequests === Infinity ? '∞' : planLimits.aiRequests}`}
        />

        <p className="reset-info">
          Resets: {new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1).toLocaleDateString()}
        </p>
      </div>

      {(usage.farmsCount >= planLimits.farms || usage.aiRequestsThisMonth >= planLimits.aiRequests) && (
        <div className="upgrade-prompt">
          <p>You've reached your plan limits</p>
          <button onClick={() => router.push('/pricing')}>
            Upgrade Plan
          </button>
        </div>
      )}
    </div>
  );
}

Usage Progress Bar

function UsageProgressBar({ used, limit, label }) {
  const percentage = limit === Infinity ? 0 : (used / limit) * 100;

  const getColor = () => {
    if (percentage >= 100) return 'red';
    if (percentage >= 80) return 'orange';
    return 'green';
  };

  return (
    <div className="progress-bar">
      <div className="progress-label">
        <span>{label}</span>
        <span>{used} / {limit === Infinity ? '∞' : limit}</span>
      </div>

      <div className="progress-track">
        <div
          className={`progress-fill bg-${getColor()}`}
          style={{ width: `${Math.min(percentage, 100)}%` }}
        />
      </div>

      <div className="progress-percentage">
        {limit === Infinity ? 'Unlimited' : `${percentage.toFixed(0)}%`}
      </div>
    </div>
  );
}

Usage Guard Hook

function useUsageGuard(resourceType) {
  const [canCreate, setCanCreate] = useState(false);
  const [loading, setLoading] = useState(true);
  const [reason, setReason] = useState(null);

  useEffect(() => {
    async function checkUsage() {
      const [usageRes, subRes] = await Promise.all([
        fetch('/api/billing/usage', {
          headers: { 'Authorization': `Bearer ${apiKey}` }
        }),
        fetch('/api/billing/subscription', {
          headers: { 'Authorization': `Bearer ${apiKey}` }
        })
      ]);

      const usage = await usageRes.json();
      const { subscription } = await subRes.json();

      const plan = subscription?.plan || 'expired';

      const limits = {
        expired: { farms: 1, aiRequests: 50 },
        seed: { farms: 1, aiRequests: 50 },
        sprout: { farms: 3, aiRequests: 200 },
        harvest: { farms: 7, aiRequests: 500 },
        grove: { farms: 15, aiRequests: 1000 },
        summit: { farms: Infinity, aiRequests: Infinity }
      };

      const limit = resourceType === 'farm'
        ? limits[plan].farms
        : limits[plan].aiRequests;

      const current = resourceType === 'farm'
        ? usage.farmsCount
        : usage.aiRequestsThisMonth;

      const allowed = current < limit;

      setCanCreate(allowed);
      setReason(allowed ? null : `${plan} plan limit reached (${current}/${limit})`);
      setLoading(false);
    }

    checkUsage();
  }, [resourceType]);

  return { canCreate, loading, reason };
}

// Usage in component
function CreateFarmButton() {
  const { canCreate, loading, reason } = useUsageGuard('farm');

  if (loading) return <button disabled>Loading...</button>;

  return (
    <button
      onClick={handleCreateFarm}
      disabled={!canCreate}
      title={reason}
    >
      {canCreate ? 'Create Farm' : `Limit Reached - Upgrade to Create More`}
    </button>
  );
}