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!
- Noko API Libraries
- URLs
- Authentication
- Pagination
- Response codes and error handling
- Rate Limiting
- Roles
- Data Formats
- Field formats
- API Test Account
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>.nokotime.com/api will return 301 Moved Permanently and point to the corresponding URI in api.nokotime.com/api
|
September 12, 2019 | Requests to <subdomain>.nokotime.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:
- Ruby: letsfreckle-client
- Python: ipmb/freckle
- Python: bitmazk/python-freckle-client
- Node.js: nodefreckle
- Clojure: clj-freckle
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.
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.
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:
-
Everything works fine—a HTTP status code in the 200 range is returned; for reads and updates
200 OK
and for newly created resources201 Created
(which also return aLocation
header pointing to the newly created resource). -
Authentication fails or the user’s role doesn’t permit an action:
401 Unauthorized
. If your application is an interactive, you likely want to ask the user for new security credentials and not use the API again until a new API token is provided. Ideally, your interactive app doesn’t ever run into the case that a users’ role doesn’t permit an action, but it can happen especially if you cache data and it gets out of sync (for example the projects a “freelancer” user has access to). If you run into this issue, it’s a good idea to invalidate your caches and fetch the data from the API again. -
On creating or updating, if required fields are missing,
422 Unprocessable Entity
is returned. -
There was an unhandled exception on the server side:
500 Internal Server Error
: This is rare, but can happen in exceptional circumstances. The best thing to do is to try the same call later. -
There’s a timeout or a network issue and the connection is dropped without response. This is rare but it does happen. Try the call again.
-
If too many requests are performed and the rate limits are exceeded:
429 Too Many Requests
.
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:
- IDs are stored as 4-byte integers (range 1 to 2147483647)
-
Timestamps are given UTC-based, e.g.
2012-01-09T08:33:29Z
-
Dates are given YYYY-MM-DD, e.g.
2011-07-26
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!
$ 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 .
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 .
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>