feriados.io ← Inicio
phplaravelsymfonytutorialintegracion

API de feriados en PHP: integración con Laravel y Symfony

Cómo integrar la API de feriados.io en PHP. Ejemplos con file_get_contents, cURL, Laravel Http facade y Symfony HttpClient para validar días hábiles en LATAM.

4 de marzo de 2026

Si tu stack es PHP — ya sea Laravel, Symfony o vanilla — integrar la API de feriados.io es cuestión de minutos. Todos los endpoints responden JSON estándar y usan autenticación Bearer token, que cualquier cliente HTTP de PHP soporta sin dependencias adicionales.

Autenticación

Todos los endpoints requieren un API key en el header Authorization:

Authorization: Bearer frd_tu_api_key

Guardá el API key en tus variables de entorno, nunca en el código:

# .env
FERIADOS_API_KEY=frd_tu_api_key

Con file_get_contents (sin dependencias)

<?php

$apiKey = getenv('FERIADOS_API_KEY');
$date   = date('Y-m-d'); // hoy

$context = stream_context_create([
    'http' => [
        'header' => "Authorization: Bearer {$apiKey}\r\n",
    ],
]);

$url  = "https://api.feriados.io/v1/CL/is-business-day?date={$date}";
$res  = file_get_contents($url, false, $context);
$data = json_decode($res, true)['data'];

if (!$data['is_business_day']) {
    echo "Hoy es feriado en Chile ({$data['day_of_week']}), saltando proceso.";
} else {
    procesarCobros();
}

Con cURL

<?php

function isBusinessDay(string $country, string $date): bool
{
    $apiKey = getenv('FERIADOS_API_KEY');
    $url    = "https://api.feriados.io/v1/{$country}/is-business-day?date={$date}";

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ["Authorization: Bearer {$apiKey}"],
    ]);

    $res  = curl_exec($ch);
    curl_close($ch);

    return json_decode($res, true)['data']['is_business_day'];
}

function addBusinessDays(string $country, string $date, int $days): string
{
    $apiKey = getenv('FERIADOS_API_KEY');
    $url    = "https://api.feriados.io/v1/{$country}/business-days/add"
            . "?date={$date}&days={$days}";

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ["Authorization: Bearer {$apiKey}"],
    ]);

    $res  = curl_exec($ch);
    curl_close($ch);

    return json_decode($res, true)['data']['result_date'];
}

// Uso
$hoy      = date('Y-m-d');
$esHabil  = isBusinessDay('CO', $hoy);
$entrega  = addBusinessDays('MX', $hoy, 5);  // requiere plan Starter, Team o Business

Con Laravel (Http facade)

<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;

class FeriadosService
{
    private string $baseUrl = 'https://api.feriados.io/v1';

    private function client()
    {
        return Http::withToken(config('services.feriados.key'));
    }

    public function isBusinessDay(string $country, string $date): bool
    {
        $res = $this->client()
            ->get("{$this->baseUrl}/{$country}/is-business-day", [
                'date' => $date,
            ]);

        return $res->json('data.is_business_day');
    }

    public function addBusinessDays(string $country, string $date, int $days): string
    {
        $res = $this->client()
            ->get("{$this->baseUrl}/{$country}/business-days/add", [
                'date' => $date,
                'days' => $days,
            ]);

        return $res->json('data.result_date');
    }

    public function countBusinessDays(string $country, string $from, string $to): int
    {
        $res = $this->client()
            ->get("{$this->baseUrl}/{$country}/business-days/between", [
                'from' => $from,
                'to'   => $to,
            ]);

        return $res->json('data.business_days');
    }
}

Registrá la key en config/services.php:

'feriados' => [
    'key' => env('FERIADOS_API_KEY'),
],

Uso en un controller:

public function calcularEntrega(Request $request, FeriadosService $feriados): JsonResponse
{
    $fechaDespacho = $request->date('fecha_despacho')->toDateString();
    $fechaEntrega  = $feriados->addBusinessDays('CL', $fechaDespacho, 3);

    return response()->json(['entrega' => $fechaEntrega]);
}

Con Symfony (HttpClient)

<?php

namespace App\Service;

use Symfony\Contracts\HttpClient\HttpClientInterface;

class FeriadosClient
{
    private const BASE = 'https://api.feriados.io/v1';

    public function __construct(
        private HttpClientInterface $http,
        private string $apiKey
    ) {}

    public function isBusinessDay(string $country, string $date): bool
    {
        $res = $this->http->request('GET', self::BASE . "/{$country}/is-business-day", [
            'headers' => ['Authorization' => "Bearer {$this->apiKey}"],
            'query'   => ['date' => $date],
        ]);

        return $res->toArray()['data']['is_business_day'];
    }

    public function nextHoliday(string $country): array
    {
        $res = $this->http->request('GET', self::BASE . "/{$country}/next-holiday", [
            'headers' => ['Authorization' => "Bearer {$this->apiKey}"],
        ]);

        return $res->toArray()['data'];
    }
}

En services.yaml:

App\Service\FeriadosClient:
    arguments:
        $apiKey: '%env(FERIADOS_API_KEY)%'

Manejo de errores

La API devuelve siempre un success: bool. Para producción, validá el status HTTP y el campo success:

function safeIsBusinessDay(string $country, string $date): ?bool
{
    $apiKey = getenv('FERIADOS_API_KEY');
    $url    = "https://api.feriados.io/v1/{$country}/is-business-day?date={$date}";

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ["Authorization: Bearer {$apiKey}"],
        CURLOPT_TIMEOUT        => 3,
    ]);

    $body   = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($body === false || $status !== 200) {
        return null; // fallback a tu lógica default
    }

    $json = json_decode($body, true);
    return $json['success'] ? $json['data']['is_business_day'] : null;
}

Los errores retornan success: false con error.code y error.status. Los más comunes: API_KEY_REQUIRED (401), RATE_LIMIT_EXCEEDED (429), COUNTRY_NOT_SUPPORTED (404).


¿Necesitas esto en producción? Empezar gratis — API key en 30 segundos, sin tarjeta →


Ver también: Documentación completa de endpoints → · Calcular días hábiles en JavaScript → · API de feriados para LATAM →

Integra feriados.io en tu proyecto

API key gratis en 30 segundos. Sin tarjeta. 11 países de Latinoamérica, siempre actualizada con los feriados oficiales.

← Ver todos los artículos