API V2 is still in beta!

Version 2 of the Freckle API is still in beta and subject to change. Have a question, feature request, or suggestion? Send us a message!


Many applications use the Freckle API every day, among them web applications like Beanstalk, Github, and Planscope; native mobile and desktop applications like Pigment and Punch; as well as many internal applications that our customers write to integrate with other software and services. Be creative! If you want to let us know about how you’re using the Freckle API, please email, tweet, or send us a message on Facebook.

Freckle is also one of the many services listed on Zapier which allows drag-and-drop integration of Freckle with other internet-based software (for example, you can send new Freckle entries to your Campfire chat room!).

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!

Freckle API Libraries

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

API v1 Libraries:

These libraries only support API v1, meaning that some of the actions and options from API v2 will not be available in these libraries.

Additionally, there are command line tools that can log time and access other API functionality, which is great if you want to use the Freckle API from a shell script:

API v2 Libraries:

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. 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 a single endpoint:

For example: if we wanted to access a user’s timers, the URL would be:

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: if we wanted to redirect to users to Freckle to request access to their Freckle account:


General Schema

The following rules define the general schema of the API:

A User Agent is Required

All API Requests must include a valid User-Agent header. Requests with no User-Agent header will be rejected. We recommend two options:


User-Agent: My-Freckle-App

Rate Limiting

You can perform up to 2 requests per second from the same IP address. Requests that exceed this limit will return a 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, some resources can only be deleted if certain conditions are met. If these resources cannot be deleted, then they may be archived. 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 (such as when creating an import), then you must send your request parameters as traditional multipart HTTP key/value pairs instead of as a JSON object.

Additionally, the Content-Type header of the request must be set to: multipart/form-data, otherwise 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 requests.

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 by default. The page can be changed by using the page query parameter. Note that the page paremter starts with 1.

Some actions can use the per_page parameter, which will be documented in the resource’s API 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: