1. Home
  2. Account Management
  3. Tools
  4. Getting Started with the API (Beta)

Getting Started with the API (Beta)

Timesheets.com provides a public API for customers who need to read account data, build internal reports, or connect Timesheets.com data to another system.

API Dashboard:
https://secure.timesheets.com/api/public/v1/index.cfm

Base URL for API requests:

https://secure.timesheets.com/api/public/v1/

Before You Begin

The API is currently intended for customer-side integrations and reporting. Most API access should be treated as administrator-level access because the authorization token authenticates requests as a specific Timesheets.com user.

Keep these rules in mind:

  • Every request requires an API key header and an authorization token header.
  • The token authenticates the request as a specific user in the Timesheets.com account.
  • Only the Primary Administrator can generate API credentials.
  • API keys and tokens do not expire automatically, but they can be deleted.
  • Treat keys and tokens like passwords. Do not paste them into source code, public repositories, help tickets, screenshots, or shared documents.
  • Store credentials in environment variables, a secrets manager, or another private configuration system.
  • The API is rate-limited to 5 requests per rolling 60 seconds per API key.
  • Too many failed authentication attempts can temporarily lock the token.

Generating API Credentials

There are two ways to create credentials.

Option 1: Generate credentials in Timesheets.com

  1. Log in as the Primary Administrator.
  2. Open Tools from the left menu.
  3. Select Generate API Keys.
  4. Click Generate Credentials.
  5. Copy the returned API key, authorization token, and header names.

Option 2: Generate credentials from the API dashboard

  1. Open the API Dashboard.
  2. Use the /auth/token endpoint.
  3. Post the Primary Administrator username and password.
  4. If the account is active and authorized, the response returns the API key, authorization token, and required header names.

Authentication Headers

Most examples use these headers:

apikey: YOUR_API_KEY
x-ts-authorization: YOUR_AUTH_TOKEN

Important: use the exact header names returned when the credentials are generated. The default examples are usually correct, but the returned credential response is the source of truth.

Example request:

curl --request GET \
  "https://secure.timesheets.com/api/public/v1/server/constants" \
  --header "apikey: YOUR_API_KEY" \
  --header "x-ts-authorization: YOUR_AUTH_TOKEN" \
  --header "Accept: application/json"

Using The API Dashboard

The API Dashboard lists available endpoints, supported request methods, parameters, and sample request forms.

To test an endpoint in the dashboard:

  1. Open an endpoint.
  2. Choose the request method, usually GET or POST.
  3. Add the authentication headers.
  4. Fill in required parameters.
  5. Send the request.
  6. Review the returned JSON.

Some dashboard parameters may appear optional but are required for specific report combinations. If a report request returns an error such as “Group by selection required,” add the requested filter and retry.

Response Format

Most API responses return JSON with an errors key and a data payload.

Common response shape:

{
  "errors": [],
  "data": []
}

If errors is empty, the request succeeded. If errors contains messages, the request authenticated but could not be completed because of missing parameters, invalid filters, permissions, or other business rules.

Do not rely only on the HTTP status code. Many authenticated requests return HTTP 200 even when the response contains application-level errors.

Example error response:

{
  "errors": [
    "Group by selection required."
  ],
  "data": []
}

Some report endpoints return a report object instead of a data object. For example, hourly report endpoints may return totals, filters, labels, included users, and ReportData inside report.

Column-Format Data

Some endpoints return query data in column format. This means field names are listed separately from the row values.

Example:

{
  "columns": ["UserID", "FullName", "Hours"],
  "data": [
    [123, "Jane Example", 8.0]
  ]
}

Most integrations should normalize this into row objects:

[
  {
    "UserID": 123,
    "FullName": "Jane Example",
    "Hours": 8.0
  }
]

Also note that some keys may be uppercase while others are camelcase. Integrations should avoid case-sensitive assumptions unless a specific endpoint requires them.

Useful Discovery Endpoint

Use /server/constants early when building an integration.

GET /server/constants

This endpoint returns account and system constants, including status codes, payroll result codes, time class IDs, record statuses, and labels.

This is especially useful because some labels can be account-specific. For example, time-off categories such as Sick, Vacation, PTO, Holiday, or custom categories may be enabled, disabled, renamed, or represented by different labels in report output.

Hourly Time And Time-Off Reports

Hourly report data is split into processed and unprocessed report endpoints.

Common endpoints include:

/report/hourly/customizable/unprocessed
/report/hourly/customizable/processed
/report/hourly/payroll/preview
/report/hourly/payroll/periods
/report/hourly/payroll/period/{PayrollID}
/report/hourly/record/history

The unprocessed customizable hourly report supports filtering by date range, users, account codes, signed status, approved status, time class, record status, grouping, report type, and optional detail fields.

For example, to report on a specific time-off class, first call /server/constants to identify the correct TimeClass value, then use that value in the unprocessed hourly report.

Example JSON body:

{
  "StartDate": "2026-01-01",
  "EndDate": "2026-07-21",
  "AllUsers": "1",
  "AllAccountCodes": "1",
  "TimeClass": "2",
  "RecordStatus": "0,1,3",
  "Signed": "0,1",
  "Approved": "0,1,2",
  "GroupType": "User",
  "ReportType": "Detailed",
  "IncludeExtendedData": "1",
  "IncludeWorkDescription": "1"
}

Report responses may include totals such as:

TotalReportHours
TotalSickReportHours
TotalVacationReportHours
TotalPTOReportHours
TotalHolidayReportHours
TotalRecords
ReportData
TimeClassLabels

When reporting on sick time or PTO, check TimeClassLabels in the response. An account may have Sick disabled and PTO enabled, or may use custom labels.

Handling Rate Limits

Limit integrations to no more than 5 requests per rolling 60 seconds per API key.

Recommended behavior:

  • Queue requests instead of sending bursts.
  • Retry only after waiting.
  • Avoid retry loops on authentication failures.
  • Cache stable reference data such as /server/constants.
  • Pull reports in larger date ranges where practical.

Security Recommendations

Do not hardcode credentials like this:

API_KEY = "..."
TOKEN = "..."

Prefer environment variables:

TIMESHEETS_API_KEY=your-api-key
TIMESHEETS_AUTH_TOKEN=your-token

Then read them from your integration code.

Rotate credentials when:

  • An employee with access leaves.
  • Credentials were pasted into a shared document.
  • Credentials were committed to source control.
  • An integration is retired.
  • You suspect unauthorized access.

Basic Integration Checklist

Before going live:

  • Generate credentials as the Primary Administrator.
  • Store the API key and token securely.
  • Confirm the correct header names.
  • Test /server/constants.
  • Confirm the endpoint’s actual response shape.
  • Handle errors in the JSON response.
  • Normalize column-format data if needed.
  • Respect the 5 requests per 60 seconds limit.
  • Log request failures without logging credentials.
  • Delete unused or exposed credentials.

Error Keys

The code values and their keys can be pulled from the /server/constants API endpoint. This will return the name of the error/warning (e.g. PAYROLL_CODE_LOCKED = 2)

CodeDescription
PAYROLL_CODE_PROCESSED = “0”

Payroll was successfully processed
The payroll report was generated as a summary only and does not include any time records
PAYROLL_CODE_SUMMARY_ONLY = “1”The payroll report was generated as a summary only and does not include any time records
PAYROLL_CODE_LOCKED = “2”Payroll report is locked and cannot be processed by current user
PAYROLL_CODE_INVALID_DATES = “3”The payroll report contains invalid run dates
PAYROLL_CODE_NO_RECORDS_FOUND = “4”There were no valid records in the payroll dates
PAYROLL_CODE_OVERLAPPING_PERIODS = “5”Users included in the payroll overlap existing payroll periods
PAYROLL_CODE_OVERLAPPING_RECORDS = “6”Users included in the payroll have overlapping records
PAYROLL_CODE_ALERTS_EXIST = “7”Alerts exist on records included in the payroll report
PAYROLL_CODE_PROCESS_VALIDATION_ERROR = “8”There was an error when attempting to validate the payroll records to process
PAYROLL_CODE_PROCESS_VALIDATION_FAILED = “9”Underlying records in the payroll report have been modified
PAYROLL_CODE_DUPLICATE_USERS_FOUND = “10”Duplicate UserIDs were detected in the payroll report
PAYROLL_CODE_NO_USERS_INCLUDED = “11”No users were included in the report
PAYROLL_CODE_UNPAID_RECORDS_EXISTS = “12”Unpaid records exist before the payroll date
PAYROLL_CODE_STANDARD_SPLITPAID_RECORDS_EXISTS = “13”Standard split paid records exist in the payroll report
PAYROLL_CODE_SALARIED_SPLITPAID_RECORDS_EXISTS = “14”Salaried split paid records exist in the payroll report
PAYROLL_CODE_INVALID_RUNBYID = “15”The user attempting to run the payroll is not authorized or valid
PAYROLL_CODE_INVALID_APPEND_PAYROLLID = “16”Attempt to append to an invalid payroll
PAYROLL_CODE_USERS_ALREADY_EXIST_IN_PAYROLL = “17”Attempt to add users to a payroll report they already exist in
PAYROLL_CODE_USERS_HAVE_POSTDATED_PAYROLL = “18”Attempt to add users to a payroll report already exist in a post dated payroll
PAYROLL_CODE_INVALID_PAYROLLID = “19”Payroll ID was not valid
PAYROLL_CODE_INVALID_PARTIAL_USER_DELETE = “20”The list of partial users to delete was not valid for the payroll period
PAYROLL_CODE_INVALID_TIMEZONE_FOR_PERIOD = “21”There were multiple time zones detected in the payroll period for a single user
PAYROLL_CODE_NONSEQUENTIAL_RECORDS = “22”Non-sequential records were detected while running payroll
PAYROLL_CODE_INVALID_ACCRUAL_SETTINGS_FOR_USER = “23”There was one or more users with invalid accrual by hours worked settings
PAYROLL_CODE_RECORDS_EXCEED_MAX_THRESHOLD = “24”Records in the payroll report were identified as exceeding the specified max threshold
Updated on July 21, 2026
Was this article helpful?

Related Articles