Log time from your own tools
Time entries record the minutes a person worked on a project, or on one task within it, on one day. With an API key you can log time for anyone in your organization whose time is tracked, then correct or remove it while their week is still open.
The rules in brief
- Minutes only. Every duration is a whole number of minutes, from 1 to
1440 per entry. A person's entries for one day can add up to 1440 minutes at
most. Dates are
YYYY-MM-DDin your organization's time zone and cannot be in the future. - Submitted weeks are locked. Once a person submits a week, every create,
update or delete that touches it answers
409until the week is unlocked in OnRamp. Entries in a locked week come back with"locked": true. - Allotted time lives on tasks. A project's allotted time is the sum of its tasks' allotted minutes; there is no separate project budget to set. Time logged without a task counts toward the project but not toward any task.
- Creates are retry-safe. If a create times out, send the identical request
again within 10 minutes. When the first one landed, you get that entry back
with
200instead of201, and no duplicate is written. Updates and deletes are not matched this way, so re-read the entry before repeating one.
Log an entry
Send task_uuid to log time on a task (its project is implied), or only
project_uuid for general project time.
curl -X POST -H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user_uuid": "USER_UUID", "task_uuid": "TASK_UUID", "entry_date": "2026-09-21", "minutes": 90, "note": "Kickoff call"}' \
"https://api.onramp.us/v1/time-entries"
import requests
response = requests.post(
"https://api.onramp.us/v1/time-entries",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"user_uuid": "USER_UUID", "task_uuid": "TASK_UUID", "entry_date": "2026-09-21", "minutes": 90, "note": "Kickoff call"},
)
created = response.status_code == 201
entry = response.json()["data"]
Correct or remove an entry
PUT /v1/time-entries/{entry_uuid} changes only the fields you send, for
example {"minutes": 45}. An entry cannot be moved to another person; delete
it and log a new one instead. DELETE /v1/time-entries/{entry_uuid} removes
it.
Compare allotted and worked time
GET /v1/time-tracking/reports/allotted-vs-worked returns one row per project,
broken down into modules and then tasks. Worked minutes are the time logged
against the project's tasks within the window (start and end; by default
the 90 days ending today in your organization's time zone). Allotted minutes
are the tasks' current allotted time and do not depend on the window. Time
logged without a task, and time on a removed task, is not part of this report.
A task is estimated when its allotted_minutes is set. Variance is
measured differently at each level:
- Task.
variance_minutesisworked_minutes - allotted_minutes, and is null when the task'sallotted_minutesis null. - Module and project.
allotted_minutesis the sum of the estimated tasks' allotted minutes, andestimated_worked_minutesis the time logged against those same tasks only.variance_minutesisestimated_worked_minutes - allotted_minutes, notworked_minutes - allotted_minutes, and is null whenallotted_minutesis 0.consumedand the project'svariance_pctdivide byallotted_minutesand are null in the same case. - Unestimated work. A project's
not_estimatedcounts its tasks with no allotted time (task_count, whether or not anyone logged time on them) and the minutes logged against them (worked_minutes). That time is inworked_minutesbut never inestimated_worked_minutes, so it cannot push a project over or under its estimate.
A project's allotted_minutes, worked_minutes and estimated_worked_minutes
are always integers, 0 when nothing on it is estimated. Tasks outside any
module are grouped under a module named General / no module whose
module_uuid is null.
Projects come largest overrun first, by variance_minutes, with projects that
have no variance last.