Normalize dates
"03/04/25" means three different calendar dates depending on who wrote it, and a spreadsheet full of dates like that is a bug waiting to happen the moment it crosses a border. This endpoint reads a date in whatever format it arrives and returns it as unambiguous ISO-8601, so every system downstream can finally agree on what day it actually is.
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
The ambiguity this removes
Ask ten people to write today's date and you get ten answers: day-month-year, month-day-year, two-digit years, dates spelled out with the month name, dates separated by dots instead of slashes. Most of the time context resolves the ambiguity for a human reader, but code has no context, and "01/02/2025" silently becomes the wrong day in a system that assumed the other convention. The parse date string api exists because that silent wrongness is far more dangerous than an outright error.
What comes back
You send the raw date string as it was written, and the response is a normalized ISO-8601 date or datetime, the format defined for exactly this purpose: unambiguous, sortable as plain text, and understood by essentially every programming language and database without a conversion library. Where a string is genuinely ambiguous, the response reflects that rather than silently guessing, because a wrong guess dressed up as certainty is worse than no answer at all.
How the request and pricing work
POST to /data/normalize-dates and the call returns a task_id immediately; the normalized result is delivered to your signed webhook or through a signed link valid for 24 hours once the job completes. Pricing is a flat $0.002 per request, published and simple to forecast, and a job that fails is retried three times before you see a clear error and is never billed.
Why ISO-8601 became the answer
Before the international standard existed, every system invented its own date convention, and integrating two of them meant guessing which one was right based on whether a number was plausible as a month. ISO-8601 fixed that by defining one order, year to day, with no ambiguity and no locale dependency, which is why it became the format every serious API and database uses internally even when the input never will be.
Where it belongs in a pipeline
Date normalization is the kind of step that pays for itself the first time a form, a scraped page, or a legacy export sends a date your system was not expecting, so it fits naturally right after ingestion and before anything touches a database or a scheduling system. Access requires prepaid balance, keeping the endpoint fast and free of abuse traffic. This endpoint is live now.
What you can do with it
Cleaning up a scraped dataset
A research team normalizes publication dates scraped from dozens of news sites, each with its own date format, into one consistent ISO-8601 field for sorting and analysis.
Import from international vendors
An e-commerce platform normalizes order dates arriving from suppliers in different countries so day-month and month-day formats never get silently swapped again.
Legacy system migration
A migration project normalizes birthdates stored as free text in a decades-old database before loading them into a schema that requires strict date typing.
Form submission cleanup
A SaaS product normalizes dates typed freely into a text field by users across regions before storing them, avoiding the classic bug where two-digit years get misread.
FAQ
How do I parse a date string with an API?
POST the raw date string to /data/normalize-dates. The parse date string api returns a task_id right away and delivers the normalized ISO-8601 result to your webhook or a signed link once processing finishes.
Is this API free to use?
The tool above runs free in your browser. The API is paid — each call draws from your prepaid ForHosting KIT balance: top up from $10.00 (it never expires), pay each request's published price, and a call with no balance returns HTTP 402. No subscription, no tokens, and a failed task is never charged.
What output format does it return?
Dates are returned in ISO-8601, the year-to-day format that sorts correctly as plain text and is understood natively by essentially every language and database.
Can it handle two-digit years and ambiguous formats?
It applies careful heuristics to common ambiguous formats, but a string with genuinely conflicting signals is reported as ambiguous rather than silently resolved to a guess.
Does it support dates written with month names or in other languages?
Yes, dates spelled out with month names in common formats are recognized and normalized the same way as numeric formats.
Can I normalize many dates in bulk?
Yes, you can submit batches of date strings, with each request processed asynchronously and the full normalized set delivered together once ready.
Is the Date Normalization API live now?
Yes, this endpoint is live today at the published price of $0.002 per request.
What happens to my data after normalization?
Submitted strings and the normalized output are deleted after the retention window and are never used for training. Delivery is by signed webhook or a signed link valid for 24 hours.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/data/normalize-dates \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"items":["valor-1","valor-2"]}'const res = await fetch("https://api.kit.forhosting.com/data/normalize-dates", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"items": [
"valor-1",
"valor-2"
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/data/normalize-dates",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"items": [
"valor-1",
"valor-2"
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/data/normalize-dates", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"items":["valor-1","valor-2"]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"items":["valor-1","valor-2"]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/data/normalize-dates", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"items": [
"valor-1",
"valor-2"
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "data.normalize_dates",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |