Numerology API Integration Guide: Complete Developer Tutorial
Comprehensive guide for integrating numerology calculations into your app. Learn API authentication, endpoint selection, caching strategies, and building complete numerology profiles with compatibility features.
Numerology API Integration Guide: Complete Developer Tutorial
Integrating numerology into your app can transform a simple utility into a deeply personal experience that users engage with daily. Whether you are building a spiritual wellness app, personal development platform, dating service, or AI chatbot, numerology features add unique value that keeps users coming back.
This comprehensive guide covers everything you need to know about numerology API integration. You will learn which endpoints to use, how to structure your requests, handle responses, implement caching strategies, and design user experiences that showcase numerology insights effectively.
Understanding Numerology API Endpoints
A complete numerology API provides multiple endpoints covering different aspects of numerology calculations. Here is what each endpoint does and when to use it:
Core Number Endpoints
Life Path Number (POST https://roxyapi.com/api/v2/numerology/life-path): The most important number in numerology, calculated from birth date. This is your starting point for any numerology feature. Use this when you want to show someone their life purpose, destiny, and core personality traits.
Expression Number (POST https://roxyapi.com/api/v2/numerology/expression): Calculated from full birth name, reveals natural talents and life goals. Perfect for career guidance features, talent assessment tools, or helping users understand their innate abilities.
Soul Urge Number (POST https://roxyapi.com/api/v2/numerology/soul-urge): Based on vowels in the name, shows inner desires and motivations. Ideal for self-discovery features, personal development apps, or understanding what truly drives someone.
Personality Number (POST https://roxyapi.com/api/v2/numerology/personality): Calculated from consonants, reveals how others perceive you. Great for social apps, networking platforms, or helping users understand their first impressions.
Birth Day Number (POST https://roxyapi.com/api/v2/numerology/birth-day): Based on birth day only, indicates special talents and abilities. Use this for quick insights or complementary features in existing date-based calculations.
Maturity Number (POST https://roxyapi.com/api/v2/numerology/maturity): Shows who you become later in life, combines life path and expression. Excellent for long-term planning features, retirement apps, or life stage guidance.
Forecasting Endpoints
Personal Year (POST https://roxyapi.com/api/v2/numerology/personal-year): Calculates current year energy and themes. Perfect for daily insight features, year planning tools, or personalized guidance that changes annually.
Karmic Endpoints
Karmic Debt (POST https://roxyapi.com/api/v2/numerology/karmic-debt): Detects karmic debt numbers (13, 14, 16, 19) and their meanings. Use this for spiritual growth features, challenge identification, or deep self-awareness tools.
Karmic Lessons (POST https://roxyapi.com/api/v2/numerology/karmic-lessons): Identifies missing numbers in name and lessons to learn. Great for personal development features, skill gap analysis, or growth opportunity identification.
Relationship Endpoints
Compatibility (POST https://roxyapi.com/api/v2/numerology/compatibility): Analyzes relationship dynamics between two people using their numerology numbers. Essential for dating apps, relationship counseling tools, or team building features.
Complete Chart Endpoint
Full Numerology Chart (POST https://roxyapi.com/api/v2/numerology/chart): Returns all core numbers, karmic analysis, and personal year in one response. This is your most efficient option when building complete numerology profiles or comprehensive reports.
Lookup Endpoints
Number Meanings (GET https://roxyapi.com/api/v2/numerology/meanings/{number}): Returns detailed interpretation for any number (1-9, 11, 22, 33). Use this for educational features, number exploration tools, or displaying meanings without calculations.
Setting Up Your API Client
Start by creating a centralized API client that handles authentication, request formatting, and error handling:
// services/numerology-api.ts
import axios, { AxiosInstance, AxiosError } from 'axios';
const API_BASE_URL = 'https://roxyapi.com/api/v2/numerology';
class NumerologyAPI {
private client: AxiosInstance;
constructor(apiKey: string) {
this.client = axios.create({
baseURL: API_BASE_URL,
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json',
},
timeout: 10000, // 10 second timeout
});
// Add response interceptor for error handling
this.client.interceptors.response.use(
(response) => response,
(error: AxiosError) => {
return this.handleError(error);
}
);
}
private handleError(error: AxiosError): Promise<never> {
if (error.response) {
const status = error.response.status;
const message = error.response.data?.error || 'API request failed';
switch (status) {
case 401:
throw new Error('Invalid API key');
case 429:
throw new Error('Rate limit exceeded. Please try again later.');
case 400:
throw new Error(message);
default:
throw new Error('Numerology calculation failed');
}
} else if (error.request) {
throw new Error('Network error. Please check your connection.');
} else {
throw new Error('Failed to calculate numerology');
}
}
async calculateLifePath(year: number, month: number, day: number) {
const response = await this.client.post('/life-path', { year, month, day });
return response.data;
}
async calculateExpression(fullName: string) {
const response = await this.client.post('/expression', { fullName });
return response.data;
}
async calculateSoulUrge(fullName: string) {
const response = await this.client.post('/soul-urge', { fullName });
return response.data;
}
async calculatePersonality(fullName: string) {
const response = await this.client.post('/personality', { fullName });
return response.data;
}
async calculateBirthDay(day: number) {
const response = await this.client.post('/birth-day', { day });
return response.data;
}
async calculateMaturity(fullName: string, year: number, month: number, day: number) {
const response = await this.client.post('/maturity', { fullName, year, month, day });
return response.data;
}
async calculatePersonalYear(year: number, month: number, day: number, currentYear?: number) {
const response = await this.client.post('/personal-year', {
year,
month,
day,
currentYear: currentYear || new Date().getFullYear()
});
return response.data;
}
async detectKarmicDebt(fullName: string, year: number, month: number, day: number) {
const response = await this.client.post('/karmic-debt', { fullName, year, month, day });
return response.data;
}
async analyzeKarmicLessons(fullName: string) {
const response = await this.client.post('/karmic-lessons', { fullName });
return response.data;
}
async calculateCompatibility(
person1: { lifePath: number; expression: number; soulUrge: number },
person2: { lifePath: number; expression: number; soulUrge: number }
) {
const response = await this.client.post('/compatibility', { person1, person2 });
return response.data;
}
async generateFullChart(fullName: string, year: number, month: number, day: number, currentYear?: number) {
const response = await this.client.post('/chart', {
fullName,
year,
month,
day,
currentYear: currentYear || new Date().getFullYear()
});
return response.data;
}
async getNumberMeaning(number: number) {
const response = await this.client.get(`/meanings/${number}`);
return response.data;
}
}
// Export singleton instance
export const createNumerologyAPI = (apiKey: string) => new NumerologyAPI(apiKey);
Implementing Response Type Definitions
TypeScript developers should define interfaces for API responses:
// types/numerology.ts
export interface NumberMeaning {
title: string;
keywords: string[];
description: string;
strengths: string[];
challenges: string[];
career: string;
relationships: string;
spirituality: string;
}
export interface CoreNumberResult {
number: number;
calculation: string;
type: 'single' | 'master';
hasKarmicDebt: boolean;
karmicDebtNumber?: number;
meaning: NumberMeaning;
}
export interface BirthDayResult {
number: number;
meaning: NumberMeaning;
}
export interface PersonalYearResult {
personalYear: number;
cycle: string;
theme: string;
forecast: string;
opportunities: string[];
challenges: string[];
advice: string;
}
export interface KarmicDebtResult {
hasKarmicDebt: boolean;
debtNumbers: number[];
meanings: Array<{
number: number;
description: string;
howToOvercome: string;
}>;
}
export interface KarmicLessonsResult {
missingNumbers: number[];
lessons: Array<{
number: number;
lesson: string;
description: string;
howToOvercome: string;
}>;
presentNumbers: Record<string, number>;
}
export interface CompatibilityResult {
overallScore: number;
rating: string;
lifePath: {
person1: number;
person2: number;
compatibility: number;
description: string;
};
expression: {
person1: number;
person2: number;
compatibility: number;
description: string;
};
soulUrge: {
person1: number;
person2: number;
compatibility: number;
description: string;
};
strengths: string[];
challenges: string[];
advice: string;
}
export interface FullChartResult {
profile: {
name: string;
birthdate: string;
};
coreNumbers: {
lifePath: CoreNumberResult;
expression: CoreNumberResult;
soulUrge: CoreNumberResult;
personality: CoreNumberResult;
birthDay: BirthDayResult;
maturity: CoreNumberResult;
};
additionalInsights: {
karmicLessons: KarmicLessonsResult;
karmicDebt: KarmicDebtResult;
personalYear: PersonalYearResult;
};
summary: string;
}
Building a Complete Numerology Profile
The full chart endpoint is perfect for generating comprehensive profiles:
// components/NumerologyProfile.tsx
import React, { useState, useEffect } from 'react';
import { View, Text, ScrollView, ActivityIndicator } from 'react-native';
import { createNumerologyAPI } from '../services/numerology-api';
import type { FullChartResult } from '../types/numerology';
interface NumerologyProfileProps {
fullName: string;
birthYear: number;
birthMonth: number;
birthDay: number;
apiKey: string;
}
const NumerologyProfile: React.FC<NumerologyProfileProps> = ({
fullName,
birthYear,
birthMonth,
birthDay,
apiKey,
}) => {
const [chart, setChart] = useState<FullChartResult | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
loadChart();
}, [fullName, birthYear, birthMonth, birthDay]);
const loadChart = async () => {
setLoading(true);
setError(null);
try {
const api = createNumerologyAPI(apiKey);
const data = await api.generateFullChart(fullName, birthYear, birthMonth, birthDay);
setChart(data);
} catch (err) {
setError(err.message || 'Failed to load numerology chart');
} finally {
setLoading(false);
}
};
if (loading) {
return (
<View style={styles.centerContainer}>
<ActivityIndicator size="large" color="#007AFF" />
<Text style={styles.loadingText}>Generating your numerology chart...</Text>
</View>
);
}
if (error) {
return (
<View style={styles.centerContainer}>
<Text style={styles.errorText}>{error}</Text>
</View>
);
}
if (!chart) return null;
return (
<ScrollView style={styles.container}>
<View style={styles.header}>
<Text style={styles.name}>{chart.profile.name}</Text>
<Text style={styles.birthdate}>{chart.profile.birthdate}</Text>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Core Numbers</Text>
<NumberCard
label="Life Path"
number={chart.coreNumbers.lifePath.number}
title={chart.coreNumbers.lifePath.meaning.title}
isMaster={chart.coreNumbers.lifePath.type === 'master'}
/>
<NumberCard
label="Expression"
number={chart.coreNumbers.expression.number}
title={chart.coreNumbers.expression.meaning.title}
isMaster={chart.coreNumbers.expression.type === 'master'}
/>
<NumberCard
label="Soul Urge"
number={chart.coreNumbers.soulUrge.number}
title={chart.coreNumbers.soulUrge.meaning.title}
isMaster={chart.coreNumbers.soulUrge.type === 'master'}
/>
<NumberCard
label="Personality"
number={chart.coreNumbers.personality.number}
title={chart.coreNumbers.personality.meaning.title}
isMaster={chart.coreNumbers.personality.type === 'master'}
/>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Current Year Energy</Text>
<Text style={styles.personalYearNumber}>
Personal Year {chart.additionalInsights.personalYear.personalYear}
</Text>
<Text style={styles.personalYearTheme}>
{chart.additionalInsights.personalYear.theme}
</Text>
<Text style={styles.forecast}>
{chart.additionalInsights.personalYear.forecast}
</Text>
</View>
{chart.additionalInsights.karmicDebt.hasKarmicDebt && (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Karmic Debt</Text>
{chart.additionalInsights.karmicDebt.meanings.map((debt, index) => (
<View key={index} style={styles.karmicCard}>
<Text style={styles.karmicNumber}>Karmic Debt {debt.number}</Text>
<Text style={styles.karmicDescription}>{debt.description}</Text>
<Text style={styles.karmicOvercome}>{debt.howToOvercome}</Text>
</View>
))}
</View>
)}
{chart.additionalInsights.karmicLessons.missingNumbers.length > 0 && (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Karmic Lessons</Text>
{chart.additionalInsights.karmicLessons.lessons.map((lesson, index) => (
<View key={index} style={styles.lessonCard}>
<Text style={styles.lessonNumber}>Missing Number {lesson.number}</Text>
<Text style={styles.lessonTitle}>{lesson.lesson}</Text>
<Text style={styles.lessonDescription}>{lesson.description}</Text>
<Text style={styles.lessonOvercome}>{lesson.howToOvercome}</Text>
</View>
))}
</View>
)}
</ScrollView>
);
};
const NumberCard: React.FC<{
label: string;
number: number;
title: string;
isMaster: boolean;
}> = ({ label, number, title, isMaster }) => (
<View style={styles.numberCard}>
<View style={styles.numberBadge}>
<Text style={styles.numberText}>{number}</Text>
</View>
<View style={styles.numberInfo}>
<Text style={styles.numberLabel}>{label}</Text>
<Text style={styles.numberTitle}>{title}</Text>
{isMaster && (
<View style={styles.masterTag}>
<Text style={styles.masterTagText}>Master Number</Text>
</View>
)}
</View>
</View>
);
Implementing Caching Strategy
Cache numerology results to reduce API calls and improve performance:
// services/numerology-cache.ts
import AsyncStorage from '@react-native-async-storage/async-storage';
const CACHE_PREFIX = 'numerology_cache_';
const CACHE_DURATION = 30 * 24 * 60 * 60 * 1000; // 30 days
interface CacheEntry<T> {
data: T;
timestamp: number;
}
export class NumerologyCache {
private static generateKey(endpoint: string, params: Record<string, any>): string {
const sortedParams = Object.keys(params)
.sort()
.map(key => `${key}=${params[key]}`)
.join('&');
return `${CACHE_PREFIX}${endpoint}_${sortedParams}`;
}
static async get<T>(endpoint: string, params: Record<string, any>): Promise<T | null> {
try {
const key = this.generateKey(endpoint, params);
const cached = await AsyncStorage.getItem(key);
if (!cached) return null;
const entry: CacheEntry<T> = JSON.parse(cached);
const age = Date.now() - entry.timestamp;
if (age > CACHE_DURATION) {
await AsyncStorage.removeItem(key);
return null;
}
return entry.data;
} catch (error) {
console.error('Cache read error:', error);
return null;
}
}
static async set<T>(endpoint: string, params: Record<string, any>, data: T): Promise<void> {
try {
const key = this.generateKey(endpoint, params);
const entry: CacheEntry<T> = {
data,
timestamp: Date.now(),
};
await AsyncStorage.setItem(key, JSON.stringify(entry));
} catch (error) {
console.error('Cache write error:', error);
}
}
static async clear(): Promise<void> {
try {
const keys = await AsyncStorage.getAllKeys();
const cacheKeys = keys.filter(key => key.startsWith(CACHE_PREFIX));
await AsyncStorage.multiRemove(cacheKeys);
} catch (error) {
console.error('Cache clear error:', error);
}
}
}
Integrate caching into your API client:
class NumerologyAPI {
// ... existing code ...
async calculateLifePath(year: number, month: number, day: number) {
const params = { year, month, day };
const cached = await NumerologyCache.get('life-path', params);
if (cached) return cached;
const response = await this.client.post('/life-path', params);
await NumerologyCache.set('life-path', params, response.data);
return response.data;
}
async generateFullChart(fullName: string, year: number, month: number, day: number, currentYear?: number) {
const params = { fullName, year, month, day, currentYear: currentYear || new Date().getFullYear() };
const cached = await NumerologyCache.get('chart', params);
if (cached) return cached;
const response = await this.client.post('/chart', params);
await NumerologyCache.set('chart', params, response.data);
return response.data;
}
// Apply same pattern to other methods...
}
Building Compatibility Features
Compatibility analysis is perfect for dating apps and relationship tools:
// components/CompatibilityChecker.tsx
import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, ScrollView } from 'react-native';
import { createNumerologyAPI } from '../services/numerology-api';
const CompatibilityChecker: React.FC<{ apiKey: string }> = ({ apiKey }) => {
const [person1Name, setPerson1Name] = useState('');
const [person1Birth, setPerson1Birth] = useState({ year: '', month: '', day: '' });
const [person2Name, setPerson2Name] = useState('');
const [person2Birth, setPerson2Birth] = useState({ year: '', month: '', day: '' });
const [result, setResult] = useState<any>(null);
const [loading, setLoading] = useState(false);
const analyzeCompatibility = async () => {
setLoading(true);
try {
const api = createNumerologyAPI(apiKey);
// Calculate core numbers for both people
const person1LifePath = await api.calculateLifePath(
parseInt(person1Birth.year),
parseInt(person1Birth.month),
parseInt(person1Birth.day)
);
const person1Expression = await api.calculateExpression(person1Name);
const person1SoulUrge = await api.calculateSoulUrge(person1Name);
const person2LifePath = await api.calculateLifePath(
parseInt(person2Birth.year),
parseInt(person2Birth.month),
parseInt(person2Birth.day)
);
const person2Expression = await api.calculateExpression(person2Name);
const person2SoulUrge = await api.calculateSoulUrge(person2Name);
// Calculate compatibility
const compatibility = await api.calculateCompatibility(
{
lifePath: person1LifePath.number,
expression: person1Expression.number,
soulUrge: person1SoulUrge.number,
},
{
lifePath: person2LifePath.number,
expression: person2Expression.number,
soulUrge: person2SoulUrge.number,
}
);
setResult(compatibility);
} catch (error) {
alert(error.message);
} finally {
setLoading(false);
}
};
return (
<ScrollView style={styles.container}>
<Text style={styles.title}>Relationship Compatibility</Text>
{/* Person 1 inputs */}
<View style={styles.personSection}>
<Text style={styles.personLabel}>Person 1</Text>
<TextInput
style={styles.input}
value={person1Name}
onChangeText={setPerson1Name}
placeholder="Full name"
/>
{/* Birth date inputs... */}
</View>
{/* Person 2 inputs */}
<View style={styles.personSection}>
<Text style={styles.personLabel}>Person 2</Text>
<TextInput
style={styles.input}
value={person2Name}
onChangeText={setPerson2Name}
placeholder="Full name"
/>
{/* Birth date inputs... */}
</View>
<TouchableOpacity
style={styles.button}
onPress={analyzeCompatibility}
disabled={loading}
>
<Text style={styles.buttonText}>
{loading ? 'Analyzing...' : 'Check Compatibility'}
</Text>
</TouchableOpacity>
{result && (
<View style={styles.results}>
<View style={styles.scoreCircle}>
<Text style={styles.score}>{result.overallScore}</Text>
<Text style={styles.scoreLabel}>Compatibility</Text>
</View>
<Text style={styles.rating}>{result.rating}</Text>
<View style={styles.detailSection}>
<Text style={styles.detailTitle}>Life Path Compatibility</Text>
<Text style={styles.detailScore}>{result.lifePath.compatibility}%</Text>
<Text style={styles.detailDescription}>{result.lifePath.description}</Text>
</View>
<View style={styles.detailSection}>
<Text style={styles.detailTitle}>Expression Compatibility</Text>
<Text style={styles.detailScore}>{result.expression.compatibility}%</Text>
<Text style={styles.detailDescription}>{result.expression.description}</Text>
</View>
<View style={styles.detailSection}>
<Text style={styles.detailTitle}>Soul Urge Compatibility</Text>
<Text style={styles.detailScore}>{result.soulUrge.compatibility}%</Text>
<Text style={styles.detailDescription}>{result.soulUrge.description}</Text>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Relationship Strengths</Text>
{result.strengths.map((strength: string, index: number) => (
<Text key={index} style={styles.listItem}>• {strength}</Text>
))}
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>Potential Challenges</Text>
{result.challenges.map((challenge: string, index: number) => (
<Text key={index} style={styles.listItem}>• {challenge}</Text>
))}
</View>
<View style={styles.adviceBox}>
<Text style={styles.adviceTitle}>Relationship Advice</Text>
<Text style={styles.adviceText}>{result.advice}</Text>
</View>
</View>
)}
</ScrollView>
);
};
Rate Limiting and Usage Tracking
Implement client-side rate limiting to avoid hitting API limits:
// services/rate-limiter.ts
class RateLimiter {
private requests: number[] = [];
private readonly maxRequests: number;
private readonly windowMs: number;
constructor(maxRequests: number, windowMs: number) {
this.maxRequests = maxRequests;
this.windowMs = windowMs;
}
async canMakeRequest(): Promise<boolean> {
const now = Date.now();
this.requests = this.requests.filter(time => now - time < this.windowMs);
return this.requests.length < this.maxRequests;
}
recordRequest(): void {
this.requests.push(Date.now());
}
getRemainingRequests(): number {
const now = Date.now();
this.requests = this.requests.filter(time => now - time < this.windowMs);
return Math.max(0, this.maxRequests - this.requests.length);
}
}
// Create limiter (example: 100 requests per minute)
export const rateLimiter = new RateLimiter(100, 60000);
Use it in your API client:
class NumerologyAPI {
async calculateLifePath(year: number, month: number, day: number) {
if (!(await rateLimiter.canMakeRequest())) {
throw new Error('Rate limit exceeded. Please wait before making more requests.');
}
const response = await this.client.post('/life-path', { year, month, day });
rateLimiter.recordRequest();
return response.data;
}
}
Best Practices
Validate inputs client-side: Check name formats, date ranges, and number values before making API calls to avoid unnecessary requests.
Cache aggressively: Numerology results never change for the same inputs. Cache them locally and only fetch when truly needed.
Batch when possible: Use the full chart endpoint instead of making multiple individual calls. It is more efficient and provides better user experience.
Handle errors gracefully: Show user-friendly error messages. Network issues happen - provide retry options.
Display loading states: Numerology calculations return quickly, but users appreciate visual feedback during API calls.
Implement offline support: Cache results allow your app to work offline. Display cached data with a "last updated" timestamp.
Monitor usage: Track which endpoints users access most to optimize your caching strategy and feature priorities.
Security Considerations
Protect API keys: Never commit API keys to version control. Use environment variables or secure key storage.
Implement certificate pinning: For production apps, use certificate pinning to prevent man-in-the-middle attacks.
Validate responses: Always validate API response structure before using the data to prevent crashes from unexpected formats.
Use HTTPS only: Never make API calls over unencrypted connections.
Testing Your Integration
Write comprehensive tests for your numerology features:
describe('NumerologyAPI', () => {
const api = createNumerologyAPI(process.env.TEST_API_KEY);
it('calculates life path number correctly', async () => {
const result = await api.calculateLifePath(1990, 7, 15);
expect(result.number).toBeGreaterThanOrEqual(1);
expect(result.number).toBeLessThanOrEqual(33);
expect(result.meaning).toBeDefined();
expect(result.meaning.description).toBeTruthy();
});
it('handles invalid dates', async () => {
await expect(api.calculateLifePath(1800, 7, 15)).rejects.toThrow();
});
it('caches results correctly', async () => {
const result1 = await api.calculateLifePath(1990, 7, 15);
const result2 = await api.calculateLifePath(1990, 7, 15);
expect(result1).toEqual(result2);
});
});
Performance Monitoring
Track API performance to identify bottlenecks:
const api = createNumerologyAPI(API_KEY);
// Wrap API calls with performance tracking
async function trackAPICall<T>(
name: string,
apiCall: () => Promise<T>
): Promise<T> {
const start = Date.now();
try {
const result = await apiCall();
const duration = Date.now() - start;
analytics.logEvent('api_call_success', { name, duration });
return result;
} catch (error) {
const duration = Date.now() - start;
analytics.logEvent('api_call_failure', { name, duration, error: error.message });
throw error;
}
}
// Usage
const result = await trackAPICall(
'calculate_life_path',
() => api.calculateLifePath(1990, 7, 15)
);
Next Steps
You now have everything needed to integrate numerology into your application. Start with basic life path calculations, then expand to full charts and compatibility features as your users engage with the content.
The numerology API handles all the complex calculations and provides professional interpretations. Your job is to create beautiful interfaces that make these insights accessible and meaningful to your users.
For complete API documentation, response schemas, and additional code examples, visit RoxyAPI numerology documentation.
Need a numerology API? RoxyAPI provides production-ready numerology calculations with comprehensive interpretations. Life path, expression, soul urge, compatibility, complete charts—everything you need to build engaging numerology features. Start your integration today.