Itinerary time budget calculator
A 14-hour day with 2 hours of transit and 2 of rest leaves 10 hours for activities, so a museum, market, park and dinner walk totalling 7.5 hours fit with 2.5 to spare. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Available hours
- 14
- Transit hours
- 2
- Rest hours
- 2
- Reserved hours
- 4
- Remaining for activities
- 10
- Planned activity hours
- 7.5
- Recommended activity hours
- 7.5
Trip days fail when the map looks generous and the clock does not. A museum, a market, a viewpoint, and a dinner reservation can each be reasonable alone, then collapse once walking time, metro transfers, and a real meal are added back in. This itinerary time budget calculator takes a positive daily hour budget, reserved transit hours, reserved rest hours, and an ordered list of named activities with planned hours, then reports whether that day still fits. Transit and rest are treated as fixed first-class costs; leftover hours become the activity envelope. If planned stops overflow that envelope, the engine scales every activity down by the same factor so the recommended plan still sums to the remaining window.
Where a daily itinerary time budget earns its keep
The overflow path returns a scaled recommendation instead of a silent overbook, which is what a guest-facing schedule needs before anyone prints a timetable. Corporate offsite planners reserve lunch and a hotel shuttle as rest and transit, then see whether three workshops still fit a ten-hour day. Students building a backpacking loop catch the classic error of stacking six attractions into a day that already spent three hours on trains.
Pair this allocator with walking-time or multi-stop distance helpers when you already know the minutes between pins and only need the day to add up. Leisure travelers can paste a draft Saturday, read the slack or overflow in one glance, and drop a stop before they book timed tickets they will never reach.
What you can do with it
City-break day planning
Reserve walking and meal hours first, then see whether museum, market, and viewpoint stops still fit the remaining sightseeing window.
Tour and group timetable drafts
Scale an overbooked coach day so printed stop times stay inside the same transit and rest envelope the guide actually has.
FAQ
How is the daily itinerary time budget allocated?
Transit and rest are reserved first. Remaining hours are the activity envelope. If planned stops fit, they keep their hours and slack is leftover. If they overflow, every activity is scaled by remaining / planned sum.
Does an overflowing day fail, or does it return a plan?
It succeeds with status overflow, fits false, and recommended hours scaled to the remaining envelope.
What does a tight status mean?
Treat it as a full day with little room for a late museum exit or a missed tram.
What should I count as transit and what as rest?
Transit covers walks between stops, metro hops, taxis and time lost in ticket lines. Rest covers meals, a sit-down coffee, hotel check-in and the breaks you actually need. Both come off the day before any activity.
Does scaling an overbooked day keep my priorities?
It keeps the proportions: every activity shrinks by the same factor. A four-hour cathedral next to a two-hour museum still gets twice the time, so drop a stop yourself if one matters more.
Related tools
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, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/travel/itinerary-time-budget \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"available_hours":14,"transit_hours":2,"rest_hours":2,"activities":[{"name":"Museum","hours":3},{"name":"Market","hours":1.5},{"name":"Park","hours":2},{"name":"Dinner walk","hours":1}]}'const res = await fetch("https://api.kit.forhosting.com/travel/itinerary-time-budget", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"available_hours": 14,
"transit_hours": 2,
"rest_hours": 2,
"activities": [
{
"name": "Museum",
"hours": 3
},
{
"name": "Market",
"hours": 1.5
},
{
"name": "Park",
"hours": 2
},
{
"name": "Dinner walk",
"hours": 1
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/travel/itinerary-time-budget",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"available_hours": 14,
"transit_hours": 2,
"rest_hours": 2,
"activities": [
{
"name": "Museum",
"hours": 3
},
{
"name": "Market",
"hours": 1.5
},
{
"name": "Park",
"hours": 2
},
{
"name": "Dinner walk",
"hours": 1
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/travel/itinerary-time-budget", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"available_hours":14,"transit_hours":2,"rest_hours":2,"activities":[{"name":"Museum","hours":3},{"name":"Market","hours":1.5},{"name":"Park","hours":2},{"name":"Dinner walk","hours":1}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"available_hours":14,"transit_hours":2,"rest_hours":2,"activities":[{"name":"Museum","hours":3},{"name":"Market","hours":1.5},{"name":"Park","hours":2},{"name":"Dinner walk","hours":1}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/travel/itinerary-time-budget", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"available_hours": 14,
"transit_hours": 2,
"rest_hours": 2,
"activities": [
{
"name": "Museum",
"hours": 3
},
{
"name": "Market",
"hours": 1.5
},
{
"name": "Park",
"hours": 2
},
{
"name": "Dinner walk",
"hours": 1
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "travel.itinerary_time_budget",
"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. |
Technical notes
Slack, overflow, utilization, and a fits flag come back with the row-level recommended hours so a human planner and an API client share one arithmetic. Zero or negative budgets, negative transit or rest, and a reserved pair that already exceeds the day fail with invalid_input instead of inventing a schedule.
How reserved transit and rest shrink the activity envelope
An itinerary time budget treats the waking window as a hard envelope, not a wish list. Transit and rest are subtracted first because they are not optional in a realistic day. Each activity keeps a name and a planned hours figure so a Louvre block, a market, and a river walk stay distinct. Equal planned hours stay equal after the scale; a four-hour cathedral next to a two-hour museum keeps a two-to-one ratio. Floating-point dust is absorbed into the last positive planned activity so recommended hours sum exactly to the remaining pool on an overflow day. The field available_hours is that envelope: fourteen hours from breakfast to hotel, or ten hours between a late start and a dinner reservation. Walking between museums, a metro hop, a taxi to a viewpoint, and the minutes lost at ticket lines all live in transit_hours. Meals, a sit-down coffee, a hotel check-in, and the pause a traveler actually needs live in rest_hours. Their sum is reserved_hours. Whatever remains is remaining_for_activities, the only pool that planned stops may spend. When the planned sum is at most the remaining pool, recommended hours equal planned hours and slack_hours is the unused remainder. When the planned sum is larger, every activity is scaled by remaining_for_activities divided by the planned sum so the recommended day still closes. Utilization can exceed one hundred percent when the as-planned committed_hours overshoots the budget; that is the signal to cut, not to pretend the clock will stretch.
Input contract, response shape, and error behaviour
The field activities is a non-empty array of objects, each with a non-empty name and a finite non-negative hours value, at most fifty rows on this free parse path. Wire the free browser form for human planning, and call the same contract from a trip builder when automation needs identical numbers. POST a JSON body with four required fields. The field available_hours is a finite number strictly greater than zero and at most one hundred sixty-eight, which is enough for a single long day or a short multi-day envelope. The fields transit_hours and rest_hours are finite and non-negative, each also capped at one hundred sixty-eight. Their sum must not exceed available_hours; a reserved pair that already eats the whole budget plus more fails with invalid_input because there is no honest activity envelope left to allocate. Missing fields, empty lists, non-object rows, blank names, non-finite numbers, negative hours, and an available budget that is zero or negative all fail with invalid_input and are not billed. On success the body echoes the three hour inputs, reports reserved_hours, remaining_for_activities, planned_activity_hours, recommended_activity_hours, committed_hours, slack_hours, overflow_hours, a boolean fits flag, a status of fits, tight, or overflow, utilization_percent, scale_factor, and activity_count. Each activity row carries index, name, planned_hours, recommended_hours, share_of_activities, and percent_of_day. Method is reserve_then_scale. Formula restates remaining equals available minus transit minus rest, then recommended_i equals planned_i times the minimum of one and remaining over the planned sum. A tight day is a fitting day whose slack is at most ten percent of available_hours. Successful API calls use the published base price $0.002 per item; validation failures do not consume prepaid balance.
Where a daily itinerary time budget earns its keep
Tour operators use an itinerary time budget calculator so a city-break template survives a shorter winter daylight window: keep the same planned stops, raise transit_hours when the group walks slower, and re-run.
Integration use cases
Trip-builder and guidebook automation
Call the same reserve-then-scale contract from a booking widget so the published day plan and the API never disagree on slack.
Technical questions
What if transit plus rest already exceed the day?
The task fails with invalid_input. Reserved transit and rest cannot be larger than available_hours, because there is no honest activity envelope left to allocate.
What does the itinerary time budget calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.