Schedule a webhook
Running a recurring job used to mean keeping a server or a container alive just to watch a clock. This cron job API lets you register a webhook against a cron expression and have it called on schedule from our infrastructure instead of yours, so the only thing you maintain is the endpoint that does the actual work.
The tax of running your own scheduler
A small team building a SaaS product, an indie developer with a side project, or an internal tools team at a larger company all eventually need something to happen on a schedule, a nightly report, a subscription renewal check, a cache warm-up, and the traditional answer is a persistent process somewhere: a cron daemon on a VM, a scheduled container, a serverless function with its own scheduler configuration. Each of those needs monitoring, needs to survive restarts, and needs someone to notice when it silently stops firing. For a single recurring task, that infrastructure is disproportionate to the job it's doing.
Registering a schedule in one call
POST /dev/cron-webhook accepts a cron expression and a target webhook URL, along with the payload to send on each trigger; once registered, the schedule is stored and the webhook fires automatically at each matching time, no polling, no persistent connection required on your end. The registration request itself is queued asynchronously and returns a task_id confirming the schedule is active, with confirmation delivered via signed webhook or a signed link valid for 24 hours.
Cron syntax outliving the reasons it was invented
The cron expression format was built for the original Unix cron utility in the 1970s to let administrators list recurring jobs in a plain text table without a graphical scheduler. Decades later, that same compact syntax is still the common language for describing recurring schedules across almost every platform, which is why building on it rather than inventing a new scheduling syntax means existing cron expressions, and the knowledge of how to write them, transfer directly into this endpoint.
What this replaces in a real system
Instead of a background worker whose only job is to wake up, check the time and fire an HTTP request, that logic moves entirely into the schedule registration, and your application only needs to expose one endpoint that receives the webhook and does the actual work when called. This composes cleanly with the rest of a task pipeline: a webhook triggered on schedule can itself kick off further asynchronous jobs. At $0.002 per request, the cost of maintaining a scheduled trigger is negligible next to the infrastructure it replaces.
Access, reliability and current status
Using the endpoint requires prepaid balance; without one, the registration request returns HTTP 402 rather than a schedule that silently never fires. A failed trigger delivery is retried automatically up to three times before a clear error is reported, and a failed attempt is never charged. The endpoint is live now, and payload data associated with each schedule is handled under the same retention and deletion rules as the rest of the API, never used for training.
What you can do with it
Nightly report generation
Trigger a webhook every night at a fixed time to kick off a report job without keeping a scheduler process running.
Subscription and billing checks
Fire a recurring webhook on the first of each month to review upcoming renewals, without a dedicated background worker.
Cache and data warm-up
Schedule a webhook every few hours to refresh a cache or pre-compute a dataset before peak traffic arrives.
Side project automation
Add a scheduled trigger to a small application without provisioning a server just to run one recurring task.
FAQ
How does this cron job API work?
Send a cron expression and a webhook URL to POST /dev/cron-webhook, and the webhook is called automatically on that schedule from then on.
Do I need to keep a server running for the schedule to work?
No, the schedule is stored and triggered from our infrastructure; your side only needs to expose the endpoint that receives the webhook call.
Is there a free tier for this API?
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.
How much does the cron webhook API cost?
It costs a flat $0.002 per request for registering and managing a schedule.
What happens if my webhook endpoint fails to respond?
A failed delivery is retried automatically up to three times before a clear error is reported, and a failed attempt is never charged.
Can I use any standard cron expression?
Yes, it accepts standard cron syntax, so existing expressions from other schedulers can generally be reused directly.
Is the cron webhook API live now?
Yes, it is live and accepting schedule registrations.
Can I schedule multiple webhooks at once?
Yes, register one schedule per request; each is independent, so you can run several recurring triggers side by side.
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/dev/cron-webhook \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/dev/cron-webhook", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"input": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/cron-webhook",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"input": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/cron-webhook", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"input":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"input":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/cron-webhook", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"input": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.cron_webhook",
"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.
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. |