API: Basics

Noko’s RESTful API enables your application or script to access entries (list/search, create, update, delete, mass import), projects (list, read, create, update, delete, archive, activate), tags (list) and users (list, read, create, update, deactivate, get avatar).

Important Freckle is getting a new name: Noko!

Below are the steps you'll need to take to make sure your integrations and apps still work! Want to learn more? You can read our announcement here

What is the timeline?

March 25, 2019 <subdomain>.nokotime.com/api will be live, and the API docs will change to reference “Noko” to prevent regressions.
August 31, 2019 All requests to <subdomain>.letsfreckle.com/api will return 301 Moved Permanently and point to the corresponding URI in api.nokotime.com/api
September 15, 2019 Requests to <subdomain>.letsfreckle.com/api will no longer work

What do I need to do?

Once <subdomain>.nokotime.com/api is live on March 25 (click here to see this time on EveryTimeZone), change your apps and integrations to point to:

https://<subdomain>.nokotime.com/api

Aside from the domain name change, the rest of the API will remain exactly the same.

What if I have questions?

If you have any questions at all, please email or tweet us! We’re incredibly grateful that you use the API, and we want to make the transition as smooth as possible.

Many applications use the Noko 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 Noko API, please email, tweet, or send us a message on Facebook.

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

Noko’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 Noko API docs and submitting a pull request!

API limitations

We plan to extend and adapt the API to allow access to more resources in the future. If you have any questions or feedback, please don’t hesitate to use the big blue feedback button on the left. Currently, there are no APIs for timers, expense tracking, invoices or assigning freelancers to projects. If you have specialized needs for an API, let us know!

There are no API call limits in place, but we reserve the right to lock out abusive clients that call the API too often. Use common sense, caching, and don’t do expensive API calls (mostly listing a lot of entries) too often.

Naming client applications

If you plan to release a public client app for Noko (such as a native mobile app, regardless if it’s paid-for or free) you’re welcome to do so. Do not name apps “Noko” or “Noko for <platform>”. Please contact us first with more details about your app if you want to use “Noko” or the Noko logo as name or icon of your app!

Noko API Libraries

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

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

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

URLs

Accessing the Noko API uses the following URL schema:

https://<subdomain>.nokotime.com/api/<resource>

Where subdomain is the subdomain of the account you want to access and resource is the resource (e.g. entries, projects, tags, users and so on).

For example, getting a list of projects from the “apitest” account via JSON would result in the URL:

https://apitest.nokotime.com/api/projects.json

Resources are normally accessed via SSL only. Some resources can also be accessed through a regular HTTP request.

Authentication

An authentication token is needed for accessing the API. This token authenticates a specific user of the account and can be found in “settings & tools > API” in the Noko user interface. Treat authentications tokens like passwords!

A user can reset the API token at any time—be sure to handle authentication errors in your application.

The token has to be sent for each request your application makes to the Noko API.

There are two ways to send the token—examples are given using the cURL command line tool:

As query parameter named token:


curl -v https://apitest.nokotime.com/api/projects.json?token=lx3gi6pxdjtjn57afp8c2bv1me7g89j

As HTTP header X-NokoToken:


curl -v -H "X-NokoToken:lx3gi6pxdjtjn57afp8c2bv1me7g89j" https://apitest.nokotime.com/api/projects.json

For better readability of URLs, in this documentation the HTTP header method will be used for the cURL examples. It’s generally also a good idea to use the HTTP header method if you wrap Noko API calls in a library or module in your code.

<p class=note> In order to make it easier for users to authenticate in interactive client applications such as on mobile devices, the token can be retrieved via the /api/user/api_auth_token API method by using HTTP Basic Auth with the user’s email and password. See the Users section for more information. </p>

Pagination

Most API resources are non-paginated, meaning they return the full result set. However Entries list is paginated, and more resources could become paginated in the future.

When there are more results available for a request, a “next” URL will be present in the Link response header

GET https://apitest.nokotime.com/api/entries.json
Link: <https://apitest.nokotime.com/api/entries.json?page=2&per_page=100>; rel="next"

To get more results, simply repeat the request with the new URL until there are enough results in total, or there is no more “next” link (if it’s necessary to fetch all data).

It’s safe to apply this logic to all API requests, even when fetching resources that are not currently paginated.

Response codes and error handling

A call to the API can result in one of six different outcomes:

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.

Roles

There are currently four user roles in Noko: administrator, owner, member, and freelancer.

Each Noko user is assigned to one of these roles. Depending on the role, certain parts of the API may not be available. For each resource, this documentation explains which roles have access and if there are any per-role restrictions (for example, a user with the “freelancer” role doesn’t have access to all projects).

Data Formats

The Noko API can accept and return data in JSON or XML.

Because it’s awesome, we’ll mostly use examples in JSON in this documentation, however, XML works just as well.

There’s no default format—to choose the data format you need to either add a .xml or .json extension to URL you are calling, or set the Accept HTTP header to text/xml or application/json.

Field formats

Noko uses the following field formats:

There’s limits on the text length of some fields, but, with the exception of tags which are limited to 30 characters, it’s highly unlikely that you’ll hit those.

API Test Account

You can use our API test account for testing your code. The data from this test account will be regularly wiped—don’t rely on your test data being there the next day. Also note that you might not be the only person using this token at a certain time.

Domain: apitest.nokotime.com
Token: lx3gi6pxdjtjn57afp8c2bv1me7g89j

If you do any kind of non-trivial client application or have special needs for API testing, we recommend that you create a Noko account specifically just for testing your application, so you can be sure your data stays intact while you develop!

Try it now!

JSON
XML

    $ curl -H "X-NokoToken:lx3gi6pxdjtjn57afp8c2bv1me7g89j" https://apitest.nokotime.com/api/projects.json
    
Instead of using cURL, you can also try it directly in your browser with hurl. You should see something like:
[
  {
    "project": {
      "group_name": null,
      "remaining_minutes": null,
      "name": "From iPhone 5",
      "billable": true,
      "created_at": "2011-02-04T06:12:31Z",
      "cached_tags": [ /* ... */ ],
      "minutes": 15,
      "import_id": null,
      "updated_at": "2011-10-19T15:59:56Z",
      "account_id": 5039,
      "billable_minutes": 15,
      "enabled": true,
      "id": 40413,
      "project_group_id": null,
      "user_id": null,
      "unbillable_minutes": 0,
      "budget": null,
      "color_hex": "55c9ef",
      "budget_minutes": null,
      "invoice_recipient_details": null,
      "stepping": 15
    }
    /* ... */
  }
]

    $ curl -H "X-NokoToken:lx3gi6pxdjtjn57afp8c2bv1me7g89j" https://apitest.nokotime.com/api/projects.xml
    
Instead of using cURL, you can also try it directly in your browser with hurl. You should see something like:
<?xml version="1.0" encoding="UTF-8"?>
<projects type="array">
  <project>
    <account-id type="integer">5039</account-id>
    <billable type="boolean">true</billable>
    <billable-minutes type="integer">7440</billable-minutes>
    <budget type="integer" nil="true"></budget>
    <cached-tags type="yaml"><!-- YAML of cached tags --></cached-tags>
    <color-hex>13a480</color-hex>
    <created-at type="date time">2009-10-16T09:04:50Z</created-at>
    <enabled type="boolean">true</enabled>
    <id type="integer">8475</id>
    <import-id type="integer" nil="true"></import-id>
    <invoice-recipient-details nil="true"></invoice-recipient-details>
    <minutes type="integer">7560</minutes>
    <name>Fixture Company</name>
    <project-group-id type="integer" nil="true"></project-group-id>
    <stepping type="integer">5</stepping>
    <unbillable-minutes type="integer">120</unbillable-minutes>
    <updated-at type="date time">2011-10-19T15:59:56Z</updated-at>
    <user-id type="integer" nil="true"></user-id>
    <minutes type="integer">7560</minutes>
    <budget-minutes nil="true"></budget-minutes>
    <remaining-minutes nil="true"></remaining-minutes>
    <unbillable-minutes type="integer">120</unbillable-minutes>
    <group-name nil="true"></group-name>
  </project>
  <!-- ...more projects -->
</projects>