MinuteDock API (1.0.0)

Download OpenAPI specification:

MinuteDock API

Welcome

MinuteDock is a time tracking and invoicing application for small businesses. This API allows you to manage time entries, contacts, projects, tasks, and generate reports.

Authentication

All MinuteDock API endpoints require authentication. OAuth 2.0 access tokens are the recommended and primary way to authenticate with the MinuteDock API for new integrations. Legacy personal API keys (X-API-Key) are still accepted for backward compatibility but are deprecated — see Legacy API Keys below.

MinuteDock authenticates API requests with OAuth 2.0 access tokens, sent as a standard Authorization: Bearer <token> header. There are two ways to obtain an access token, depending on what you're building:

  1. Personal Access Tokens — for scripts, internal tools, CI jobs, and other first-party integrations where you authenticate as yourself. You generate a ready-to-use OAuth access token straight from your MinuteDock profile — no application registration or authorization flow required. See Personal Access Tokens below.
  2. OAuth Client Credentials — for integrations and third-party applications that authenticate other MinuteDock users. Register an OAuth client (client ID and secret) with us and implement the authorization-code flow so each user authorizes your integration and selects the MinuteDock account to use. See OAuth Authorization Flow below.

Whichever path you use, the resulting tokens work identically. To obtain OAuth client credentials (client ID and secret), contact us at team@minutedock.com.

Personal Access Tokens

If you just want to authenticate as yourself (for a script, internal tool, CI job, or other first-party integration) you don't need to run the full OAuth flow or register an OAuth application. You can create a Personal Access Token from within MinuteDock — this is a ready-to-use OAuth access token, issued under your own user, that you send as a standard Authorization: Bearer <token> header.

Personal access tokens behave exactly like OAuth access tokens obtained through the authorization-code flow:

  • They are account-scoped — you pick the account when creating the token, and the X-Account-ID header is ignored. Create a separate token for each account you need to access.
  • They carry the read and write scopes.
  • They do not expire — they remain valid until you revoke them.
  • They act as you, with your permissions within the chosen account.

To create one:

  1. Log in to your MinuteDock account
  2. Open your Profile and select Manage Access Tokens
  3. Click Create Token, give it a recognizable name, and choose the account to scope it to
  4. Copy the revealed token immediately — it is only shown once
  5. Use it in requests:
curl -H "Authorization: Bearer <your-personal-access-token>" \
      https://minutedock.com/api/v1/users/me

Treat personal access tokens like a password: keep them private, never commit them to source control, and revoke any token you no longer need from the same Manage Access Tokens page.

OAuth Authorization Flow

Register an OAuth client (client ID and secret) with us, then run the authorization-code flow so each of your users authorizes your integration and selects the MinuteDock account to use:

1. Redirect user to /oauth/authorize
2. User logs in and selects which account to authorize
3. MinuteDock redirects back with an authorization code
4. Exchange code for access token at /oauth/token
5. Include token in requests: Authorization: Bearer <token>
curl -H "Authorization: Bearer <access-token>" \
      https://minutedock.com/api/v1/users/me

Account Scoping

All OAuth access tokens — whether obtained as a personal access token or via the authorization flow — are account-scoped. Each token is bound to the specific account the user selected, and the X-Account-ID header is ignored for OAuth requests. For multi-account access, obtain a separate token per account.

Legacy API Keys (Deprecated)

⚠️ Deprecated. Personal API keys (X-API-Key) are legacy credentials retained only for backward compatibility with existing integrations. Do not use API keys for new integrations — use OAuth 2.0 instead. API keys may be removed in a future major API version.

Each request must include the legacy API key in the X-API-Key header:

curl -H "X-API-Key: your-api-key" https://minutedock.com/api/v1/users/me

To get an API key (existing integrations only):

  1. Log in to your MinuteDock account
  2. Navigate to your User Profile
  3. You can find your API key when viewing your Profile
  4. Keep this key secure - it provides full access to your account

Account Selection with X-Account-ID

Legacy API keys are user-scoped and can access any account the user belongs to. MinuteDock supports multiple accounts per user; by default the API uses your currently active account. To work with a specific account, include the X-Account-ID header:

curl -H "X-API-Key: your-api-key" \
      -H "X-Account-ID: 12345" \
      https://minutedock.com/api/v1/entries

We strongly recommend always specifying the X-Account-ID header when using legacy API keys, to ensure consistency, especially if you belong to multiple accounts. This header is ignored for OAuth requests, where the account is fixed by the token itself.

Finding Your Account ID

To determine which accounts you have access to:

  1. List all accounts: GET /accounts
  2. Get current account: GET /accounts/current

Authentication Examples

OAuth access token (recommended):

curl -H "Authorization: Bearer abc123def456" \
      https://minutedock.com/api/v1/users/me

Legacy API key (deprecated) — basic request:

curl -H "X-API-Key: abc123def456" \
      https://minutedock.com/api/v1/users/me

Legacy API key (deprecated) — request with specific account:

curl -H "X-API-Key: abc123def456" \
      -H "X-Account-ID: 789" \
      https://minutedock.com/api/v1/contacts

Creating an entry with an OAuth access token:

curl -X POST \
      -H "Authorization: Bearer abc123def456" \
      -H "Content-Type: application/json" \
      -d '{"entry": {"description": "Client meeting", "duration": 3600}}' \
      https://minutedock.com/api/v1/entries

Common Authentication Errors

  • 401 Unauthorized: Missing or invalid OAuth access token / legacy API key
  • 403 Forbidden: Valid credentials but no access to the requested resource
  • 404 Not Found: The account specified in X-Account-ID doesn't exist or you don't have access

Security Best Practices

  1. Prefer OAuth 2.0 - use OAuth access tokens rather than long-lived legacy API keys
  2. Never share your credentials - treat tokens and API keys like passwords
  3. Use HTTPS only - all API requests must use HTTPS
  4. Regenerate if compromised - rotate OAuth tokens or regenerate your API key in account settings
  5. Monitor API usage - regularly review your API activity

Request Format

For POST/PUT requests, use application/json with parameters nested under the resource name:

curl -X POST -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"entry": {"description": "Meeting with client", "duration": 3600}}' \
  https://minutedock.com/api/v1/entries

Rate Limiting

API requests are rate limited. If you exceed the limit, you'll receive a 429 status code.

User ID vs User Account ID

Important: This API contains legacy fields that can be confusing. Please read this section carefully.

Historically, users could only belong to one MinuteDock account, so a simple user_id field was sufficient. When we introduced multi-account support (allowing users to belong to multiple MinuteDock accounts), we added the user_account_id field to properly identify users within specific accounts.

Current State

  • User objects (/users): Contain both id (legacy user ID) and user_account_id (the correct ID to use)
  • Entry records: Contain both user_id (deprecated, matches User.id) and user_account_id (correct)
  • Other resources: May contain user_id fields that are deprecated
  • Always use user_account_id - this correctly identifies users within accounts
  • Ignore id and user_id fields - these contain legacy user IDs only for backward compatibility
  • For associations: Match Entry.user_account_id with User.user_account_id (NOT User.id)

Future Changes

In the next major API version:

  • The confusing user_id fields will be removed entirely
  • The user_account_id field will be renamed to simply user_id
  • This will eliminate the current confusion while maintaining proper multi-account support

Accounts

Account info

List accounts

Returns all accounts the authenticated user belongs to

Authorizations:
OAuth2ApiKeyHeader

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get current account

Returns the currently active account for the authenticated user

Authorizations:
OAuth2ApiKeyHeader

Responses

Response samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Acme Corporation"
}

Users

User info

List users

Returns all users in the current account

Authorizations:
OAuth2ApiKeyHeader
query Parameters
active
boolean

Filter by active status

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Get current user

Returns information about the authenticated user

Authorizations:
OAuth2ApiKeyHeader

Responses

Response samples

Content type
application/json
{
  • "id": "123",
  • "email": "john.doe@example.com",
  • "first_name": "John",
  • "last_name": "Doe",
  • "billing_rate": "100.00"
}

Dock

Real-time timer synchronization across devices

Redock entry

Moves a logged entry back to the dock (active timer). If there's already an active timer, it will be logged first. Any insignificant time from the previous timer is added to this entry.

Authorizations:
OAuth2ApiKeyHeader
path Parameters
entryId
required
integer

Entry ID to redock

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123456",
  • "user_account_id": "123456",
  • "contact_id": null,
  • "project_id": null,
  • "task_ids": [
    ],
  • "description": "Working on API documentation",
  • "duration": 3600,
  • "duration_hours": "1.0",
  • "account_id": "123456",
  • "user_id": "123456",
  • "date": "2024-01-20",
  • "invoice_id": "123456",
  • "billing_rate": "150.00",
  • "updated_at": "2024-01-20T15:45:00Z",
  • "logged_at": "2024-01-20T14:30:00-05:00",
  • "logged": true,
  • "rate": "150.00"
}

Get current timer Deprecated

DEPRECATED: Use GET /dock instead.

Alias for /dock - returns the current active timer entry. For new integrations, use the /dock endpoint directly.

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123456",
  • "user_account_id": "123456",
  • "contact_id": null,
  • "project_id": null,
  • "task_ids": [
    ],
  • "description": "Working on API documentation",
  • "duration": 3600,
  • "duration_hours": "1.0",
  • "account_id": "123456",
  • "user_id": "123456",
  • "date": "2024-01-20",
  • "invoice_id": "123456",
  • "billing_rate": "150.00",
  • "updated_at": "2024-01-20T15:45:00Z",
  • "logged_at": "2024-01-20T14:30:00-05:00",
  • "logged": true,
  • "rate": "150.00"
}

Get current dock entry

Returns the current active timer entry (dock). This is the entry that's currently being tracked. Returns null if no timer is active.

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "account_id": "456",
  • "user_account_id": "123",
  • "description": "Working on API improvements",
  • "duration": 1800,
  • "duration_hours": "0.5",
  • "contact_id": "789",
  • "project_id": "1011",
  • "task_ids": [
    ],
  • "logged": false,
  • "timer_active": true,
  • "date": "",
  • "version_id": "550e8400-e29b-41d4-a716-446655440000",
  • "version_client_id": "web-app",
  • "version_number": 42
}

Update dock

Updates the current dock entry with version control for distributed synchronization. This endpoint ensures consistency across multiple clients (web, mobile, etc.).

The version parameters are required to prevent conflicts when multiple clients are updating the timer simultaneously.

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{
  • "entry": {
    }
}

Response samples

Content type
application/json
{
  • "id": null,
  • "user_account_id": "123456",
  • "contact_id": null,
  • "project_id": null,
  • "task_ids": [
    ],
  • "description": "Working on API documentation",
  • "duration": 3600,
  • "duration_hours": "1.0",
  • "account_id": "123456",
  • "user_id": "123456",
  • "invoice_id": null,
  • "rate": null,
  • "timer_active": true,
  • "logged": false,
  • "version_id": "550e8400-e29b-41d4-a716-446655440000",
  • "version_client_id": "web-app",
  • "version_number": 42
}

Entries

Time entries - the core records for time tracking

Search entries

Search and filter time entries. Results are sorted by date descending. Use various parameters to filter results.

Authorizations:
OAuth2ApiKeyHeader
query Parameters
limit
integer [ 1 .. 1000 ]
Default: 500
Example: limit=100

Maximum number of results to return (max 1000)

offset
integer >= 0
Default: 0

Number of results to skip for pagination

(Array of strings or integers or null) (ListFilter)
Example: user_accounts=all

Filter by user account IDs

(Array of strings or integers or null) (ListFilter)
Example: contacts=789,790

Filter by Contact IDs

(Array of strings or integers or null) (ListFilter)
Example: projects=1011,1012

Filter by Project IDs

(Array of strings or integers or null) (ListFilter)
Example: tasks=1213,1214

Filter by Task IDs

from
string <date>
Example: from=2024-01-01

Start date (inclusive)

to
string <date>
Example: to=2024-01-31

End date (inclusive)

since
string <date-time>
Example: since=2024-01-15T00:00:00Z

Return entries updated after this timestamp

users
Array of strings
Deprecated
Example: users=all

DEPRECATED: Use user_accounts parameter instead. Filter by legacy user IDs or 'all' for all users. This parameter uses the deprecated user ID values.

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create entry

Creates a new time entry. If no date is provided, creates an active timer. Tasks can be specified via task_ids array or by using #hashtags in the description.

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{
  • "entry": {
    }
}

Response samples

Content type
application/json
{
  • "id": "123456",
  • "user_account_id": "123456",
  • "contact_id": null,
  • "project_id": null,
  • "task_ids": [
    ],
  • "description": "Working on API documentation",
  • "duration": 3600,
  • "duration_hours": "1.0",
  • "account_id": "123456",
  • "user_id": "123456",
  • "date": "2024-01-20",
  • "invoice_id": "123456",
  • "billing_rate": "150.00",
  • "updated_at": "2024-01-20T15:45:00Z",
  • "logged_at": "2024-01-20T14:30:00-05:00",
  • "logged": true,
  • "rate": "150.00"
}

Get entry

Retrieve a specific entry by ID or use 'current' to get the active timer

Authorizations:
OAuth2ApiKeyHeader
path Parameters
required
integer or string
Example: 5432

Entry ID or 'current' for active timer

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123456",
  • "user_account_id": "123456",
  • "contact_id": null,
  • "project_id": null,
  • "task_ids": [
    ],
  • "description": "Working on API documentation",
  • "duration": 3600,
  • "duration_hours": "1.0",
  • "account_id": "123456",
  • "user_id": "123456",
  • "date": "2024-01-20",
  • "invoice_id": "123456",
  • "billing_rate": "150.00",
  • "updated_at": "2024-01-20T15:45:00Z",
  • "logged_at": "2024-01-20T14:30:00-05:00",
  • "logged": true,
  • "rate": "150.00"
}

Update entry

Update an existing entry. You can only update your own entries unless you have admin permissions. For active timers, some fields like timer_active can control start/pause state.

Authorizations:
OAuth2ApiKeyHeader
path Parameters
required
integer or string
Example: 5432

Entry ID or 'current' for active timer

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{
  • "entry": {
    }
}

Response samples

Content type
application/json
{
  • "id": "123456",
  • "user_account_id": "123456",
  • "contact_id": null,
  • "project_id": null,
  • "task_ids": [
    ],
  • "description": "Working on API documentation",
  • "duration": 3600,
  • "duration_hours": "1.0",
  • "account_id": "123456",
  • "user_id": "123456",
  • "date": "2024-01-20",
  • "invoice_id": "123456",
  • "billing_rate": "150.00",
  • "updated_at": "2024-01-20T15:45:00Z",
  • "logged_at": "2024-01-20T14:30:00-05:00",
  • "logged": true,
  • "rate": "150.00"
}

Delete entry

Delete an entry. You can only delete your own entries unless you have admin permissions.

Authorizations:
OAuth2ApiKeyHeader
path Parameters
required
integer or string
Example: 5432

Entry ID or 'current' for active timer

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "5432",
  • "status": "deleted"
}

Redock entry

Moves a logged entry back to the dock (active timer). If there's already an active timer, it will be logged first. Any insignificant time from the previous timer is added to this entry.

Authorizations:
OAuth2ApiKeyHeader
path Parameters
entryId
required
integer

Entry ID to redock

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123456",
  • "user_account_id": "123456",
  • "contact_id": null,
  • "project_id": null,
  • "task_ids": [
    ],
  • "description": "Working on API documentation",
  • "duration": 3600,
  • "duration_hours": "1.0",
  • "account_id": "123456",
  • "user_id": "123456",
  • "date": "2024-01-20",
  • "invoice_id": "123456",
  • "billing_rate": "150.00",
  • "updated_at": "2024-01-20T15:45:00Z",
  • "logged_at": "2024-01-20T14:30:00-05:00",
  • "logged": true,
  • "rate": "150.00"
}

Contacts

Client/customer management

List contacts

Returns all contacts/clients in the current account

Authorizations:
OAuth2ApiKeyHeader
query Parameters
active
boolean

Filter by active status

pinned
boolean

Filter by pinned status

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Create contact

Creates a new contact/client

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
object (Contact)

A client/customer that time can be tracked against

Responses

Request samples

Content type
application/json
{
  • "contact": {
    }
}

Response samples

Content type
application/json
{
  • "id": "791",
  • "name": "New Client Inc",
  • "short_code": "NCI",
  • "active": true,
  • "pinned": false,
  • "default_rate_dollars": "175.00"
}

Get contact

Retrieve details of a specific contact

Authorizations:
OAuth2ApiKeyHeader
path Parameters
contactId
required
integer

Contact ID

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123456",
  • "name": "ABC Industries",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": false,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "budget_progress": 30.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Update contact

Update contact details

Authorizations:
OAuth2ApiKeyHeader
path Parameters
contactId
required
integer

Contact ID

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
name
required
string non-empty
short_code
string

Short code identifier for the Contact. In the application UI, time can be tracked for a Contact using this @identifier

active
boolean
Default: true

Whether the contact is active

pinned
boolean
Default: false

Whether the contact is pinned for quick access

budget_type
string or null
Default: "null"
Enum: "hours" "billable"

The type of budget tracking. If not set (null), the budget will not be tracked. An 'hours' budget will track the number of hours for time entries within the budget period. A 'billable' budget will track the billable value of time entries within the budget period.

budget_frequency
string or null
Default: "null"
Enum: "total" "weekly" "monthly" "quarterly" "yearly"

The time period which the budget will report on

budget_target
number or null
Default: "null"

The targetted value for the budget. For an hourly budget, this is the number of hours. For a money budget, this is the amount in dollars.

CurrencyString (string) or null

Default hourly rate for tracked time. If not set (null), the appropriate next rate will be used. A time entry's billing rate will be chosen, in order, from:

  • The Task's rate (if the entry has a Task)
  • The Project's rate (if the entry has a Project)
  • The Contact's rate
  • The User's rate
billable
boolean
Default: true

Whether tracked time should be billed (Rate is not 0)

Responses

Request samples

Content type
application/json
{
  • "id": "123456",
  • "name": "ABC Industries",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": false,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Response samples

Content type
application/json
{
  • "id": "123456",
  • "name": "ABC Industries",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": false,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "budget_progress": 30.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Delete contact

Delete a Contact. This will not delete associated time Entries.

Authorizations:
OAuth2ApiKeyHeader
path Parameters
contactId
required
integer

Contact ID

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123",
  • "status": "deleted"
}

Projects

Project organization within contacts

List projects

Returns all projects in the current account

Authorizations:
OAuth2ApiKeyHeader
query Parameters
contact_id
integer

Filter projects by contact

active
boolean

Filter by active status

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create project

Create a new Project within a Contact

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
name
required
string non-empty
contact_id
required
string (ID)

ID of the Contact this project belongs to. A Project is always associated with a Contact.

short_code
string

Short code identifier for the Project. In the application UI, time can be tracked for a Project using this #code

active
boolean
Default: true

Whether the project is active

pinned
boolean
Default: false

Whether the project is pinned for quick access

budget_type
string or null
Default: "null"
Enum: "hours" "billable"

The type of budget tracking. If not set (null), the budget will not be tracked. An 'hours' budget will track the number of hours for time entries within the budget period. A 'billable' budget will track the billable value of time entries within the budget period.

budget_frequency
string or null
Default: "null"
Enum: "total" "weekly" "monthly" "quarterly" "yearly"

The time period which the budget will report on

budget_target
number or null
Default: "null"

The targetted value for the budget. For an hourly budget, this is the number of hours. For a money budget, this is the amount in dollars.

CurrencyString (string) or null

Default hourly rate for tracked time. If not set (null), the appropriate next rate will be used. A time entry's billing rate will be chosen, in order, from:

  • The Task's rate (if the entry has a Task)
  • The Project's rate (if the entry has a Project)
  • The Contact's rate
  • The User's rate
billable
boolean
Default: true

Whether tracked time should be billed (Rate is not 0)

Responses

Request samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Website Redesign",
  • "contact_id": "123456",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": true,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Response samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Website Redesign",
  • "contact_id": "123456",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": true,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "budget_progress": 30.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Get project

Retrieve details of a specific Project

Authorizations:
OAuth2ApiKeyHeader
path Parameters
projectId
required
integer
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Website Redesign",
  • "contact_id": "123456",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": true,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "budget_progress": 30.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Update project

Update Project details

Authorizations:
OAuth2ApiKeyHeader
path Parameters
projectId
required
integer
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
name
required
string non-empty
contact_id
required
string (ID)

ID of the Contact this project belongs to. A Project is always associated with a Contact.

short_code
string

Short code identifier for the Project. In the application UI, time can be tracked for a Project using this #code

active
boolean
Default: true

Whether the project is active

pinned
boolean
Default: false

Whether the project is pinned for quick access

budget_type
string or null
Default: "null"
Enum: "hours" "billable"

The type of budget tracking. If not set (null), the budget will not be tracked. An 'hours' budget will track the number of hours for time entries within the budget period. A 'billable' budget will track the billable value of time entries within the budget period.

budget_frequency
string or null
Default: "null"
Enum: "total" "weekly" "monthly" "quarterly" "yearly"

The time period which the budget will report on

budget_target
number or null
Default: "null"

The targetted value for the budget. For an hourly budget, this is the number of hours. For a money budget, this is the amount in dollars.

CurrencyString (string) or null

Default hourly rate for tracked time. If not set (null), the appropriate next rate will be used. A time entry's billing rate will be chosen, in order, from:

  • The Task's rate (if the entry has a Task)
  • The Project's rate (if the entry has a Project)
  • The Contact's rate
  • The User's rate
billable
boolean
Default: true

Whether tracked time should be billed (Rate is not 0)

Responses

Request samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Website Redesign",
  • "contact_id": "123456",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": true,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Response samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Website Redesign",
  • "contact_id": "123456",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": true,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "budget_progress": 30.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Delete project

Delete a Project. This will not delete associated time Entries.

Authorizations:
OAuth2ApiKeyHeader
path Parameters
projectId
required
integer
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123",
  • "status": "deleted"
}

Tasks

Work categorization tags

List tasks

Returns all Tasks in the current account

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create task

Create a new Task for time tracking

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
name
required
string non-empty

Task name

pinned
boolean
Default: false

Whether the task is pinned for quick access

default_rate_dollars
string (CurrencyString) ^\d+\.\d{2}$

Default hourly rate for this Task type

Responses

Request samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Development",
  • "pinned": true,
  • "default_rate_dollars": "150.00"
}

Response samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Development",
  • "pinned": true,
  • "default_rate_dollars": "150.00",
  • "entries_count": 342
}

Get task

Retrieve details of a specific Task

Authorizations:
OAuth2ApiKeyHeader
path Parameters
taskId
required
integer
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Development",
  • "pinned": true,
  • "default_rate_dollars": "150.00",
  • "entries_count": 342
}

Update task

Update Task details

Authorizations:
OAuth2ApiKeyHeader
path Parameters
taskId
required
integer
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
name
required
string non-empty

Task name

pinned
boolean
Default: false

Whether the task is pinned for quick access

default_rate_dollars
string (CurrencyString) ^\d+\.\d{2}$

Default hourly rate for this Task type

Responses

Request samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Development",
  • "pinned": true,
  • "default_rate_dollars": "150.00"
}

Response samples

Content type
application/json
{
  • "id": "123456",
  • "name": "Development",
  • "pinned": true,
  • "default_rate_dollars": "150.00",
  • "entries_count": 342
}

Delete task

Delete a Task. This will also remove the Task from any existing Entries in the system.

Authorizations:
OAuth2ApiKeyHeader
path Parameters
taskId
required
integer
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123",
  • "status": "deleted"
}

Items

Billable item catalog for expenses

List items

Returns the current account's billable items for use with expense updates. The default_rate_cents value is applied automatically when an expense is updated with item_id.

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Expenses

Expense tracking and management.

Note: The Expenses feature must be enabled on your account before these endpoints can be used. Contact support to enable this feature. Requests to these endpoints will return a 422 Unprocessable Entity error if the feature is not enabled.

List expenses

Returns expenses in the current account. Non-admin users only see their own expenses. Supports filtering by contact, project, user account, date ranges, and invoice status.

Authorizations:
OAuth2ApiKeyHeader
query Parameters
contact_id
integer

Filter by contact ID

project_id
integer

Filter by project ID

user_account_id
integer

Filter by user account ID (admin only)

from
string <date>

Filter expenses from this date (YYYY-MM-DD)

to
string <date>

Filter expenses to this date (YYYY-MM-DD)

since
string <date-time>

Filter expenses updated since this timestamp (ISO 8601)

invoiced_only
boolean

Only return invoiced expenses

uninvoiced_only
boolean

Only return uninvoiced expenses

limit
integer [ 1 .. 1000 ]
Default: 500

Maximum number of expenses to return (1-1000, default 500)

offset
integer >= 0
Default: 0

Number of expenses to skip (for pagination)

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Update expense

Update an existing expense. You can only update your own expenses unless you have reports admin permissions.

Expense update semantics:

  • Providing item_id uses the item's default_rate_cents and allows a variable quantity
  • Providing rate_cents without item_id creates a one-off expense with an implicit quantity of 1
  • Setting manually_invoiced to true marks the expense as invoiced without linking it to an invoice object
Authorizations:
OAuth2ApiKeyHeader
path Parameters
expenseId
required
integer
Example: 1234

Expense ID

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{
  • "expense": {
    }
}

Response samples

Content type
application/json
{
  • "id": "1234",
  • "description": "Office supplies",
  • "quantity": 2,
  • "unit_amount": "25.50",
  • "amount": "51.00",
  • "currency": "USD",
  • "date": "2024-01-15",
  • "contact_id": "789",
  • "project_id": "1011",
  • "user_account_id": "456",
  • "invoice_id": null,
  • "manually_invoiced": false,
  • "written_off": false,
  • "item": {
    },
  • "created_at": "2024-01-15T10:30:00Z",
  • "updated_at": "2024-01-15T10:30:00Z"
}

Invoices

Invoice read operations

List invoices

Returns invoices in the current account. Requires the Manage Invoices permission. Results are sorted by invoice date descending.

Authorizations:
OAuth2ApiKeyHeader
query Parameters
contact_id
integer

Filter by contact ID

from
string <date>

Filter invoices from this invoice date

to
string <date>

Filter invoices to this invoice date

since
string <date-time>

Filter invoices updated since this timestamp

sent_only
boolean

Only return sent invoices

draft_only
boolean

Only return draft invoices

archived
boolean
Default: false

Return archived invoices instead of active invoices

limit
integer [ 1 .. 1000 ]
Default: 500
Example: limit=100

Maximum number of results to return (max 1000)

offset
integer >= 0
Default: 0

Number of results to skip for pagination

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get invoice

Retrieve an invoice by ID, including its line items. Requires the Manage Invoices permission.

Authorizations:
OAuth2ApiKeyHeader
path Parameters
invoiceId
required
integer
Example: 1234

Invoice ID

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": "123456",
  • "contact_id": 0,
  • "number": "string",
  • "reference": "string",
  • "status": "draft",
  • "sent_at": "2019-08-24T14:15:22Z",
  • "archived": true,
  • "date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "currency": "string",
  • "subtotal": "string",
  • "tax": "string",
  • "total": "string",
  • "delivery": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "line_items": [
    ]
}

Reports

Time data aggregation and reporting

Get report Deprecated

DEPRECATED: Use POST /reports/generate instead.

Retrieve a saved report configuration and optionally execute it to get current data. Reports are pre-configured filters and groupings for time entry data. For new integrations, use the /reports/generate endpoint to run ad-hoc reports with custom filters.

Authorizations:
OAuth2ApiKeyHeader
path Parameters
reportId
required
integer

Report ID

query Parameters
run
boolean
Default: false

Execute the report and return data (not just configuration)

header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Responses

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Weekly Time Summary",
  • "filters": {
    },
  • "grouping": "user",
  • "data": {
    }
}

Generate ad-hoc report

Generate a report summary with custom filters without saving the configuration. Returns aggregated totals for matching time entries. Billing-related fields are only included for users with appropriate permissions.

Authorizations:
OAuth2ApiKeyHeader
header Parameters
X-Account-ID
string

(Recommended) Account ID to use for the API requests. If not specified, the user's active account will be used. We recommend specifying this parameter to ensure consistency if the user is a member of multiple MinuteDock accounts. You can determine the currently active account by making a request to the /accounts/current endpoint. You can list all of the available accounts for a user by making a request to the /accounts endpoint.

Request Body schema: application/json
required
from
string <date>

Start date (inclusive)

to
string <date>

End date (inclusive)

users
Array of integers
Deprecated

DEPRECATED: Use user_accounts instead. Filter by legacy user IDs.

(Array of strings or integers or null) (ListFilter)
(Array of strings or integers or null) (ListFilter)
(Array of strings or integers or null) (ListFilter)
(Array of strings or integers or null) (ListFilter)
billable_only
boolean

Only include billable entries

unbillable_only
boolean

Only include unbillable entries

invoiced_only
boolean

Only include invoiced entries

uninvoiced_only
boolean

Only include uninvoiced entries

group_by
Array of strings
Items Enum: "contact" "user" "project" "date" "month" "year"

Dimensions to group results by. When provided, the response includes a groups array with per-dimension aggregated totals. A comma-separated string (e.g. "contact,user") is also accepted.

Date dimensions (date, month, year) are mutually exclusive — only one may be combined with the entity dimensions in a single request.

Responses

Request samples

Content type
application/json
{
  • "from": "2024-01-01",
  • "to": "2024-01-31",
  • "contacts": [
    ],
  • "billable_only": true,
  • "group_by": [
    ]
}

Response samples

Content type
application/json
Example
{
  • "description": "Report for Jan 2024",
  • "entries": 42,
  • "hours": "156.5",
  • "billable_hours": "120.25",
  • "billable_amount": {
    }
}

Models

Entity model schemas

User

user_account_id
string (ID)

The correct ID to use for this user within the account. Use this value when associating users with entries or other resources.

archived
boolean

Whether the user is archived

email
string <email>
first_name
string
last_name
string
billing_rate
string (CurrencyString) ^\d+\.\d{2}$

Default billing rate for the user

id
string
Deprecated

Legacy user ID - do not use for new integrations. This field exists only for backward compatibility with old API clients. Always use user_account_id instead for proper multi-account support. See the "User ID vs User Account ID" section for full details.

account_id
string
Deprecated

ID of the associated Account. Redundant as this is always the active API account. (Will be removed in the next major version.)

time_zone_id
string
Deprecated
time_zone_offset
string
Deprecated
push_channel_token
string
Deprecated
{
  • "user_account_id": "123456",
  • "archived": false,
  • "email": "john.doe@example.com",
  • "first_name": "John",
  • "last_name": "Doe",
  • "billing_rate": "150.00",
  • "id": "123456",
  • "account_id": "123456",
  • "time_zone_id": "string",
  • "time_zone_offset": "string",
  • "push_channel_token": "string"
}

Account

id
string (ID)

The unique identifier for the entity.

name
string
{
  • "id": "123456",
  • "name": "Acme Corporation"
}

Contact

id
string (ID)

The unique identifier for the entity.

name
required
string non-empty
short_code
string

Short code identifier for the Contact. In the application UI, time can be tracked for a Contact using this @identifier

active
boolean
Default: true

Whether the contact is active

pinned
boolean
Default: false

Whether the contact is pinned for quick access

budget_type
string or null
Default: "null"
Enum: "hours" "billable"

The type of budget tracking. If not set (null), the budget will not be tracked. An 'hours' budget will track the number of hours for time entries within the budget period. A 'billable' budget will track the billable value of time entries within the budget period.

budget_frequency
string or null
Default: "null"
Enum: "total" "weekly" "monthly" "quarterly" "yearly"

The time period which the budget will report on

budget_target
number or null
Default: "null"

The targetted value for the budget. For an hourly budget, this is the number of hours. For a money budget, this is the amount in dollars.

budget_progress
number or null
Default: "null"

The current value for the budget. This is the sum of all time entries for the current budget period.

CurrencyString (string) or null

Default hourly rate for tracked time. If not set (null), the appropriate next rate will be used. A time entry's billing rate will be chosen, in order, from:

  • The Task's rate (if the entry has a Task)
  • The Project's rate (if the entry has a Project)
  • The Contact's rate
  • The User's rate
billable
boolean
Default: true

Whether tracked time should be billed (Rate is not 0)

{
  • "id": "123456",
  • "name": "ABC Industries",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": false,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "budget_progress": 30.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Project

id
string (ID)

The unique identifier for the entity.

name
required
string non-empty
contact_id
required
string (ID)

ID of the Contact this project belongs to. A Project is always associated with a Contact.

short_code
string

Short code identifier for the Project. In the application UI, time can be tracked for a Project using this #code

active
boolean
Default: true

Whether the project is active

pinned
boolean
Default: false

Whether the project is pinned for quick access

budget_type
string or null
Default: "null"
Enum: "hours" "billable"

The type of budget tracking. If not set (null), the budget will not be tracked. An 'hours' budget will track the number of hours for time entries within the budget period. A 'billable' budget will track the billable value of time entries within the budget period.

budget_frequency
string or null
Default: "null"
Enum: "total" "weekly" "monthly" "quarterly" "yearly"

The time period which the budget will report on

budget_target
number or null
Default: "null"

The targetted value for the budget. For an hourly budget, this is the number of hours. For a money budget, this is the amount in dollars.

budget_progress
number or null
Default: "null"

The current value for the budget. This is the sum of all time entries for the current budget period.

CurrencyString (string) or null

Default hourly rate for tracked time. If not set (null), the appropriate next rate will be used. A time entry's billing rate will be chosen, in order, from:

  • The Task's rate (if the entry has a Task)
  • The Project's rate (if the entry has a Project)
  • The Contact's rate
  • The User's rate
billable
boolean
Default: true

Whether tracked time should be billed (Rate is not 0)

{
  • "id": "123456",
  • "name": "Website Redesign",
  • "contact_id": "123456",
  • "short_code": "ABC",
  • "active": true,
  • "pinned": true,
  • "budget_type": "hours",
  • "budget_frequency": "monthly",
  • "budget_target": 40.5,
  • "budget_progress": 30.5,
  • "default_rate_dollars": "150.00",
  • "billable": true
}

Task

id
string (ID)

Unique identifier for the Task

name
required
string non-empty

Task name

pinned
boolean
Default: false

Whether the task is pinned for quick access

default_rate_dollars
string (CurrencyString) ^\d+\.\d{2}$

Default hourly rate for this Task type

entries_count
integer

Number of entries using this task

{
  • "id": "123456",
  • "name": "Development",
  • "pinned": true,
  • "default_rate_dollars": "150.00",
  • "entries_count": 342
}

Item

id
string (ID)

Unique identifier for the Item

name
required
string non-empty

Item name

description
string

Optional item description

default_rate_cents
integer

Default billable rate in cents used when the item is attached to an expense

{
  • "id": "123456",
  • "name": "Consulting",
  • "description": "Hourly consulting work",
  • "default_rate_cents": 15000
}

Entry

id
string

The unique identifier for the entity.

user_account_id
required
string

The ID of the User who has logged this entry. (See User.user_account_id)

ID (string) or null
Default: null

Associated Contact ID

ID (string) or null
Default: null

Associated Project ID

task_ids
Array of strings (ID)

Array of associated Task IDs

description
string

Description of work performed

duration
integer >= 0

The time entry's duration (in seconds)

duration_hours
string

The time entry's duration (in hours)

account_id
string
Deprecated

Account this entry belongs to (deprecated)

user_id
string
Deprecated

Legacy user ID - do not use for new integrations. This field exists only for backward compatibility with old API clients. Always use user_account_id instead. See the "User ID vs User Account ID" section for full details.

string or null

Date of the entry (YYYY-MM-DD). Defaults to today's date if not provided. Null for active timers.

invoice_id
string

The Invoice that this entry was billed in, if any. (An entry is considered 'billed' if it has been included in an invoice.)

billing_rate
string (CurrencyString) ^\d+\.\d{2}$

The time entry's billing rate

updated_at
string <date-time>

Last update timestamp

string or null
Deprecated

The date the time entry is logged on, in the user's timezone, as a timestamp (deprecated). Null for unlogged entries.

logged
boolean
Deprecated

Whether the entry is logged (completed) (deprecated)

rate
string (CurrencyString) ^\d+\.\d{2}$
Deprecated

Use billing_rate instead

{
  • "id": "123456",
  • "user_account_id": "123456",
  • "contact_id": null,
  • "project_id": null,
  • "task_ids": [
    ],
  • "description": "Working on API documentation",
  • "duration": 3600,
  • "duration_hours": "1.0",
  • "account_id": "123456",
  • "user_id": "123456",
  • "date": "2024-01-20",
  • "invoice_id": "123456",
  • "billing_rate": "150.00",
  • "updated_at": "2024-01-20T15:45:00Z",
  • "logged_at": "2024-01-20T14:30:00-05:00",
  • "logged": true,
  • "rate": "150.00"
}

Expense

id
string

Unique identifier for the expense

description
required
string

Description of the expense

quantity
required
number

Quantity of items or units

unit_amount
string

Unit price in decimal format

amount
string

Total amount (quantity × unit price) in decimal format

currency
string

Currency code

date
required
string <date>

Date of the expense (YYYY-MM-DD)

contact_id
string or null

Associated contact/client ID

project_id
string or null

Associated project ID

user_account_id
required
string

The ID of the user who created this expense

invoice_id
string or null

Associated invoice ID if expense has been invoiced

manually_invoiced
boolean

Whether the expense has been marked as invoiced without linking it to an invoice

written_off
boolean

Whether the expense has been written off

object or null

Associated item/rate information

created_at
string <date-time>

Creation timestamp

updated_at
string <date-time>

Last update timestamp

{
  • "id": "1234",
  • "description": "Office supplies",
  • "quantity": 2,
  • "unit_amount": "25.50",
  • "amount": "51.00",
  • "currency": "USD",
  • "date": "2024-01-15",
  • "contact_id": "789",
  • "project_id": "1011",
  • "user_account_id": "456",
  • "invoice_id": null,
  • "manually_invoiced": false,
  • "written_off": false,
  • "item": {
    },
  • "created_at": "2024-01-15T10:30:00Z",
  • "updated_at": "2024-01-15T10:30:00Z"
}

InvoiceLineItem

id
string (ID)

The unique identifier for the entity.

description
string
quantity
string

Display quantity for the line item

unit_amount
string

Unit price in decimal format

subtotal
string

Line subtotal in decimal format

tax
string

Tax amount in decimal format

total
string

Line total including tax in decimal format

position
integer
{
  • "id": "123456",
  • "description": "string",
  • "quantity": "string",
  • "unit_amount": "string",
  • "subtotal": "string",
  • "tax": "string",
  • "total": "string",
  • "position": 0
}

InvoiceDelivery

service
string
Enum: "xero" "quickbooks" "freshbooks" "wave" "myob"
id
string

Remote invoice ID in the accounting service

{
  • "service": "xero",
  • "id": "string"
}

InvoiceSummary

id
string (ID)

The unique identifier for the entity.

contact_id
integer

Associated contact/client ID

number
string or null
reference
string or null
status
string
Enum: "draft" "sent"
sent_at
string or null <date-time>
archived
boolean
date
string <date>
due_date
string <date>
currency
string
subtotal
string

Invoice subtotal in decimal format

tax
string

Invoice tax total in decimal format

total
string

Invoice total in decimal format

InvoiceDelivery (object) or null

Remote delivery details when the invoice has been sent to an accounting service

created_at
string <date-time>
updated_at
string <date-time>
{
  • "id": "123456",
  • "contact_id": 0,
  • "number": "string",
  • "reference": "string",
  • "status": "draft",
  • "sent_at": "2019-08-24T14:15:22Z",
  • "archived": true,
  • "date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "currency": "string",
  • "subtotal": "string",
  • "tax": "string",
  • "total": "string",
  • "delivery": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Dock

id
string
Deprecated

The unique identifier for the entity.

user_account_id
string

The ID of the User who has logged this entry. (See User.user_account_id)

ID (string) or null
Default: null

Associated Contact ID

ID (string) or null
Default: null

Associated Project ID

task_ids
Array of strings (ID)

Array of associated Task IDs

description
string

Description of work performed

duration
integer >= 0

The time entry's duration (in seconds)

duration_hours
string

The time entry's duration (in hours)

account_id
string
Deprecated

Account this entry belongs to (deprecated)

user_id
string
Deprecated

Legacy user ID - do not use for new integrations. This field exists only for backward compatibility with old API clients. Always use user_account_id instead. See the "User ID vs User Account ID" section for full details.

invoice_id
any
Deprecated
rate
any
Deprecated
timer_active
boolean

Whether the timer is currently running

logged
boolean

If true, the Entry will be logged.

version_id
string

Unique version identifier for conflict resolution

version_client_id
string

Client identifier that made the last update

version_number
integer

Incremental version number

{
  • "id": null,
  • "user_account_id": "123456",
  • "contact_id": null,
  • "project_id": null,
  • "task_ids": [
    ],
  • "description": "Working on API documentation",
  • "duration": 3600,
  • "duration_hours": "1.0",
  • "account_id": "123456",
  • "user_id": "123456",
  • "invoice_id": null,
  • "rate": null,
  • "timer_active": true,
  • "logged": false,
  • "version_id": "550e8400-e29b-41d4-a716-446655440000",
  • "version_client_id": "web-app",
  • "version_number": 42
}

Properties

Common property types used across resources

ID

string (ID)

The unique identifier for the entity.

"123456"

CurrencyString

string (CurrencyString) ^\d+\.\d{2}$

Currency amount formatted as a string with exactly 2 decimal places

"150.00"

CurrencyMap

property name*
additional property
string
{
  • "USD": "1500.00",
  • "NZD": "3500.00"
}

Inputs

Special input types or formats used as arguments

ListFilter

One of
Array
One of
string
[ ]