Extract dates
Contracts say 'within thirty days of signing', emails say 'let's talk next Tuesday', invoices say '15/03/24' — three formats, one meaning a machine needs to sort chronologically. This date extraction endpoint reads free-form text and pulls out every date and event mention it finds, normalising each into a single unambiguous format so a downstream system can finally sort, filter and compare them.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The problem with dates buried in prose
Dates written by humans are wonderfully inconsistent: relative phrases like 'next Friday' or 'in two weeks', regional formats where 03/04 means two different days depending on the country, and written-out forms like 'the fifteenth of March'. A script built around one regex pattern breaks the moment a document uses a different convention, which is exactly the failure mode this endpoint is built to avoid by reading dates the way a person would, in context.
Who actually needs this
Legal teams processing contracts for deadline tracking, logistics companies parsing shipping manifests and delivery notes, recruiters scanning resumes for employment date ranges, and support teams mining tickets for SLA-relevant timestamps all share the same need: turning scattered date mentions into a structured timeline without manually rereading every document.
What comes back in the response
POST /text/extract-dates returns each date mention found in the source text alongside its normalised value, so 'next Tuesday' resolves against context when the reference point is inferable and explicit dates like '2024-03-15' pass through cleanly. Where the surrounding text names an event tied to the date — a renewal, a deadline, a meeting — that label is attached too, so the output reads as a mini-timeline rather than a bare list of timestamps.
A quick note on why this is genuinely hard
Date parsing looks trivial until you account for the fact that '03/04/2024' means March 4th in the United States and April 3rd almost everywhere else, that fiscal years don't align with calendar years in every jurisdiction, and that phrases like 'Q3' or 'end of quarter' carry no fixed date at all without organizational context. This is why generic regex-based date parsers fail silently on real-world documents far more often than people expect.
Fitting into a document pipeline
Because the call is asynchronous, you fire off a batch of contracts or emails and collect each normalised timeline as it lands — by signed webhook the moment it's ready, or via a 24-hour signed link if your system prefers to pull. Pricing follows document length rather than a flat fee, so a two-line email costs a fraction of what a multi-page lease agreement costs, and nothing is charged on a task that fails after retries.
What you can do with it
Contract deadline tracking
Pull every renewal date, notice period and termination clause date out of a batch of signed contracts to populate a compliance calendar automatically.
Resume timeline verification
Extract employment date ranges from uploaded resumes to flag unexplained gaps or overlapping roles during screening.
Email-to-calendar automation
Scan incoming customer emails for meeting dates and proposed times to auto-suggest calendar events instead of manually reading each thread.
Shipping and logistics documents
Normalise delivery dates and cutoff times from manifests written in mixed date formats across different supplier countries.
FAQ
How does the date extraction API work?
You send text to POST /text/extract-dates, it returns a task_id right away, and the normalised list of dates and their context arrives afterward by webhook or a 24-hour signed link.
Does it handle relative dates like 'next Monday'?
Yes — when the surrounding text gives enough context, relative expressions are resolved into an explicit date; when there's no reliable reference point, the phrase is returned as-is rather than guessed.
What date formats does it recognise?
It reads mixed formats within the same document, including numeric formats like DD/MM/YYYY and MM/DD/YYYY, written-out dates, and informal phrasing, and returns them all normalised to one consistent format.
Is there a free trial?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
What does it cost to extract dates from text?
It's $0.003 per request plus $0.0135 per 1,000 words processed, and you're only billed for tasks that complete successfully.
Can I process a large batch of documents?
Yes, each document is an independent asynchronous task, so you can submit as many as you need and collect results as each one finishes.
Does it also extract the event tied to a date?
When the text names what the date refers to — a deadline, a renewal, a meeting — that label is returned alongside the normalised date rather than just the timestamp on its own.
Why not just use a regex to find dates?
A single regex pattern can't reliably tell '03/04' apart across regional formats or resolve relative phrases like 'in two weeks', which is why documents with mixed formats need contextual reading rather than pattern matching.
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/text/extract-dates \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"…"}'const res = await fetch("https://api.kit.forhosting.com/text/extract-dates", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/text/extract-dates",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/text/extract-dates", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/text/extract-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
{
"text": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "text.extract_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_tokens | 20000 |
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. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |