Intervals API Introduction

The Intervals API allows you to perform actions on various resources available within Intervals in a RESTful manner. For most resources, you can perform actions on them using all four verbs: you can retrieve information (GET), update items (PUT), create new items (POST), and delete items (DELETE).

The API root URL is located at https://api.myintervals.com/

The Intervals API is available to all Intervals accounts (including trial accounts). Each request must include user credentials in the Authorization HTTP header of the user on whose behalf you are making the request. API requests return either XML or JSON formatted data, depending on the accept type header used (either application/xml or application/json). Some resources can return image data accompanied by the image/* accept type header.

API Response

An HTTP status code in the 200s will be returned if a request is successful. For example, when a new item is created, the API will return "201 Created"; when an update takes place, "202 Accepted" will be returned; otherwise "200 OK" will be returned.

If a request fails, the error information is returned with the HTTP status code, along with a more detailed explanation of what happened in xml or json format (depending on what was requested). A list of error codes and their associated HTTP status codes can be found on the errors page.

Current user (/me/)

GET https://api.myintervals.com/me/ returns the account tied to the credentials in the Authorization header. The response uses the usual collection envelope (personid, status, code, listcount, and a me array with one person record) so you can read your person id, role-related fields, and other profile data without scanning GET /person/.

Request parameters and response fields: Me resource documentation. To list or filter other people (where your permissions allow), use Person.

Data Formats

Requests must meet the following conditions:

  • All data should be UTF-8 encoded
  • Calendar dates: For query parameters and request bodies, use a calendar day only in YYYY-MM-DD form (no time of day, no T separator, no timezone offset). These use the account’s local calendar. Typical collection date range filters and task open/due/closed filters are calendar dates.
  • Datetime fields: Where a parameter or body field includes hours, minutes, and seconds, use YYYY-MM-DD HH:MM:SS (space between the date and time, consistent with datetime values in API responses). Values are in UTC with no timezone offset suffix. In a query string, encode the space as %20.
  • Multi-value filters: When a parameter allows more than one ID, pass a comma-separated list with no spaces (for example projectid=3,5,11).
  • String length: Maximum lengths for string fields are given in parentheses in each resource’s parameter table, and in the OpenAPI spec where applicable.
  • All numbers (including quantities of time) should be represented with the "." character (period, stop, full stop, ASCII 46) as the decimal separator, and the digit group separator should be omitted.
  • Booleans are either 't'(true) or 'f'(false)
  • For application/xml request bodies, represent null with an empty element: <fieldname />. For JSON, use null.

Pagination

Collection GET requests support two optional query parameters:

  • limit — maximum number of records to return in this response. If omitted, the default is 10.
  • offset — number of matching records to skip before returning results. If omitted, the default is 0 (start at the first matching record). The API uses this name instead of a “page number,” but if you keep limit the same on every request, you can picture it like pages: the first page is offset=0, the second is offset=limit, the third is offset=(limit * 2), and so on.

There is no maximum value for limit. Large limits are allowed but produce larger responses and may take longer to process.

The envelope field listcount is how many records match your filters before limit and offset are applied. If it is 0, the collection is empty.

Walking the whole list: pick a page size (limit), start at offset=0, and keep calling while offset < listcount, adding limit to offset after each response. The last page may have fewer than limit rows; do not stop on that alone, or you can miss the final page when listcount is an exact multiple of limit.

Example: listcount is 125 and limit is 50 — three calls (GET /time/?limit=50&offset=0, then offset=50, then offset=100) return 50, 50, and 25 rows. After that, offset would become 150, which is greater than listcount, so you are done.

Data models for task and time entries

Most integrations create or update tasks and time entries. The table below describes how IDs on each resource line up with other records for valid POST /task/ and POST /time/ calls. In the product, a task belongs to a module; in the API that is moduleid on the task.

Use this as a checklist of relationships (foreign keys), not ownership depth. Rows can be read in any order once you know which record you are creating or updating.

Resource Connects to How (typical fields)
Project /project/ Optional Client /client/ Optional clientid. Scope for tasks and time is always a single projectid.
Module /module/ Referenced by Task; by Time only when taskid is null Tasks always use moduleid (a task belongs to one module). For general time (taskid null), a time create must include moduleid; when taskid is set, moduleid is not required on create.1
Milestone /milestone/ (optional) Optional link from Task Tasks do not have to sit in a milestone; when linked, at most one milestone per task.
Task /task/ Project, Module, Status /taskstatus/, Priority /taskpriority/, optional Milestone projectid, moduleid, statusid, priorityid, plus milestone / assignee fields as documented on the task resource.
Time entry /time/ Project, Person /person/, Work type /worktype/; optional Task; Module only when taskid is null Always projectid, personid, worktypeid, date. Set taskid when the hours belong to a task (moduleid not required on create). For general time (taskid null), include moduleid.2

This layout is relational, not hierarchical: Module is its own row because tasks always reference it via moduleid, and time entries do too when they are general time (taskid null). For general time, leave taskid empty and supply moduleid (required) together with projectid and the other required fields. When the hours are on a task (taskid set), moduleid is not required on create because the task already carries the module.

1 For a valid moduleid on a task, that module must already exist in the project_module table for that project. For general time (taskid null), the moduleid you send must satisfy the same rule. When taskid is set, you typically omit moduleid on create.

2 For a valid worktypeid on a time entry, that work type must already exist in the project_worktype table for that project.

IDs to resolve first

  • Create or update a task: You need a projectid, a moduleid valid for that project, a statusid and priorityid (from /taskstatus/ and /taskpriority/), and optionally milestone / assignee fields per the task resource docs.
  • Post time on a task: Provide projectid, taskid, personid, worktypeid, work date, and hours; moduleid is not required on create when taskid is set. For general time, omit taskid and supply projectid, moduleid, personid, worktypeid, date, and hours.
  • Project context: Linking a project to a client (/client/, clientid) is optional. Valid moduleid values for tasks (and for general time when you send moduleid) come from modules configured on that project.

Related lookups you will often cache: /client/, /taskstatus/, /taskpriority/, /module/, /worktype/.

API Rate Limits

All Plans (Except Unlimited):

  • 100 requests per minute per IP
  • 6,000 requests per day per customer account

The Unlimited Plan:

  • 100 requests per minute per IP
  • 12,000 requests per day per customer account

These rate limits are in place to ensure everyone’s requests are handled in a timely manner and that runaway processes don’t overwhelm the API. Exceeding these numbers will trigger a temporary suspension on further API requests. If the daily limit is exceeded, it is lifted after midnight (UTC).

In the interest of staying within these rate limits, here are some tips to keep in mind when developing your application:

  1. Pay close attention to the control flow of your program. Make sure that any requests made in loops have escape conditions and that infinite loops are detected and prevented.
  2. Plan for and handle all possible errors returned by the server. Even if your request is perfectly formed, there is still the possibility that errors could be returned.
  3. Implement and utilize efficient caching techniques, and be judicious in deciding which requests to make. Certain resources change so infrequently (clients, projects, milestones, statuses, modules, worktypes) that it may not make sense to pull information about them each time you need to refresh a task.

Please be respectful of other users and other developers when using the API. Repeated suspensions may trigger a ban on API access to your user and/or customer account. Please see our terms of service for more information.

Getting Help

If you need help with the API there are two ways to get it:

  1. Fill out the Submit a Bug or Feature Request from within your Intervals account.
  2. Email our API support team at api@myintervals.com

OpenAPI specification

The complete API definition is published as a single JSON document at /api/openapi.json. Use it for codegen, tooling, and agents that need every endpoint and parameter in one place. For interactive docs, open Swagger UI on SwaggerHub.

Start tracking time today

Join 5,000+ companies spending their time wisely with Intervals.

Try Intervals free