Spain public holidays API

Every holiday.
Every town.

National + regional + fiestas patronales for all 8,132 Spanish municipios — as one clean JSON feed. Built for payroll, HR, and scheduling that needs to know: is this a working day in this specific town?

Built for Payroll software HR platforms Scheduling tools Absence management Compliance automation Calendar integrations
0municipios indexed
0100% accounted for
0autonomous regions
    Pick a community, search for a municipio, choose a date — then hit Try it live.
    Sample response
    "is_holiday": true,
    "matches": [{
      "name": "Día de la Hispanidad",
      "scope": "nacional"
    }],
    "next": {
      "date": "2026-12-06",
      "name": "Constitución española",
      "days_away": 146
    }

    Quick start

    Get a free key instantly — no signup form, no email required:

    Your API key — save it somewhere safe
    100 req / day free · upgrade anytime

    Prefer the terminal? curl -s -X POST https://festivos.dsl4.com/v1/signup

    Then call the API:

    curl -s "https://festivos.dsl4.com/v1/is-holiday?date=2026-05-15&municipio=28079" \
      -H "X-API-Key: YOUR_KEY"

    Or use the public demo key demo_key_festivos_2026 for evaluation (tight rate limit).

    Endpoints

    GET
    /v1/holidays?municipio=&year=

    Every holiday (national + regional + island + local) for a municipio in a given year.

    GET
    /v1/is-holiday?date=&municipio=

    Is this exact date a holiday here? Returns matches + a local_coverage honesty flag.

    GET
    /v1/next?municipio=&from=

    The next upcoming holiday for a municipio. Defaults from to today.

    GET
    /v1/municipios?q=&ccaa=&province=

    Search the 8,000+ municipio registry by name or region to find an INE code.

    GET
    /v1/ccaa  ·  /v1/coverage

    Reference data + the local-coverage honesty ledger. No API key required.

    POST
    /v1/signup

    Instant free-tier API key. JSON response, no email required.

    municipio accepts a 5-digit INE code (e.g. 28079) or an exact/prefix name match (e.g. San Cristóbal de La Laguna).

    Authentication & rate limits

    Pass your key as an X-API-Key header (preferred) or ?api_key= query param. All /v1/* endpoints require a key except /v1/ccaa, /v1/coverage, and POST /v1/signup.

    Each tier has a daily request cap counted per key per UTC day. Every authenticated response tells you where you stand:

    X-RateLimit-Limit: 100
    X-RateLimit-Remaining: 99

    Over the cap → 429 with Retry-After. Counter resets at midnight UTC. Invalid keys → 401.

    Code examples

    Full spec: OpenAPI 3.1 · llms.txt for agent use

    Is this date a holiday?

    curl -s "https://festivos.dsl4.com/v1/is-holiday?date=2026-05-15&municipio=28079" \
      -H "X-API-Key: YOUR_KEY"
    const res = await fetch(
      "https://festivos.dsl4.com/v1/is-holiday?date=2026-05-15&municipio=28079",
      { headers: { "X-API-Key": "YOUR_KEY" } }
    );
    const data = await res.json();
    console.log(data.is_holiday); // true
    import requests
    
    resp = requests.get(
        "https://festivos.dsl4.com/v1/is-holiday",
        params={"date": "2026-05-15", "municipio": "28079"},
        headers={"X-API-Key": "YOUR_KEY"},
    )
    print(resp.json()["is_holiday"])  # True

    Next holiday for a municipio

    curl -s "https://festivos.dsl4.com/v1/next?municipio=35016" \
      -H "X-API-Key: YOUR_KEY"
    const res = await fetch("https://festivos.dsl4.com/v1/next?municipio=35016", {
      headers: { "X-API-Key": "YOUR_KEY" },
    });
    const { next } = await res.json();
    console.log(next.date, next.name);
    import requests
    
    resp = requests.get(
        "https://festivos.dsl4.com/v1/next",
        params={"municipio": "35016"},
        headers={"X-API-Key": "YOUR_KEY"},
    )
    nxt = resp.json()["next"]
    print(nxt["date"], nxt["name"])

    Coverage check (no key required)

    curl -s "https://festivos.dsl4.com/v1/coverage"
    const res = await fetch("https://festivos.dsl4.com/v1/coverage");
    const data = await res.json();
    console.log(data.pct_accounted); // 100
    import requests
    
    resp = requests.get("https://festivos.dsl4.com/v1/coverage")
    print(resp.json()["pct_accounted"])  # 100

    Coverage — honestly, per region

    National + all 19 regional calendars are 100% complete. Local fiestas patronales are real data from official open-data portals and gazette sources — we do not claim full national local coverage. All 8,132 municipios are accounted for: ~7,700 carry real local-fiesta data, the rest are verified none-declared. /v1/holidays returns local_fiestas_declared: true/false/null so you can distinguish "has fiestas" from "verified none" from "unknown". See /v1/coverage for the live machine-readable version.

    Has local fiestas Verified none-declared Bars fill to 100% accounted; the darker slice is real fiesta data.
    Castilla y León
    2077/2248
    accounted
    Cataluña
    917/947
    accounted
    Castilla-La Mancha
    909/919
    accounted
    Andalucía
    774/785
    accounted
    Aragón
    581/731
    accounted
    Comunitat Valenciana
    539/542
    accounted
    Extremadura
    388/388
    complete
    Galicia
    313/313
    complete
    País Vasco
    252/252
    complete
    Comunidad Foral de Navarra
    249/272
    accounted
    Comunidad de Madrid
    179/179
    complete
    La Rioja
    171/174
    accounted
    Cantabria
    102/102
    complete
    Canarias
    88/88
    complete
    Principado de Asturias
    78/78
    complete
    Illes Balears
    67/67
    complete
    Región de Murcia
    45/45
    complete
    Ciudad de Ceuta
    1/1
    complete
    Ciudad de Melilla
    1/1
    complete

    Pricing

    Free
    €0
    • 100 requests / day
    • Full national + CCAA data
    • Instant key, no email
    Get a key
    Pro
    €19 / mo
    • 200,000 requests / day
    • Priority support
    • Early access to new regions
    Subscribe

    Already have a free key? Append ?client_reference_id=YOUR_KEY to the Payment Link to upgrade that same key.