Freckle API v2

Welcome to the Freckle Developer Documentation!


Freckle provides a secure Restful JSON API over HTTPS; with authentification either via OAuth or, for non-user-facing integrations, generated tokens.

There’s many public and internal apps using the Freckle API, among them web applications like Beanstalk, Github, and Planscope; native mobile and desktop applications like Punch. Plus, many customers have created internal applications that integrate Freckle with their own custom software and services, such as Pecas. You can even make a giant LED display for your timer!

Be creative! If you want to let us know about how you’re using the Freckle API, please email or tweet us!

Freckle’s API docs are on Github: if you find an error or omission in the API documentation, you can help fix it quickly by forking the Freckle API docs and submitting a pull request.

Not a developer?

If you’re not a developer, or just want to quickly connect Freckle to other internet-based apps your use, consider using Zapier.

Freckle is one of 500+ services supported by Zapier, which allows drag-and-drop integration and complex workflows with other internet-based software. For example, you could alert your Slack chat room that an invoice has been paid, or send new entries directly to a Google Doc!

Freckle API Libraries

There are several 3rd-party open source libraries for popular languages available:

Additionally, the command-line tool Pippi can log time and access other API functionality, which is great if you want to use the Freckle API from a shell script.

These are 3rd-party libraries and Freckle can't provide support for them. Please contact the library authors directly if you need help with these.

Naming client applications

If you plan to release a public client app for Freckle (such as a native mobile app, regardless if it’s paid-for or free) you’re welcome to do so, and we’re happy to help!

Please note that Freckle® is a registered trademark of Slash7 LLC. Do not name apps “Freckle” or “Freckle for ”. Please contact us first with more details about your app if you want to use “Freckle” or the Freckle logo as name or icon of your app.


API Resources

API Resources are accessed through this base endpoint:

For example, the URL for accessing the timers of a user is:

This is different than API v1, where the API was accessed through an account-specific endpoint. If you are migrating from API v1, make sure to change the endpoint URL.


Authenticating through OAuth is handled through a different endpoint than accessing API Resources:

For example, the URL to redirect users to request access to their Freckle account is:


General Schema

The following rules define the general schema of the API:

User Agent (required)

All API Requests must include a valid User-Agent header. Requests with no User-Agent header will be rejected. We highly recommend to set a name and version, e.g. MyFreckleBot/1.0. This will help us help you better in case debugging is required!


User-Agent: MyFreckleBot/1.0

Rate Limiting

You can perform up to 2 requests per second from the same IP address. Requests that exceed this limit will at first be slowed down (for up to 5 requests total). If you send more requests than that, remaining requests will be dropped and return an empty 429 Too Many Requests response.

If you receive a 429 response, make sure to wait a little longer between requests.

Status: 429 Too Many Requests

Client Errors

There are a few errors that can occur while making API calls. the following are the kinds of errors you may encounter when using the API.

Invalid JSON

Status: 400 Bad Request
  "message": "JSON Parsing Error"

Wrong type of JSON sent

Status: 400 Bad Request
  "message": "Body should be JSON Hash"

Fields were not in the correct format

Status: 400 Bad Request

The user does not have the necessary permissions to perform an action

Status: 403 Forbidden

Account does not include this feature

Status: 403 Forbidden
  "message": "Account does not include this feature"

Account is currently locked for migration

Status: 503 Service Unavailable
  "message": "Freckle is changing the internal data for your account so you can start using hashtags"

The errors array

When validation errors occur, the errors array is populated with objects that explain why the request was invalid. Each object has the following fields:

Deleting or Archiving Resources

In certain cases, resources can only be deleted if certain conditions are met. If these resources cannot be deleted, they may be archived instead. An example of this is the Project resource: a project cannot be deleted if it has any entries, invoices, or expenses; but it can be archived. However, if a project does not have any entries, invoices, or expenses; then it cannot be archived (it can only be deleted).

For these resources, we have two separate actions for deleting and archiving. The Delete action is accessible through the DELETE HTTP verb, while the archive action is accessible via PUT archive/.

When a resource cannot be deleted

The delete action will only succeed if the resource is able to deleted. If the resource is unable to be deleted, a 400 error will be returned, with an explanation for why the resource cannot be deleted.

This explanation uses a new error code: dependent, and the field field will indicate which associated resources exist and are preventing this resource from being deleted.

Note that custom error codes can be defined for a resource’s delete action, and will be documented in the resource’s API page.

Status: 400 Bad Request
  "message": "The Project cannot be deleted because it has entries, expenses, or invoices.",
  "errors": [
      "resource": "Project",
      "field": "base",
      "code": "not_deletable"

When a resource cannot be archived

The archive action will only succeeed if the resource is able to archived. If the resource is able to be deleted, then it is unable to be archived. If a resource is unable to be archived, a 400 error will be returned, with an explanation for why the resource cannot be archived.

Status: 400 Bad Request
  "message": "The Project should be deleted because it does not have any entries, expenses, or invoices.",
  "errors": [
      "resource": "Project",
      "field": "base",
      "code": "deletable"

Background Processing

In some cases, an API action may need to be processed in the background. In these cases, a 202 response will be returned with a message that the user will be notified via email when the action has completed.

For example, a large tag merge may return the following response:

Status: 202 Accepted
  "message": "The user will be sent an email once this tag merge is complete."

Uploading Files

If an action includes a file as one of the request parameters, then you must send your request parameters as traditional multipart HTTP key/value pairs instead of a JSON object.

Additionally, the Content-Type header of the request must be set to: multipart/form-data. If you don’t set the header, the request will not be processed and a 400 Bad Request error will be returned.

HTTP Redirection

HTTP Redirection will be used when appropriate, meaning that clients should assume any request may result in a redirection.

Redirect responses will have a Location header field which contains the URI of the resource to which the client should repeat the request.

Permanent Redirection

Status: 301 Moved Permanently

This and all future requests should be directed to the new URI.

Temporary Redirection

Status: 302 Found
Status: 307 Temporary Redirect

Repeat the request verbatim to the URI specified in the Location header, but clients should still continue to use th original URI in future requests.

Supported HTTP Verbs

Can be issued against any GET request to return just the HTTP header info.



Used for replacing resources or collections and performing actions on a resource.



All resources have one or more *_url properties linking to other resources or custom actions on this resource. They are meant to provide explicit URLs so clients don’t have to generate them. Using these URLs will make API upgrades easier for developers. All URLs follow RFC 6570 URI templates.

Example (Timer Object):

  "id": 123456,
  "state": "running",
  "seconds": 180,
  "formatted_time": "00:03:00",
  "date": "2013-07-09",
  "description": "freckle work",
  "user": {
    "id": 5538,
    "email": "[email protected]",
    "first_name": "John",
    "last_name": "Test",
    "profile_image_url": "",
    "url": ""
  "project": {
    "id": 37396,
    "name": "Gear GmbH",
    "billing_increment": 10,
    "enabled": true,
    "billable": true,
    "color": "#ff9898",
    "url": ""
  "url": "",
  "start_url": "",
  "pause_url": "",
  "log_url": ""


Responses including multiple items will be paginated to 30 items per page by default. The page can be changed by using the page query parameter. Note that the page parameter starts with 1.

Some actions can use the per_page parameter to return up to 1,000 items per page.

When pagination is used, the Link header includes the URLs used in Pagination. Clients should use these links instead of following their own, in case pagination rules change in the future.

Link: <>; rel="next",
  <>; rel="prev",
  <>; rel="first",
  <>; rel="last"

The rel attribute indicates what the URL links to: