Approve a timesheet
Approves a timesheet whose period has ended, every remaining approval step at once (your organisation's approvers
approve step by step in Agoo Workspace and the Console), and locks it. A timesheet still waiting for the person
to confirm it is sent for approval first. Returns invalid_state while something is left to sort out (a missing
clock-out, a break not ended, extra time or leave waiting for a decision, a punch waiting for review, or days
still being worked out), for a period still running, and for one approved already. timesheet.approved fires.
Scope: attendance:manage · Plan: Pro and Enterprise in live mode; every plan in test mode.
AuthorizationBearer <token>Send Authorization: Bearer <token> on every request. The token is one of:
| Prefix | What it is | Where it may be used |
|---|---|---|
agoo_sk_live_ | Secret key, live mode | Your servers only |
agoo_sk_test_ | Secret key, test mode | Your servers only |
agoo_pk_live_ | Publishable key, live mode | Browsers and apps: create pre-registrations and bookings, read public booking types (with their intake questions) and their free slots, read the visit types open for pre-registration with their public forms. Never lists people. |
agoo_pk_test_ | Publishable key, test mode | As above, in test mode |
Admins create keys in Console → Developers → API keys and choose each key's scopes. A key is shown once. Never put a secret key in a URL, a browser or a mobile app.
Scope: attendance:manage
timesheet_id*stringThe timesheet's ID.
^ts_[0-7][0-9a-hjkmnp-tv-z]{25}$"ts_01m5a2b3c4d5e6f7g8h9jkmnpq"Idempotency-Key*stringA UUID you generate for this operation. If you retry with the same key within 24 hours, Agoo returns the
original response instead of acting twice. While the first request is still running, a retry returns
conflict. Reusing a key with a different request returns idempotency_key_reused. Responses with
rate_limited, internal_error or unavailable aren't stored, so retry those with the same key.
uuidThe timesheet, approved and locked.
application/json- response
One person's timesheet for one period. Approved is locked: its days and totals don't change until it's reopened.
id*TimesheetIdA timesheet ID (TypeID with the ts prefix).
^ts_[0-7][0-9a-hjkmnp-tv-z]{25}$"ts_01m5a2b3c4d5e6f7g8h9jkmnpq"person_id*PersonIdA person ID (TypeID with the person prefix).
^person_[0-7][0-9a-hjkmnp-tv-z]{25}$"person_01kjsesxm0e4zbyvkr7bcfxbfg"period*status*stringopen while its period runs; to_confirm while the person is asked to confirm it; to_approve in approval (or waiting to lock itself where your organisation approves none); approved and locked.
"open""to_confirm""to_approve""approved"round*integerEach time it goes for approval again (sent back or reopened) is a new round.
confirmed_at*|When the person confirmed it, where your organisation asks them to.
date-timesubmitted_at*|date-timeapproved_at*|date-timeapproved_by*|Who approved its last step; null when approved through the API or by Agoo.
^person_[0-7][0-9a-hjkmnp-tv-z]{25}$approved_via*|auto: it locked itself, or nobody else could approve it.
"person""api""auto"nulllocked*booleanreopened_at*|date-timereopen_reason*string|nullchanged_after_lock*booleanSomething arrived after it was locked (an offline punch, a holiday) that isn't counted until it's reopened.
totals*What the period adds up to, from each day as Agoo worked it out. Times in seconds, breaks and lateness in minutes, days as counts.
approval*|The current round's approval; null when there's none.
created_at*stringdate-timeupdated_at*stringdate-timecurl -X POST 'https://api.agoo.ardent.africa/v1/timesheets/ts_01m5a2b3c4d5e6f7g8h9jkmnpq/approve' \ -H 'Idempotency-Key: 3f6b2a1e-8c4d-4f7a-9b2e-5d1c0a7e9f64'{ "id": "ts_01m5a2b3c4d5e6f7g8h9jkmnpq", "person_id": "person_01kjsesxm0e4zbyvkr7bcfxbfg", "period": { "id": "tsp_01m5a2b3c4d5e6f7g8h9jkmnpr", "starts_on": "2019-08-24", "ends_on": "2019-08-24", "payroll_on": "2019-08-24" }, "status": "open", "round": 0, "confirmed_at": "2019-08-24T14:15:22Z", "submitted_at": "2019-08-24T14:15:22Z", "approved_at": "2019-08-24T14:15:22Z", "approved_by": "string", "approved_via": "person", "locked": true, "reopened_at": "2019-08-24T14:15:22Z", "reopen_reason": "string", "changed_after_lock": true, "totals": { "worked_seconds": 0, "counted_seconds": 0, "regular_seconds": 0, "overtime_daily_seconds": 0, "overtime_weekly_seconds": 0, "rest_day_seconds": 0, "holiday_seconds": 0, "night_seconds": 0, "extra_pending_seconds": 0, "extra_approved_seconds": 0, "extra_declined_seconds": 0, "paid_break_minutes": 0, "unpaid_break_minutes": 0, "nursing_break_minutes": 0, "days_worked": 0, "holidays": 0, "absences": 0, "authorised_paid": 0, "authorised_unpaid": 0, "late_count": 0, "late_minutes": 0, "early_leave_count": 0, "early_leave_minutes": 0, "leave": [ { "type_id": "string", "name": "Annual leave", "kind": "annual", "paid": true, "days": 0 } ] }, "approval": { "status": "pending", "step": 0, "of": 0 }, "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}Get a timesheet GET
Returns one timesheet with each day of its period as Agoo worked it out: worked and counted time, regular time, overtime, rest-day and holiday work, extra time and its decision, breaks, lateness, leave and absences. **Scope:** `attendance:read` · **Plan:** Pro and Enterprise in live mode; every plan in test mode.
Reopen a timesheet POST
Reopens an approved timesheet, with a reason the person and whoever approved it see: it's unlocked, its days are worked out again, and it goes back through your organisation's approval steps. A timesheet that isn't approved returns `invalid_state`. `timesheet.reopened` fires. **Scope:** `attendance:manage` · **Plan:** Pro and Enterprise in live mode; every plan in test mode.