Journey Docs
Members APITransfers

Get Transfer Limits

Get current transfer limits including tier defaults, overrides, and usage

GET/members/me/transfers/limits

Overview

Returns the current member's transfer limits including tier defaults, member-specific overrides, and current usage statistics. Use this endpoint to verify transfer limits before attempting transfers and to display available transfer capacity to users.

Authentication

Requires a valid Clerk JWT token in the Authorization header.

Request

curl -X GET "http://localhost:3000/v1/members/me/transfers/limits" \
  -H "Authorization: Bearer YOUR_CLERK_JWT"

Response

perTransferMaxnumberrequired

Maximum points allowed per single transfer

dailyLimitnumberrequired

Maximum points that can be transferred per day

monthlyLimitnumberrequired

Maximum points that can be transferred per month

minimumTransfernumberrequired

Minimum points required for any transfer

dailyUsednumberrequired

Points already transferred today

dailyRemainingnumberrequired

Remaining points available for transfer today

monthlyUsednumberrequired

Points already transferred this month

monthlyRemainingnumberrequired

Remaining points available for transfer this month

Response

{
  "perTransferMax": 50000,
  "dailyLimit": 100000,
  "monthlyLimit": 500000,
  "minimumTransfer": 100,
  "dailyUsed": 5000,
  "dailyRemaining": 95000,
  "monthlyUsed": 25000,
  "monthlyRemaining": 475000
}

Limit Types

Per Transfer Maximum

  • Purpose: Maximum points in a single transfer
  • Typical Values: 50,000 - 100,000 points
  • Use Case: Prevent large single transfers
  • Override: Can be increased for VIP members

Daily Limit

  • Purpose: Maximum points transferred per calendar day
  • Reset: Midnight UTC
  • Typical Values: 100,000 - 250,000 points
  • Cumulative: Includes all transfers (direct + pending)

Monthly Limit

  • Purpose: Maximum points transferred per calendar month
  • Reset: First day of month at midnight UTC
  • Typical Values: 500,000 - 1,000,000 points
  • Rollover: No rollover of unused limits

Minimum Transfer

  • Purpose: Smallest transfer amount allowed
  • Typical Values: 50 - 100 points
  • Reason: Prevent spam/abuse of small transfers

Tier-Based Limits

Standard Tier

{
  "perTransferMax": 50000,
  "dailyLimit": 100000,
  "monthlyLimit": 500000,
  "minimumTransfer": 100
}

Premium Tier

{
  "perTransferMax": 75000,
  "dailyLimit": 200000,
  "monthlyLimit": 750000,
  "minimumTransfer": 75
}

VIP Tier

{
  "perTransferMax": 100000,
  "dailyLimit": 250000,
  "monthlyLimit": 1000000,
  "minimumTransfer": 50
}

Usage Calculations

Daily Usage

  • Tracks: All transfers within current calendar day (UTC)
  • Includes: Direct transfers + pending transfers created
  • Resets: Daily at midnight UTC
  • Calculation: dailyRemaining = dailyLimit - dailyUsed

Monthly Usage

  • Tracks: All transfers within current calendar month (UTC)
  • Includes: Direct transfers + pending transfers created
  • Resets: First day of month at midnight UTC
  • Calculation: monthlyRemaining = monthlyLimit - monthlyUsed

Member Overrides

Custom Limits

  • VIP Members: May have higher limits
  • Business Accounts: Custom enterprise limits
  • Support Approved: Temporary limit increases
  • Algorithm: effectiveLimit = max(tierDefault, memberOverride)

Temporary Increases

  • Duration: Usually 30-90 days
  • Approval: Requires support ticket
  • Use Cases: Special events, bulk gifting campaigns
  • Monitoring: Increased fraud monitoring during override period

Use Cases

Pre-Transfer Validation

const validateTransfer = async (amount: number) => {
  const response = await fetch('/api/members/me/transfers/limits');
  const limits = await response.json();
  
  const errors = [];
  
  if (amount < limits.minimumTransfer) {
    errors.push(`Minimum transfer is ${limits.minimumTransfer} points`);
  }
  
  if (amount > limits.perTransferMax) {
    errors.push(`Maximum per transfer is ${limits.perTransferMax} points`);
  }
  
  if (amount > limits.dailyRemaining) {
    errors.push(`Daily limit exceeded. ${limits.dailyRemaining} points remaining today`);
  }
  
  if (amount > limits.monthlyRemaining) {
    errors.push(`Monthly limit exceeded. ${limits.monthlyRemaining} points remaining this month`);
  }
  
  return {
    valid: errors.length === 0,
    errors,
    limits
  };
};

Display Transfer Capacity

const displayTransferLimits = async () => {
  const response = await fetch('/api/members/me/transfers/limits');
  const limits = await response.json();
  
  const maxTransferToday = Math.min(
    limits.perTransferMax,
    limits.dailyRemaining,
    limits.monthlyRemaining
  );
  
  return {
    maxTransferToday,
    dailyProgress: (limits.dailyUsed / limits.dailyLimit) * 100,
    monthlyProgress: (limits.monthlyUsed / limits.monthlyLimit) * 100,
    resetTimes: {
      daily: getNextMidnightUTC(),
      monthly: getFirstOfNextMonthUTC()
    }
  };
};

Bulk Transfer Planning

const planBulkTransfers = async (recipients: number[], amount: number) => {
  const response = await fetch('/api/members/me/transfers/limits');
  const limits = await response.json();
  
  const totalAmount = recipients.length * amount;
  const maxTransfersToday = Math.floor(limits.dailyRemaining / amount);
  const maxTransfersThisMonth = Math.floor(limits.monthlyRemaining / amount);
  
  return {
    canTransferAll: totalAmount <= Math.min(limits.dailyRemaining, limits.monthlyRemaining),
    maxToday: Math.min(recipients.length, maxTransfersToday),
    maxThisMonth: Math.min(recipients.length, maxTransfersThisMonth),
    needsSpread: totalAmount > limits.dailyRemaining,
    daysRequired: Math.ceil(totalAmount / limits.dailyLimit)
  };
};

Performance Notes

Caching

  • Server-side: Limits cached for 5 minutes
  • Client-side: Safe to cache for 1-2 minutes
  • Invalidation: Updated after each transfer

Real-time Updates

  • Usage Tracking: Updated immediately after transfers
  • Limit Changes: Applied within 5 minutes
  • Overrides: Applied immediately after approval

Monitoring & Alerts

Near Limit Warnings

const checkLimitWarnings = (limits) => {
  const warnings = [];
  
  if (limits.dailyRemaining < limits.dailyLimit * 0.1) {
    warnings.push('Approaching daily transfer limit');
  }
  
  if (limits.monthlyRemaining < limits.monthlyLimit * 0.1) {
    warnings.push('Approaching monthly transfer limit');
  }
  
  return warnings;
};

Usage Analytics

  • Daily Pattern: Track typical daily usage
  • Monthly Trends: Monitor monthly transfer patterns
  • Limit Utilization: Percentage of limits used
  • Optimization: Suggest limit adjustments based on usage

On this page