Skip to content

Developers

Free public API for holidays, HTTP status codes, colors and CPF/CNPJ

arielton.com runs a free, read-only JSON API at https://www.arielton.com/api/v1 with public holidays for Brazil, the United States and Portugal, every HTTP status code, the CSS and Tailwind CSS v4 colors, and CPF/CNPJ check-digit validation. There is no key and no signup, and CORS is open to any origin, so you can call it straight from the browser.

Quick start

Every endpoint is a plain HTTPS GET that returns JSON. Try one in a terminal:

curl
curl https://www.arielton.com/api/v1/holidays/brazil/2026
API basics
Base URLhttps://www.arielton.com/api/v1
AuthenticationNone, no key or signup
FormatJSON, UTF-8, pretty-printed
CORSAccess-Control-Allow-Origin: * on every response
CachingReference data: public, max-age=86400. CPF/CNPJ: no-store
VersioningPath prefix /v1. Breaking changes would ship as /v2
IndexGET /api/v1 lists every endpoint

Endpoints

Endpoints
MethodPathReturns
GET/api/v1/holidays/{country}/{year}Every national, federal and optional holiday of one country in one year
GET/api/v1/http-statusEvery code with its title, class and one-line meaning
GET/api/v1/http-status/{code}One code with retry, caching and spec details
GET/api/v1/colorsAll 148 CSS named colors and 286 Tailwind CSS v4 colors with hex values
GET/api/v1/colors/{name}One color in hex, RGB, HSL and OKLCH with WCAG contrast
GET/api/v1/cpf/validate/{cpf}Check-digit verdict for one CPF
POST/api/v1/cpf/validateSame, with the number in the JSON body
GET/api/v1/cnpj/validate/{cnpj}Check-digit verdict for one CNPJ, numeric or alphanumeric
POST/api/v1/cnpj/validateSame, with the number in the JSON body

Every response also has source (the page on arielton.com the data comes from), docs, attribution and, for reference data, updated.

Public holidays

  • GET /api/v1/holidays/{country}/{year}

Holidays for Brazil, the United States and Portugal in 2026, 2027 and 2028, computed from the legal rules rather than scraped: Lei 662/1949, Lei 9.093/1995, Lei 6.802/1980, Lei 14.759/2023 and the Portaria MGI 11.460/2025 for Brazil; 5 U.S.C. 6103 and the OPM schedules for the US; articles 234 and 235 of the Código do Trabalho for Portugal.

Brazilian pontos facultativos (Carnival, Corpus Christi, Ash Wednesday until 2 pm) and the Portuguese feriado facultativo (Carnival) come back with type "optional". Filter them out when you need days off that apply to everyone. State and municipal holidays are not included.

Parameters

Public holidays: Parameters
NameInDescription
countrypathbrazil, united-states or portugal, or the lowercase ISO 3166-1 code: br, us, pt.
yearpath2026, 2027 or 2028.

Examples

curl
curl https://www.arielton.com/api/v1/holidays/brazil/2026
JavaScript (fetch)
const res = await fetch('https://www.arielton.com/api/v1/holidays/br/2027');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { holidays } = await res.json();
const daysOff = holidays
  .filter((h) => h.type !== 'optional')
  .map((h) => h.observed);
Python (requests)
import requests

res = requests.get("https://www.arielton.com/api/v1/holidays/united-states/2027", timeout=10)
res.raise_for_status()
for h in res.json()["holidays"]:
    print(h["observed"], h["name"]["en"])

Response fields

Public holidays: Response fields
FieldTypeDescription
countryobjectslug, ISO code and name in English and Portuguese.
countnumberNumber of items in holidays.
holidays[].idstringStable identifier, e.g. tiradentes or juneteenth.
holidays[].datestringLegal date, YYYY-MM-DD.
holidays[].observedstringThe day off. Differs from date only for US federal holidays on a weekend: Saturday moves to Friday, Sunday to Monday. New Year's Day on a Saturday is observed on December 31 of the previous year.
holidays[].weekdaystringWeekday of date, lowercase English (monday).
holidays[].typestringnational (Brazil, Portugal), federal (US) or optional.
holidays[].nameobjectName in English (en) and Portuguese (pt).
holidays[].officialNamestringName in the country's official language, as the law writes it.
holidays[].legalBasisstringLaw or ordinance that creates the day.
holidays[].ruleobjectHow the date is set, in words (fixed, days after Easter, third Monday).
holidays[].movablebooleantrue for days tied to Easter.
holidays[].partialDayobject | nullPart-day optional days, e.g. Ash Wednesday until 2 pm.
holidays[].federalStaffOnlybooleantrue for Dia do Servidor Público (federal civil servants only).

Sample response

Brazil 2026, first 2 of 19 items shown.
{
  "country": {
    "slug": "brazil",
    "code": "BR",
    "name": {
      "en": "Brazil",
      "pt": "Brasil"
    }
  },
  "year": 2026,
  "count": 19,
  "holidays": [
    {
      "id": "confraternizacao",
      "date": "2026-01-01",
      "observed": "2026-01-01",
      "weekday": "thursday",
      "type": "national",
      "name": {
        "en": "New Year's Day",
        "pt": "Confraternização Universal"
      },
      "officialName": "Confraternização Universal",
      "legalBasis": "Lei 662/1949",
      "rule": {
        "en": "Fixed: January 1",
        "pt": "Fixo: 1º de janeiro"
      },
      "movable": false,
      "partialDay": null,
      "federalStaffOnly": false
    },
    {
      "id": "carnaval-segunda",
      "date": "2026-02-16",
      "observed": "2026-02-16",
      "weekday": "monday",
      "type": "optional",
      "name": {
        "en": "Carnival Monday",
        "pt": "Carnaval (segunda-feira)"
      },
      "officialName": "Carnaval",
      "legalBasis": "Portaria MGI",
      "rule": {
        "en": "48 days before Easter",
        "pt": "48 dias antes da Páscoa"
      },
      "movable": true,
      "partialDay": null,
      "federalStaffOnly": false
    }
  ],
  "updated": "2026-09-27",
  "source": "https://www.arielton.com/holidays/brazil/2026",
  "docs": "https://www.arielton.com/developers#holidays",
  "attribution": "Data by Arielton Oberek (arielton.com). Free to use; please link to the source URL when you publish it."
}

HTTP status codes

  • GET /api/v1/http-status
  • GET /api/v1/http-status/{code}

The registered codes from the IANA HTTP Status Code Registry and RFC 9110, plus the unofficial ones that show up in real logs: nginx 444 and 499 and the Cloudflare 520 to 526 range, flagged with official: false.

Each item carries a one-line meaning in English and Portuguese that you can show next to an error, and a link to the section of the RFC that defines it.

Parameters

HTTP status codes: Parameters
NameInDescription
codepathThree-digit status code, e.g. 404. The list endpoint shows every code available.

Examples

curl
curl https://www.arielton.com/api/v1/http-status/429
JavaScript (fetch)
const res = await fetch('https://www.arielton.com/api/v1/http-status/503');
const status = await res.json();
console.log(`${status.code} ${status.title}: ${status.meaning.en}`);
Python (requests)
import requests

codes = requests.get("https://www.arielton.com/api/v1/http-status", timeout=10).json()["statuses"]
server_errors = [s["code"] for s in codes if s["class"] == "server"]
print(server_errors)

Response fields

HTTP status codes: Response fields
FieldTypeDescription
codenumberThe status code.
titlestringRegistered reason phrase (Not Found).
titlePtstringPortuguese gloss of the title (Não encontrado).
classstringinformational, success, redirection, client, server or unofficial. classInfo adds the range (4xx) and a readable name.
meaningobjectOne-line meaning in en and pt.
officialbooleanfalse for nginx and Cloudflare codes; unofficialBy says which.
retryobjectWhether a client may retry, in a short phrase.
cacheablestringheuristic (cacheable by default, RFC 9110 section 15.1), explicit (only with Cache-Control or Expires), never, or validator (304).
specobjectlabel and url of the defining document.
deprecatedobject | nullSet for reserved or obsolete codes.

Sample response

GET /api/v1/http-status/429
{
  "code": 429,
  "title": "Too Many Requests",
  "titlePt": "Pedidos demais",
  "class": "client",
  "meaning": {
    "en": "Rate limited: too many requests in a time window. Wait, then retry.",
    "pt": "Limite de taxa atingido: pedidos demais num intervalo. Espere e tente de novo."
  },
  "official": true,
  "source": "https://www.arielton.com/http-status/429",
  "classInfo": {
    "key": "client",
    "range": "4xx",
    "name": {
      "en": "Client errors",
      "pt": "Erros do cliente"
    }
  },
  "alsoKnownAs": [],
  "unofficialBy": null,
  "deprecated": null,
  "retry": {
    "en": "Yes, after the delay in Retry-After, or with exponential backoff and jitter if there is none",
    "pt": "Sim, depois do tempo indicado em Retry-After, ou com espera exponencial e jitter se ele não vier"
  },
  "cacheable": "never",
  "spec": {
    "label": "RFC 6585 §4",
    "url": "https://www.rfc-editor.org/rfc/rfc6585#section-4"
  },
  "updated": "2026-09-27",
  "docs": "https://www.arielton.com/developers#http-status",
  "attribution": "Data by Arielton Oberek (arielton.com). Free to use; please link to the source URL when you publish it."
}

Colors

  • GET /api/v1/colors
  • GET /api/v1/colors/{name}

The 148 named colors of CSS Color Module Level 4 and the Tailwind CSS v4 default palette (tailwindcss 4.3.3). Tailwind v4 defines its colors in OKLCH; tailwind.token is the exact theme value, and hex is the sRGB value after CSS Color 4 gamut mapping when the color falls outside sRGB (inSrgbGamut: false).

Contrast ratios follow WCAG 2.x and are floored to two decimals, so a ratio of 4.499 reports 4.49 and fails AA instead of rounding up to a pass.

Parameters

Colors: Parameters
NameInDescription
namepathA CSS keyword in lowercase (rebeccapurple) or a Tailwind color as hue-shade (blue-500).

Examples

curl
curl https://www.arielton.com/api/v1/colors/rebeccapurple
JavaScript (fetch)
const res = await fetch('https://www.arielton.com/api/v1/colors/blue-500');
const color = await res.json();
button.style.background = color.css.oklch;
button.style.color = color.contrast.bestText;
Python (requests)
import requests

c = requests.get("https://www.arielton.com/api/v1/colors/teal", timeout=10).json()
print(c["hex"], c["contrast"]["white"]["ratio"], c["contrast"]["white"]["aa"])

Response fields

Colors: Response fields
FieldTypeDescription
kindstringcss or tailwind.
hexstringLowercase #rrggbb.
rgb / hsl / oklchobjectNumeric channels. oklch.l runs from 0 to 1.
cssobjectReady-to-paste CSS strings for hex, rgb(), hsl() and oklch().
contrastobjectRatio against white and black with AA/AAA pass flags for normal and large text, and bestText: the text color with more contrast.
aliases / familystring[] / stringCSS colors only: same-value keywords (gray, grey) and hue family.
tailwindobjectTailwind colors only: hue, shade, token, inSrgbGamut.

Sample response

GET /api/v1/colors/rebeccapurple
{
  "name": "rebeccapurple",
  "kind": "css",
  "hex": "#663399",
  "rgb": {
    "r": 102,
    "g": 51,
    "b": 153
  },
  "hsl": {
    "h": 270,
    "s": 50,
    "l": 40
  },
  "oklch": {
    "l": 0.4403,
    "c": 0.1603,
    "h": 303.37
  },
  "css": {
    "hex": "#663399",
    "rgb": "rgb(102, 51, 153)",
    "hsl": "hsl(270, 50%, 40%)",
    "oklch": "oklch(44% 0.16 303.4)"
  },
  "contrast": {
    "white": {
      "ratio": 8.4,
      "aa": true,
      "aaLarge": true,
      "aaa": true,
      "aaaLarge": true
    },
    "black": {
      "ratio": 2.49,
      "aa": false,
      "aaLarge": false,
      "aaa": false,
      "aaaLarge": false
    },
    "bestText": "white"
  },
  "aliases": [],
  "family": "purple",
  "source": "https://www.arielton.com/colors/rebeccapurple",
  "updated": "2026-09-27",
  "docs": "https://www.arielton.com/developers#colors",
  "attribution": "Data by Arielton Oberek (arielton.com). Free to use; please link to the source URL when you publish it."
}

CPF validation

  • GET /api/v1/cpf/validate/{cpf}
  • POST /api/v1/cpf/validate

Checks the two CPF check digits (mod 11) and rejects numbers made of one repeated digit, which pass the math but are never issued. It does not query the Receita Federal: valid means well formed, not registered or active.

Nothing is stored or logged by the handler, and responses are sent with Cache-Control: no-store so no CDN or browser cache keeps them. For real people's numbers, prefer POST: a number in the URL path can end up in proxy access logs and browser history.

Parameters

CPF validation: Parameters
NameInDescription
cpfpath11 digits; dots, dash and spaces are ignored.
cpfbodyJSON body {"cpf": "529.982.247-25"}, up to 1 KB.

Examples

curl
curl -X POST https://www.arielton.com/api/v1/cpf/validate \
  -H 'Content-Type: application/json' \
  -d '{"cpf": "529.982.247-25"}'
JavaScript (fetch)
const res = await fetch('https://www.arielton.com/api/v1/cpf/validate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ cpf: input.value })
});
const { valid, formatted, message } = await res.json();
Python (requests)
import requests

r = requests.get("https://www.arielton.com/api/v1/cpf/validate/52998224725", timeout=10).json()
print(r["valid"], r["formatted"], r["reason"])

Response fields

CPF validation: Response fields
FieldTypeDescription
validbooleantrue when both check digits match and the digits are not all the same.
formattedstring | nullMasked as 000.000.000-00 when there are 11 digits.
reasonstringvalid, empty, invalidChars, invalidLength, repeated, firstDigit, secondDigit, bothDigits or tooLong.
messageobjectThe reason as a sentence, in en and pt.
fiscalRegionobject | nullThe 9th digit and the states of the fiscal region that issued the number.

Sample response

POST {"cpf": "529.982.247-25"}
{
  "valid": true,
  "formatted": "529.982.247-25",
  "reason": "valid",
  "message": {
    "en": "Both check digits match. This confirms the number is well formed, not that it is registered with the Receita Federal.",
    "pt": "Os dois dígitos verificadores conferem. Isso mostra que o número é bem formado, não que esteja cadastrado na Receita Federal."
  },
  "fiscalRegion": {
    "digit": 7,
    "states": [
      "ES",
      "RJ"
    ]
  },
  "source": "https://www.arielton.com/tools/cpf-validator",
  "docs": "https://www.arielton.com/developers#cpf",
  "attribution": "Data by Arielton Oberek (arielton.com). Free to use; please link to the source URL when you publish it."
}

CNPJ validation

  • GET /api/v1/cnpj/validate/{cnpj}
  • POST /api/v1/cnpj/validate

Validates both CNPJ formats: the classic 14 digits and the alphanumeric CNPJ the Receita Federal issues from July 2026, where the first 12 characters may be letters A to Z. Each character is valued by its ASCII code minus 48, so the numeric algorithm is the special case of the new one.

The formatted CNPJ contains a slash, which cannot sit inside a URL path segment. Send the characters without the mask on GET, or use POST.

Parameters

CNPJ validation: Parameters
NameInDescription
cnpjpath14 characters without the slash, e.g. 11222333000181 or 12ABC34501DE35.
cnpjbodyJSON body {"cnpj": "12.ABC.345/01DE-35"}, mask allowed, up to 1 KB.

Examples

curl
curl https://www.arielton.com/api/v1/cnpj/validate/11222333000181
JavaScript (fetch)
const res = await fetch('https://www.arielton.com/api/v1/cnpj/validate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ cnpj: '12.ABC.345/01DE-35' })
});
const { valid, format } = await res.json();
Python (requests)
import requests

r = requests.post("https://www.arielton.com/api/v1/cnpj/validate", json={"cnpj": "12.ABC.345/01DE-35"}, timeout=10)
print(r.json()["valid"], r.json()["format"])

Response fields

CNPJ validation: Response fields
FieldTypeDescription
validbooleantrue when both check digits match.
formattedstring | nullMasked as 00.000.000/0000-00 when there are 14 characters.
reason / messagestring / objectSame values as the CPF endpoint.
formatstring | nullnumeric or alphanumeric.
branch / headquartersstring / booleanThe 4 branch characters; 0001 is the headquarters (matriz).

Sample response

POST {"cnpj": "12.ABC.345/01DE-35"}
{
  "valid": true,
  "formatted": "12.ABC.345/01DE-35",
  "reason": "valid",
  "message": {
    "en": "Both check digits match. This confirms the number is well formed, not that the company exists or is active.",
    "pt": "Os dois dígitos verificadores conferem. Isso mostra que o número é bem formado, não que a empresa exista ou esteja ativa."
  },
  "format": "alphanumeric",
  "branch": "01DE",
  "headquarters": false,
  "source": "https://www.arielton.com/tools/cnpj-validator",
  "docs": "https://www.arielton.com/developers#cnpj",
  "attribution": "Data by Arielton Oberek (arielton.com). Free to use; please link to the source URL when you publish it."
}

Errors

Unknown values in the path (a country, year, status code or color the API does not have) return HTTP 404. The reference endpoints are prerendered, so check res.ok before parsing the body.

A POST without a usable JSON body returns 400 with {"error": {"status": 400, "message": "..."}}. An invalid CPF or CNPJ is not an error: it returns 200 with valid: false and a reason.

Fair use

  • No key and no fixed quota. Be reasonable: this runs on a personal site.
  • Cache responses. Reference data changes only when a page is reviewed, and the CDN already keeps it for 24 hours.
  • Use GET /api/v1/http-status and GET /api/v1/colors to fetch everything in one request instead of looping over single items.
  • Send a User-Agent that identifies your app, so problems can be reported to you instead of blocked.
  • The service is free and best effort, with no uptime guarantee. If your product depends on it, copy the data you need; the lists are small.

Attribution

Attribution is requested, not required. If you publish data from the API, link to the source URL of the response, for example:

HTML
<p>Holiday data: <a href="https://www.arielton.com/holidays/brazil/2026">arielton.com</a></p>

Privacy of CPF and CNPJ checks

  • The number is used to compute the answer and then discarded. The handler does not store it, log it or send it anywhere.
  • Responses carry Cache-Control: private, no-store, so neither the CDN nor the browser keeps a copy.
  • Like any web request, the URL may appear in the hosting platform's standard access logs. POST keeps the number out of the URL.

Embeddable widgets

No code at all: the holiday countdown, the holiday list and the HTTP status card are available as iframes you can paste into any page.

Build a widget

Need a custom API or integration?

The same approach (static data, prerendered JSON, no database to run) works for price tables, catalogs, internal reference data and public datasets. Arielton builds APIs and integrations in TypeScript and Go.

Email contact@arielton.com or use the contact page /contact.

Changelog

  • v1 released: holidays, HTTP status codes, colors, CPF and CNPJ validation.
  • Embeddable widgets: next holiday countdown, holiday list, HTTP status card.

Frequently asked questions

Do I need an API key?
No. There is no key, no signup and no account. Send a plain GET (or POST for CPF/CNPJ) and read the JSON.
Is there a rate limit?
No fixed quota is published. Responses are cached by the CDN for 24 hours, so cache them on your side too and use the list endpoints instead of looping over single items. Traffic that looks abusive may be blocked.
Can I use the data in a commercial project?
Yes. The API is free for personal and commercial projects. Attribution is requested, not required: a link to the source URL in each response is what keeps it free.
Does the CPF endpoint check whether a CPF exists?
No. It checks the two check digits and the repeated-digit rule, which is everything that can be known from the number itself. Whether a CPF is registered and regular can only be checked with the Receita Federal.
Can I call the API from the browser?
Yes. Every response carries Access-Control-Allow-Origin: *, and the POST endpoints answer the CORS preflight, so fetch works from any site without a proxy.

Last reviewed by Arielton Oberek.