Skip to content

Stop a timer

POST
/api/time-entries/timer/{id}/stop
curl --request POST \
--url https://invoicing-api.eddish.app/api/time-entries/timer/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/stop \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "endedTime": "example", "endedDate": "2026-04-15" }'

Stops a running timer. The entry ends at the nearest quarter hour, at least a quarter after its start. If the stop is on a later day than the entry, the entry ends at midnight and a second entry continues on the stop day. Returns the entry, and the second entry if there is one.

id
required
string format: uuid
Media typeapplication/json
One of:
null

Example generated

{
"endedTime": "example",
"endedDate": "2026-04-15"
}

OK

Media typeapplication/json

Shorthand for the overwhelmingly common ServiceResponse&lt;TData, ErrorResponse&gt;. C# cannot alias an open generic, so this is expressed as a subclass rather than a using alias.

object
success

True when the call succeeded and TData? ServiceResponse<TData, TError>.Data is populated.

boolean
data

Payload on success; default on failure.

Array<object> | null

A time entry.

object
id
required
string format: uuid
projectId
required
string format: uuid
projectName
required
string
clientId
required
string format: uuid
clientName
required
string
workTaskId
required
string format: uuid
workTaskName
required
string
userId
required
string format: uuid
userName
required
string
spentDate
required

The day the time was worked, as yyyy-MM-dd.

string format: date
hours
required

Hours worked, as a decimal: 1.5 is an hour and a half.

number | string format: double
/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/
notes
required
null | string
startedTime
required

The time of day the work started, if recorded.

null | string format: time
endedTime
required

The time of day the work ended, if recorded.

null | string format: time
timerStartedAtUtc
required

When the running timer started, counted back from its start time. Empty when no timer is running.

null | string format: date-time
isRunning
required

Whether a timer is running on the entry.

boolean
isLocked
required

True once the entry is on a sent invoice, or its week is approved, and it can’t be changed.

boolean
billable
required

Whether the time can be billed.

boolean
billableRate
required

The hourly rate the entry is billed at, in the account’s currency. Only shown to people who may see that amount.

null | number | string format: double
/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/
isBilled
required

Whether the entry is on an invoice.

boolean
invoiceId
required

The invoice the entry is on, if any.

null | string format: uuid
createdAtUtc

When the entry was created. Untimed time is stacked in this order when a day is converted.

null | string format: date-time
error
One of:
null

Example generated

{
"success": true,
"data": [
{
"id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"projectId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"projectName": "example",
"clientId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"clientName": "example",
"workTaskId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"workTaskName": "example",
"userId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"userName": "example",
"spentDate": "2026-04-15",
"hours": 1,
"notes": "example",
"startedTime": "example",
"endedTime": "example",
"timerStartedAtUtc": "2026-04-15T12:00:00Z",
"isRunning": true,
"isLocked": true,
"billable": true,
"billableRate": 1,
"isBilled": true,
"invoiceId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"createdAtUtc": "2026-04-15T12:00:00Z"
}
],
"error": {
"code": "example",
"message": "example",
"fieldErrors": "example",
"details": "example"
}
}

Not signed in, or the credential isn’t recognised, has expired or was revoked: auth.missing_credential, auth.invalid_credential, auth.expired_credential, auth.revoked_credential.

Media typeapplication/json

Shorthand for the overwhelmingly common ServiceResponse&lt;TData, ErrorResponse&gt;. C# cannot alias an open generic, so this is expressed as a subclass rather than a using alias.

object
success

True when the call succeeded and TData? ServiceResponse<TData, TError>.Data is populated.

boolean
data

Payload on success; default on failure.

error

The Framework’s default error shape, used as the TError of ServiceResponse<TData, TError> unless an App genuinely needs its own.

object
code

Stable, machine-readable error identifier (for example account.not_found). Clients branch on this, never on string ErrorResponse.Message.

string
message

Human-readable description of what went wrong. Safe to surface to a User.

string
fieldErrors

Optional per-field validation failures, keyed by field name. Null (and omitted from JSON) for errors that are not validation failures.

null | object
details

Optional machine-readable facts about the failure that a client renders rather than parses out of string ErrorResponse.Message — e.g. plan.limit_reached’s limit, count and planName. Null (and omitted from JSON) for errors that carry none.

null | object

Example generated

{
"success": true,
"data": "example",
"error": {
"code": "example",
"message": "example",
"fieldErrors": "example",
"details": "example"
}
}

Not allowed. error.code says why: auth.role_not_permitted (your role doesn’t allow it), auth.read_only_token (the token can only read), app.no_seat (no seat in this App), auth.api_access_not_in_plan (the plan doesn’t include API access), auth.not_a_member (no longer a member of the Account), auth.insufficient_scope (an Account API key without the scope).

Media typeapplication/json

Shorthand for the overwhelmingly common ServiceResponse&lt;TData, ErrorResponse&gt;. C# cannot alias an open generic, so this is expressed as a subclass rather than a using alias.

object
success

True when the call succeeded and TData? ServiceResponse<TData, TError>.Data is populated.

boolean
data

Payload on success; default on failure.

error

The Framework’s default error shape, used as the TError of ServiceResponse<TData, TError> unless an App genuinely needs its own.

object
code

Stable, machine-readable error identifier (for example account.not_found). Clients branch on this, never on string ErrorResponse.Message.

string
message

Human-readable description of what went wrong. Safe to surface to a User.

string
fieldErrors

Optional per-field validation failures, keyed by field name. Null (and omitted from JSON) for errors that are not validation failures.

null | object
details

Optional machine-readable facts about the failure that a client renders rather than parses out of string ErrorResponse.Message — e.g. plan.limit_reached’s limit, count and planName. Null (and omitted from JSON) for errors that carry none.

null | object

Example generated

{
"success": true,
"data": "example",
"error": {
"code": "example",
"message": "example",
"fieldErrors": "example",
"details": "example"
}
}

Too many requests: rate_limit.exceeded. Wait the number of seconds in the Retry-After header.

Media typeapplication/json

Shorthand for the overwhelmingly common ServiceResponse&lt;TData, ErrorResponse&gt;. C# cannot alias an open generic, so this is expressed as a subclass rather than a using alias.

object
success

True when the call succeeded and TData? ServiceResponse<TData, TError>.Data is populated.

boolean
data

Payload on success; default on failure.

error

The Framework’s default error shape, used as the TError of ServiceResponse<TData, TError> unless an App genuinely needs its own.

object
code

Stable, machine-readable error identifier (for example account.not_found). Clients branch on this, never on string ErrorResponse.Message.

string
message

Human-readable description of what went wrong. Safe to surface to a User.

string
fieldErrors

Optional per-field validation failures, keyed by field name. Null (and omitted from JSON) for errors that are not validation failures.

null | object
details

Optional machine-readable facts about the failure that a client renders rather than parses out of string ErrorResponse.Message — e.g. plan.limit_reached’s limit, count and planName. Null (and omitted from JSON) for errors that carry none.

null | object

Example generated

{
"success": true,
"data": "example",
"error": {
"code": "example",
"message": "example",
"fieldErrors": "example",
"details": "example"
}
}
Retry-After
integer

Seconds to wait before trying again.