FAQ & Best Practices
Common questions and best practices for using the Festivo API effectively.
Frequently Asked Questions
How do city-level holidays work?
City-level holidays are local observances specific to individual cities, such as patron saint days in Italy. These holidays are not recognized nationally but are official in specific cities.
Example: Milan celebrates the Feast of Saint Ambrose (Sant'Ambrogio) on December 7th. This is a public holiday in Milan but not in other Italian cities.
To query city-level holidays, use the regions parameter with city code format {COUNTRY_CODE}-{CITY} (Pro plan):
1import { FestivoClient } from '@festivo-io/festivo-sdk'23const client = new FestivoClient({ apiKey: process.env.FESTIVO_API_KEY })4const res = await client.request('/v3/public-holidays/list?country=IT®ions=IT-MILAN&year=2026')5console.log(res.holidays)6
What are ISO 3166-2 subdivision codes?
ISO 3166-2 is the international standard for subdivision codes (states, provinces, regions). Festivo uses these codes for precise regional filtering.
Format: {COUNTRY}-{SUBDIVISION}
Examples:
GB-SCT- ScotlandUS-CA- CaliforniaDE-BY- BavariaFR-75- Paris
Use the regions parameter to filter by ISO codes (Builder plan and above).
How do I handle holidays in multiple timezones?
Use the timezone parameter to get holidays with accurate local times (Growth plan):
1import { FestivoClient } from '@festivo-io/festivo-sdk'23const client = new FestivoClient({ apiKey: process.env.FESTIVO_API_KEY })4const { holidays } = await client.getHolidays('JP', 2026, { timezone: 'Asia/Tokyo' })5// Timestamps are in Tokyo local time6console.log(holidays[0].start)7console.log(holidays[0].end)8
Supported timezones: All IANA timezone database names (e.g., America/New_York, Europe/London, Asia/Tokyo)
What's the difference between subdivisions and regions fields?
subdivisions(legacy): String array of subdivision codesregions(new): Structured array withcodeandtypefields
The regions field provides richer metadata:
1{2 "subdivisions": [3 "IT-MILAN"4 ],5 "regions": [6 {7 "code": "IT-MILAN",8 "type": "city"9 }10 ]11}
Use regions for new integrations to easily distinguish between city-level and region-level holidays.
How do I handle rate limits?
Rate limits vary by plan:
- Explorer (Free): 100 requests/day
- Builder: 10,000 requests/day
- Growth: 50,000 requests/day
- Pro: 200,000 requests/day
- Titan: Unlimited
Best practices:
- Cache holiday data (holidays don't change frequently)
- Fetch by year, not by day
- Implement exponential backoff for 429 errors
- Monitor
X-RateLimit-Remainingheader
Can I get holidays in different languages?
Yes! The language parameter supports 190+ languages (Growth plan and above):
1# Get German holidays with French names2curl "https://api.getfestivo.com/v3/public-holidays/list?country=DE&year=2026&language=fr&api_key=YOUR_API_KEY"
Holiday names will be returned in the specified language in the name field.
What does the observed field mean?
The observed field indicates when a holiday is actually observed, which may differ from the actual date.
Example: If Christmas (December 25) falls on Saturday, some countries observe it on Monday (December 27) as a substitute:
1{2 "date": "2026-12-25",3 "name": "Christmas Day",4 "observed": "2026-12-27",5 "substitute": true,6 "weekday": {7 "date": {8 "name": "Saturday",9 "numeric": 610 },11 "observed": {12 "name": "Monday",13 "numeric": 114 }15 }16}
Always use the observed field for business logic, scheduling, and compliance.
How accurate is the holiday data?
Festivo maintains one of the most accurate holiday databases globally:
- Sources: Government gazette publications, official announcements, legal codes
- Verification: Multi-source verification for each holiday
- Updates: Real-time updates when governments announce changes
- Coverage: 250+ countries, 5,500+ regions, 1,000+ cities
- Historical Data: Available back to 2000
- Future Data: Up to 5 years in advance (where officially announced)
Can I filter by holiday type?
Yes! Use the type parameter to filter by holiday category (Builder plan):
Available types:
public- Official public holidaysbank- Bank holidaysobservance- Widely observed but not officialregional- Region or city-specificreligious- Religious observances
1# Get only public holidays2curl "https://api.getfestivo.com/v3/public-holidays/list?country=GB&year=2026&type=public&api_key=YOUR_API_KEY"
What's the dataVersion field for?
The dataVersion field indicates the schema version of the holiday data, helping you:
- Track which data model version you're working with
- Handle API evolution safely
- Implement version-specific logic when needed
Example: "dataVersion": "3.1.0" indicates you're receiving the latest schema with enhanced regions field support.
Best Practices
1. Cache Holiday Data
Holidays don't change frequently. Cache them to improve performance:
Recommended caching strategy:
- Cache duration: 24 hours
- Cache key:
holidays:{country}:{city}:{year} - Invalidation: Manual or on API update notifications
2. Fetch by Year, Not by Day
Instead of checking individual dates, fetch all holidays for the year once and filter locally:
✅ Good:
// Fetch once per year
const holidays = await getHolidays("IT", "Milan", 2026);
const isHoliday = holidays.some((h) => h.observed === "2026-12-07");
❌ Avoid:
// Don't make separate API call for each date
const isHoliday = await checkDate("IT", "Milan", "2026-12-07");
3. Use Structured regions Field
Leverage the new regions field for cleaner, more maintainable code:
1// Filter city-specific holidays2const cityHolidays = holidays.filter(h =>3h.regions.some(r => r.type === 'city')4);56// Check if holiday applies to specific location7function appliesToLocation(holiday, locationCode) {8return holiday.regions.some(r => r.code === locationCode);9}
4. Handle Timezone Observances Correctly
For global operations, always use timezone-aware queries:
1# Get holidays with local timezone2holidays = get_holidays_with_timezone(3 country="JP",4 year=2026,5 timezone="Asia/Tokyo"6)78# Parse timestamps correctly910from datetime import datetime11start_time = datetime.fromisoformat(holidays[0]['start'])12print(f"Holiday starts at: {start_time} JST")
5. Test with City-Level Data
When testing integrations, use cities with known local holidays:
Good test cities:
- Milan, Italy - Feast of Saint Ambrose (Dec 7)
- Rome, Italy - Saints Peter and Paul (June 29)
- Munich, Germany - Various local festivals
- Barcelona, Spain - La Mercè festival
6. Monitor API Status
Check the API Status Page for:
- Real-time uptime monitoring
- Scheduled maintenance windows
- Incident reports
- Performance metrics
7. Use the Right Plan for Your Needs
Choose based on your requirements:
- Explorer (Free): Testing and small projects
- Builder: Regional/subdivision filtering needed
- Growth: Multilingual support required
- Pro: City-level data essential
- Titan: High-volume enterprise use
Performance Tips
Batch Requests Efficiently
If you need holidays for multiple locations, batch them:
1async function getHolidaysForMultipleCities(cityConfigs, year) {2const requests = cityConfigs.map(({ country, cityCode }) =>3 fetch(`https://api.getfestivo.com/v3/public-holidays/list?country=${country}®ions=${cityCode}&year=${year}&api_key=YOUR_API_KEY`)4 .then(r => r.json())5);67const results = await Promise.all(requests);89return cityConfigs.map((location, i) => ({10location,11holidays: results[i].holidays12}));13}1415// Usage: Get holidays for multiple office locations16// City codes follow format: {COUNTRY_CODE}-{CITY}17const offices = [18{ country: "IT", cityCode: "IT-MILAN" },19{ country: "IT", cityCode: "IT-ROME" },20{ country: "DE", cityCode: "DE-MUNICH" }21];2223const allHolidays = await getHolidaysForMultipleCities(offices, 2026);
Filter Locally When Possible
Fetch broader data sets and filter on your end:
1// Fetch once for entire year2const allHolidays = await getHolidays("IT", "Milan", 2026);34// Filter locally for different needs5const publicOnly = allHolidays.filter(h => h.public);6const december = allHolidays.filter(h => h.date.startsWith('2026-12'));7const citySpecific = allHolidays.filter(h =>8h.regions.some(r => r.type === 'city')9);
Troubleshooting
401 Unauthorized
Cause: Invalid or missing API key
Solution:
- Verify your API key is correct
- Check that it's properly included in the request
- Ensure key hasn't been revoked or expired
403 Forbidden
Cause: Attempting to use features not available in your plan
Solution:
- Check feature availability in plan comparison
- Upgrade to access premium features
- Example:
cityparameter requires Pro plan
429 Rate Limit Exceeded
Cause: Too many requests for your plan tier
Solution:
- Implement caching
- Reduce request frequency
- Upgrade to higher plan tier
- Use
X-RateLimit-*headers to track usage
Need More Help?
- Email Support: support@getfestivo.com
- API Reference: /docs/api-reference
- Code Examples: /docs/examples
- Tutorials: /docs/tutorials
- Status Page: status.getfestivo.com