Migrating from V2 to V3 API
V2 API Retirement Notice
The V2 API will be retired and disabled on March 15, 2026. All V2 endpoints will return 410 Gone errors after this date. Please migrate to V3 before this deadline.
The V3 API represents a significant improvement over V2, with better performance, enhanced data quality, and new features like city-level holiday support. This guide will help you migrate your integration smoothly.
Why Migrate to V3?
The V3 API offers several advantages over V2:
- Better Performance: Optimized queries and improved caching (sub-100ms response times)
- City-Level Holidays: Support for 1000+ cities worldwide with granular location data
- Enhanced Data Model: Structured subdivision metadata and clearer response formats
- New Endpoints:
/checkendpoint for fast single-date validation - Improved Error Handling: More descriptive error messages and better status codes
- Future-Proof: All new features and improvements will be V3-only
Key Differences Between V2 and V3
Base URL Changes
V2:
https://api.getfestivo.com/v2/
V3:
https://api.getfestivo.com/v3/
Endpoint Changes
| V2 Endpoint | V3 Endpoint | Notes |
|---|---|---|
/v2/holidays | /v3/public-holidays/list | Renamed for clarity |
/v2/countries | /v3/countries | No change in path structure |
| N/A | /v3/public-holidays/check | New: Fast single-date validation |
Authentication
Authentication remains unchanged - both V2 and V3 use the same API key format:
X-API-Key: YOUR_API_KEY
Alternative (legacy compatibility): Query parameter:
?api_key=YOUR_API_KEY
Note: V2 supported Authorization: Bearer header, but V3 standardizes on X-API-Key header for better consistency. The query parameter method is maintained for backward compatibility but header authentication is preferred.
Request Parameters
Most parameters remain the same, with some additions in V3:
Common Parameters (Both V2 and V3):
country- ISO 3166-1 alpha-2 country codeyear- Year for holiday datalanguage- Response language
V3 Additions:
city- City name for city-specific holidays (new)region- Region/subdivision code (enhanced)
Response Format Changes
V3 introduces several improvements to the response format:
New Fields in V3
1. dataVersion Field
Every V3 response includes a dataVersion field indicating the schema version:
{
"dataVersion": "3.1.0",
"holidays": []
}
2. Enhanced regions Field
V3 provides structured subdivision data:
{
"regions": [
{
"code": "IT-MILAN",
"type": "city"
},
{
"code": "IT-88",
"type": "region"
}
]
}
3. deprecated Field
For features approaching end-of-life:
{
"deprecated": {
"message": "This endpoint will be retired on 2027-01-01",
"migrationGuide": "https://docs.getfestivo.com/migration"
}
}
Backward Compatible Fields
The following fields remain unchanged and work identically in both V2 and V3:
name- Holiday namedate- ISO 8601 datetype- Holiday type (public, observance, etc.)subdivisions- Array of subdivision codes (still supported, butregionsis recommended)
Migration Steps
Step 1: Update Your Base URL
Change all API calls from /v2/ to /v3/:
Before (V2):
const response = await fetch(
'https://api.getfestivo.com/v2/holidays?country=US&year=2024',
{
headers: {
'Authorization': `Bearer ${API_KEY}`
}
}
);
After (V3):
const response = await fetch(
'https://api.getfestivo.com/v3/public-holidays/list?country=US&year=2024',
{
headers: {
'X-API-Key': API_KEY
}
}
);
Step 2: Update Endpoint Paths
Replace endpoint names where applicable:
/v2/holidays→/v3/public-holidays/list/v2/countries→/v3/countries
Step 3: Handle New Response Fields (Optional)
If you want to take advantage of V3's enhanced features, update your code to handle new fields:
const data = await response.json();
// Access new structured region data
if (data.regions) {
data.regions.forEach(region => {
console.log(`${region.code} (${region.type})`);
});
}
// Check data version
console.log('API Version:', data.dataVersion);
// Handle deprecation notices
if (data.deprecated) {
console.warn('Deprecation notice:', data.deprecated.message);
}
Step 4: Test Your Integration
Before deploying to production:
- Test with sample requests using your actual API key
- Verify response parsing works with new fields
- Check error handling for new error formats
- Monitor response times (should be faster with V3)
Step 5: Deploy and Monitor
Once testing is complete:
- Deploy your updated integration
- Monitor for errors or unexpected behavior
- Check response times and API usage in your dashboard
Code Examples
Python
V2:
import requests
url = "https://api.getfestivo.com/v2/holidays"
params = {"country": "US", "year": 2024}
headers = {"Authorization": f"Bearer {API_KEY}"}
response = requests.get(url, params=params, headers=headers)
holidays = response.json()
V3:
import requests
url = "https://api.getfestivo.com/v3/public-holidays/list"
params = {"country": "US", "year": 2024}
headers = {"Authorization": f"Bearer {API_KEY}"}
response = requests.get(url, params=params, headers=headers)
data = response.json()
holidays = data['holidays']
Node.js
V2:
const axios = require('axios');
const response = await axios.get('https://api.getfestivo.com/v2/holidays', {
params: { country: 'US', year: 2024 },
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
const holidays = response.data;
V3:
const axios = require('axios');
const response = await axios.get('https://api.getfestivo.com/v3/public-holidays/list', {
params: { country: 'US', year: 2024 },
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
const { holidays, dataVersion } = response.data;
PHP
V2:
<?php
$url = "https://api.getfestivo.com/v2/holidays?country=US&year=2024";
$headers = ["Authorization: Bearer " . $apiKey];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$holidays = json_decode($response, true);
curl_close($ch);
V3:
<?php
$url = "https://api.getfestivo.com/v3/public-holidays/list?country=US&year=2024";
$headers = ["X-API-Key: " . $apiKey];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);
$holidays = $data['holidays'];
curl_close($ch);
Using the New /check Endpoint
V3 introduces a /check endpoint for fast, single-date validation:
curl "https://api.getfestivo.com/v3/public-holidays/check?country=IT&date=2024-12-25" \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"isHoliday": true,
"isWorkingDay": false,
"name": "Christmas Day",
"date": "2024-12-25",
"subdivisions": ["IT"]
}
This is much faster than fetching the full holiday list when you only need to check a single date.
City-Level Holiday Support
V3 adds support for city-specific holidays. Simply add the city parameter:
curl "https://api.getfestivo.com/v3/public-holidays/list?country=IT&city=Milan&year=2024" \
-H "X-API-Key: YOUR_API_KEY"
The response includes both national and Milan-specific holidays.
Error Handling
V3 provides more detailed error messages:
V2 Error:
{
"error": "Invalid country code"
}
V3 Error:
{
"error": {
"code": "INVALID_COUNTRY",
"message": "The country code 'XX' is not valid",
"details": "Please use ISO 3166-1 alpha-2 country codes (e.g., 'US', 'GB', 'DE')",
"documentation": "https://docs.getfestivo.com/api/countries"
}
}
Rate Limits
Rate limits remain the same between V2 and V3, based on your subscription plan. Check your dashboard for current limits.
SDK Updates
We've released brand new official SDKs with full V3 support. All legacy SDKs and packages are now deprecated.
New Official SDKs (V3 Compatible)
Python:
pip install festivo-python
Node.js:
npm install @festivo-io/festivo-sdk
PHP:
composer require festivo-io/festivo-php
Ruby:
gem install festivo
Go:
go get github.com/festivo-io/festivo-sdk-go
Java:
- Maven:
<dependency> <groupId>io.github.festivo-io</groupId> <artifactId>festivo-sdk</artifactId> <version>0.2.1</version> </dependency> - Gradle:
implementation 'io.github.festivo-io:festivo-sdk:0.2.1'
Deprecated Legacy SDKs & Packages
All previous SDK versions and unofficial packages are deprecated and will not receive updates:
⚠️ Deprecated Python Packages:
festivo-api(old unofficial package)festivo< 3.0.0 (pre-2026 versions)holiday-api-python(unmaintained)
⚠️ Deprecated Node.js Packages:
festivo(old package name, use@festivo-io/festivo-sdkinstead)@festivo/api< 3.0.0 (pre-2026 versions)@festivo/sdk(old scope, use@festivo-io/festivo-sdkinstead)holiday-api(unmaintained third-party package)- Any packages without
@festivo-io/scope
⚠️ Deprecated PHP Packages:
festivo/api< 3.0.0 (pre-2026 versions)holiday-api/php(unmaintained)
⚠️ Deprecated Ruby Gems:
festivo-api(old name)festivo< 3.0.0 (pre-2026 versions)
⚠️ Deprecated Go Packages:
github.com/festivo/api(old package path)- Any packages not from
github.com/festivo-io/festivo-sdk-go
⚠️ Deprecated Java Libraries:
com.festivo:api< 3.0.0 (pre-2026 versions)
What's New in V3 SDKs
All new official SDKs include:
- ✅ Full V3 API Support: All new endpoints including
/check - ✅ Type Safety: Complete TypeScript definitions and static typing
- ✅ Async/Await: Modern asynchronous patterns
- ✅ Better Error Handling: Detailed error messages and typed exceptions
- ✅ City-Level Support: Built-in support for city-specific holidays
- ✅ Comprehensive Docs: Full API documentation and code examples
- ✅ Active Maintenance: Regular updates and bug fixes
- ✅ Production Ready: Tested and used by thousands of developers
Migration from Legacy SDKs
If you're using an old SDK, follow these steps:
- Uninstall the old package
- Install the new official SDK (see commands above)
- Update import statements to use the new package names
- Update API calls to use V3 endpoints (most SDKs handle this automatically)
- Test your integration with the new SDK
For detailed SDK-specific migration guides, see our Getting Started guide and Code Examples.
Troubleshooting
Common Migration Issues
Issue: Getting 404 errors
- Solution: Ensure you're using
/v3/public-holidays/listinstead of/v2/holidays
Issue: Response format different than expected
- Solution: V3 wraps holiday data in a
holidaysarray within a response object. Update your parsing logic.
Issue: City parameter not working
- Solution: City-level access requires an appropriate subscription plan. Check your plan limits in the dashboard.
Issue: Authentication failing
- Solution: API keys work the same in V2 and V3. Verify your key is active in your dashboard.
Getting Help
Need assistance with your migration?
- Email: support@getfestivo.com
- Documentation: https://docs.getfestivo.com
- Support Portal: https://festivo.atlassian.net/servicedesk
We're here to help make your migration as smooth as possible!
Important Dates
- Now: V3 API is live and fully supported
- March 15, 2026 (in 20 days): V2 API will be completely disabled
- After March 15, 2026: All V2 requests will return
410 Goneerrors
⚠️ URGENT ACTION REQUIRED - Migrate immediately to avoid service disruption. V3's improved features and performance make migration straightforward.