Working with Tweek API can be divided into three parts:
Navigate to tweek.so in your web browser and open the user profile, scroll down to the bottom of the popup and press the API Settings button.
After that you’ll see the popup that allows you to generate the API Key, press Generate button to proceed.
Once generation is complete you’ll see API Settings with information about read and write quotas.
We’re using Google Identity Platform as our authentication provider so you have to obtain a JWT token for your user by calling Google Identity Platform endpoints. Also it is your responsibility to refresh this token once it expires.
As a first step you need to request idToken and refreshToken from Google Identity Platform, you can do it using the following request. Also you will need to provide API-key along with the request parameters which is:
AIzaSyC7_JO56peYl_eD9QODZlLwZpMclLUoC9s
POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={{apiKey}}
Content-Type: application/json
Request body should contain the following object:
{
"email": "{{email}}",
"password": "{{password}}",
"returnSecureToken": true
}
As a response you will receive the object containing a bunch of fields, the most important for you will be:
{
...
"idToken": "string",
"refreshToken": "string",
"expiresIn": "string"
...
}
You can use expiresIn field to understand if it's necessary to refresh existing idToken or if it's still valid.
To exchange refreshToken to new idToken you will need to make another request to Google Identity Platform like the following:
POST https://securetoken.googleapis.com/v1/token?key={{apiKey}}
Content-Type: application/x-www-form-urlencoded
Request body should contain the following form urlencoded data:
grant_type=refresh_token&refresh_token={{refreshToken}}
As a response you will receive the object with the following fields:
{
"expires_in": "3600",
"token_type": "Bearer",
"refresh_token": "[REFRESH_TOKEN]",
"id_token": "[ID_TOKEN]",
"user_id": "tRcfmLH7o2XrNELi...",
"project_id": "1234567890"
}
From which you can get new idToken, refresh token and expiration time.
First version of Tweek API is able to provide you with a bunch of functionality like requesting a calendar list, working with tasks and acquiring user’s custom colors.
Tweek API is available on the following URL: https://tweek.so/api/v1
All endpoints have to be called with Authorization mandatory header:
Authorization: Bearer {{your valid idToken}}
Also for POST requests you have to additionally append the following header:
Content-Type: application/json
You can find the list of endpoints with a short explanation below.
Important thing to note: if the field of the object has a question mark in the name then this field is optional and can have a value of null or can be absent in the object.
Endpoint: /calendars
Request type: GET
Returns a list of calendars that are available for the user.
Response example:
[
{
"id": "string" (id of the calendar),
"name": "string" (name of the calendar),
"ownerId": "string" (id of calendar’s owner),
"role": "string" (current user’s role in this calendar),
"lists: [list of someday sections for this calendar],
"isDefault": "boolean" (whether it is default calendar or not)
}
]
Someday section object format:
{
"id": "string" (id of the someday section),
"name": "string" (name of the someday section),
"hidden": "boolean" (whether this section is collapsed on mobile clients),
"webHidden": "boolean" (whether this section is collapsed on the web)
}
User’s role enum values:
ROLE_OWNER - the user is owner of this calendar
ROLE_EDITOR - the user is not the owner, but can edit this calendar
ROLE_VIEWER - the user can only view data in this calendar
Endpoint: /tasks?calendarId={calendarId}[&startAt={next document id}][&dateFrom={iso-date}][&dateTo={iso-date}]
Request type: GET
Returns a list of tasks for the user. Tasks are returned in a form of pages, each page’ size is limited to 100 for the v1. This is intended for pagination purposes.
To get all tasks in the current calendar you will need to make a series of requests to the same endpoint. In each request you have to pass a startAt query parameter with the data from nextDocId field that you’ve got from the response of the previous request. Repeat request cycle until you get null in the nextDocId field. To obtain the first page do not pass the startAt parameter.
It is also possible to filter tasks by date (taking into account date and dtStart fields), to do so you simply have to pass dateFrom and/or dateTo query parameters. Important thing to note: tasks in someday sections don't have a date so when date-filtering is active these tasks will be filtered out from the result data set.
Response example:
{
"pageSize": "number" (total number of tasks in the page),
"nextDocId": "string" (the identifier of the first task in the next page),
"data": [list of task objects]
}
Task object format will be described in the next section.
Endpoint: /tasks/{taskId}
Request type: GET
Returns the task object by its identifier.
Response example:
{
"id": "string" (identifier of the task),
"calendarId": "string" (identifier of the calendar),
"color?": "string" (identifier of the color),
"done": "boolean" (whether the task is closed or not),
"text": "string" (title of the task),
"note?": "string" (text of the task),
"checklist?": [a list of subtask objects],
"notifyAt?": "string" (ISO-date of the task’ notification),
"date?": "string" (date of the task in yyyy-MM-dd format, or someday section identifier),
"dtStart?": "string" (start date of the task for recurrent tasks in yyyy-MM-dd format),
"isoDate?": "string" (date of the task in ISO-format for tasks from integration with other calendars),
"freq?": "number" (recurrent task type for Tweek-recurrents),
"gcal": "boolean" (whether this task is from the Google Calendar or not),
"recurrence?": "string" (RRULE-string rule for custom recurring tasks or from integration with other calendars),
"recurringTodoId?": "string" (id of the base recurrent task - first task in the sequence),
"listId?": "string" (id of the someday section for this task),
"deleted?": "boolean" (whether this task is temporary deleted from the calendar)
"isBase?": "boolean" (is this task a base task for recurrent sequence),
"isBaseDeleted?": "boolean" (if this property is true then this task acts as the last task in the recurrent sequence. For example cases when we delete all the following tasks in the sequence then first deleted task is marked with isBaseDeleted flag)
"source?": "object" (object with information about integration with AppleCal/Reminders.app, see TaskSource type below)
}
Subtask object format:
{
"id": "string" (id of the subtask),
"text": "string" (subtask’ text),
"done": "boolean" (whether this subtask is closed or not),
"highlighted?": "boolean" (is this subtask "starred"),
"indent?": "number" (subtask’ indentation from 0 to 2),
"variant?": "string" (subtask’ type: "header" or "checklistItem")
}
TaskSource object format (source field of the task object):
{
"identifier": "string" (id of task in the integration source - AppleCal/Reminders.app),
"type": "string" (integration type: "apple" or "reminders"),
"calendarIdentifier?": "string" (id of the calendar or list in the source),
"lastModifiedDate?": "string" (last modification date in the ISO-format),
}
Tweek-recurrents enum (freq field of the task object):
NEVER: 0,
DAILY: 1,
WEEKLY: 2,
MONTHLY: 3,
ANNUALLY: 4,
WEEKDAYS: 5,
TWO_WEEKS: 6,
CUSTOM: 7
Endpoint: /tasks
Request type: POST
Creates a new task in the selected calendar.
You have to provide the task object in JSON format along with the request.
It is important to note that our API is expecting you to always include the calendarId field along with the task object so the backend can create the task in a particular calendar. On the other hand, the task identifier is generated by the API itself so you don’t need to include it.
Response example:
{
"id": "string" (identifier of the newly created task)
}
Endpoint: /tasks/{taskId}
Request type: PATCH
Updates the task object by its identifier.
You have to provide the object with fields for modification in JSON format along with the request.
Endpoint: /tasks/{taskId}
Request type: DELETE
Completely deletes the task object from the database by its identifier.
Endpoint: /custom-colors/{userId}
Request type: GET
Returns a list of custom colors for a particular user.
Response example:
[
{
"id": "string" (id of the color),
"color": "string" (color code for foreground in HEX format),
"backgroundColor": "string" (color code of the background in HEX format)
}
]