This document covers the methods and techniques required to access and modify user content in Wrike through the API.

Authorization

Wrike’s API uses the OAuth 2.0 protocol for authorization. Every API request must contain the Authorization header (preferred option) or the access_token parameter with the OAuth 2.0 access token. Access scopes may be requested during the authorization process. See the OAuth 2.0 authorization description for details.

Overview

The API methods are organized in the RESTful way and support GET, POST, PUT and DELETE requests. If a client is not able to execute all kinds of requests, then only GET requests can be used with an additional method parameter, which is set to the required request type (e.g., ...&method=POST).

To access a specific API method, the request token should have at least one of the scopes required by this method. Supported scopes: Default, wsReadOnly, wsReadWrite, amReadOnlyWorkflow, amReadWriteWorkflow, amReadOnlyInvitation, amReadWriteInvitation, amReadOnlyGroup, amReadWriteGroup, amReadOnlyUser, amReadWriteUser.

Each API method operates on a certain type of resource with a defined model (for details, see the Methods section below) and produces a JSON response that contains the entity type in the kind field and an array of entities in the data field. Client can pass an additional state parameter in the request, which also will be included in the response.

Response example:

HTTP codeerrordetails
400invalid_requestRequest HTTP type is invalid, request critical data is absent or malformed (e.g., no attachment body)
400invalid_parameterRequest parameter name or value is invalid
400parameter_requiredRequired parameter is absent
401not_authorizedUser is not authorized (authorization is invalid, malformed or expired)
403access_forbiddenAccess to requested entity is denied for user
403not_allowedRequested action is not allowed due to license/quota limitations, e.t.c.
404resource_not_foundRequested entity is not found
404method_not_foundRequested API method does not exist
500server_errorServer side error

Wrike API uses the OAuth 2.0 protocol for authorization. The OAuth 2.0 Authorization Framework protocol is described in http://tools.ietf.org/html/rfc6749. OAuth standard defines four flows for different use cases: authorization code, implicit, resource owner password credentials, and client credentials. At the moment, we support only authorization code flow.

This documentation contains a brief description of the OAuth 2.0 authorization process. For details, please see [RFC6749, 4.1.].

  1. Explore OAuth 2.0 authorization flow
  2. Skip OAuth 2.0 using permanent access token

Initial Setup

Before you get started with OAuth 2.0 authorization, you’ll need to register and properly set up the Wrike API application. Each application is assigned a unique Client ID and Client Secret which will be used in the OAuth flow. You can find the client credentials of your application and manage other options on App Console. Screenshot below demonstrates the configuration section of any application.


Please note the “Client ID” and “Client secret” fields as you will need them on the next steps.

However, if you created your application by filling out the form on the Get Started page you will receive your client credentials by email.

OAuth 2.0 authorization flow

1. Requesting authorization code [RFC6749, 4.1.1.]

To start the authorization process, the user should click on the link in your application that will direct him to the following URL:

https://www.wrike.com/oauth2/authorize?client_id=<client_id>&response_type=code

Please note “client_id” parameter above - it should exactly match “Client ID” field you get from App Console on the previous step.

The authorize URL can also contain the optional parameters. See details about request parameters in the table below:

client_id Required The client_id you obtained in the Initial Setup.
response_type Required Whether the endpoint returns an authorization code. For web applications, a value of code should be used.
redirect_uri Optional URI where the response will be redirected. We assume that you have a working web server with a public address that can correctly handle Wrike requests.
Redirect URI should comply with OAuth2 standard requirements and utilize HTTPS protocol. Use https:// localhost for local development.
state Optional An arbitrary string that will be included in the response to your application at the end of OAuth flow.
This parameter is intended to preserve some state object set by the client in the authorization request, and make it available to the client in the response. The main purpose of this is preventing Cross Site Request Forgery (CSRF).
However “state” parameter is just a string, so you can include anything that might be useful for your application.
scope Optional OAuth scopes allow you to specify exactly how your application needs to access Wrike data. This parameter is expressed as a list of comma-delimited, case-sensitive strings. You can find scopes required for each API method in the corresponding section. For example, “Create Task” API method requires the following scopes: Default, wsReadWrite

2. Handling authorization code [RFC6749, 4.1.2.]

After clicking on the authorization URL on the first step, the user is redirected to the Wrike login page if he or she is not already logged in.

The user will enter his password and then will be redirected to a consent page to get confirmation approval.

If the user grants access in the previous screen, the consent page will redirect the client to the redirect_uri with the code parameter set to the authorization code and state parameter, if you included one. Please note that the authorization code is valid for only 10 minutes.

For example, if your redirect URI was https://www.myapp.com/oauth2_uri, Wrike would redirect to:

https://www.myapp.com/oauth2_uri?code=<authorization_code>

If the user denies access, Wrike will redirect him back to your redirect_uri with error parameters:

https://www.myapp.com/oauth2_uri?error=access_denied&error_description=<error_description>

3. Exchanging authorization code for access token [RFC6749, 4.1.3.]

Access credentials are requested by executing POST request to a token URL with an authorization code.

POST https://www.wrike.com/oauth2/token
//Parameters:
client_id=<client_id>
client_secret=<client_secret>
grant_type=authorization_code
code=<authorization_code>

All parameters here are mandatory. See details about them in the table below:

client_id Required The client_id you obtained in the Initial Setup.
client_secret Required The client_secret you obtained in the Initial Setup
grant_type Required Must be authorization_code
code Required The authorization code you retrieved on the previous step
Copy to clipboard
CURL example:
curl -X POST -d "client_id=&client_secret=<client_secret>&grant_type=authorization_code&code=<authorization_code>" https://www.wrike.com/oauth2/token

Response example:

  • {
  •         "access_token": "2YotnFZFEjr1zCsicMWpAA",
  •         "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
  •         "token_type": "bearer",
  •         "expires_in": "3600",
  •         "host": "www.wrike.com"
  • }

Please notice the "host" parameter. Wrike stores customer data in several data centers located in USA and European Union and you need to use a specific base URL to access user's data, based on where it is located. All the following requests on behalf of this user should be done using the base URL which you build by using the "host":

https://<host>/api/v3

Please review the Overview section of the documentation to get more details on how we store customer data and why you need to use different base URLs.

4. Using access token

Every request to the API should be done using the HTTPS protocol with the access token, which should be passed in the authorization header (preferred option) or the access_token parameter. For all requests, you should be using the base URL which you built based on the "host" parameter passed to you on the previous step.

Let’s assume that we want to obtain information about yourself. Thus we have to execute the following request:

Copy to clipboard
CURL example:
curl -X GET -H "Authorization: bearer " https://www.wrike.com/api/v3/contacts?me=true

You’ll receive the response similar to:

  • {
  •    "kind": "contacts",
  •    "data":
  •    [
  •        {
  •            "id": "KUAJ25LC",
  •            "firstName": "Test",
  •            "lastName": "User",
  •            "type": "Person",
  •            "profiles":
  •            [
  •                {
  •                    "accountId": "IEAGIITR",
  •                    "email": "test.user@myapp.com",
  •                    "role": "User",
  •                    "external": false,
  •                    "admin": false,
  •                    "owner": true
  •                }
  •            ],
  •            "avatarUrl": "https://www.wrike.com/avatars//7E/A2/Box_ffdf2a2e_84-84_v1.png",
  •            "timezone": "Europe/Moscow",
  •            "locale": "en",
  •            "deleted": false,
  •            "me": true
  •        }
  •    ]
  • }

Each access token is valid for one hour. After the access token has expired, the application should refresh it to continue.

The server response for an expired access token will be as follows:

  • {
  •    "error": "not_authorized",
  •    "errorDescription": "Access token is unknown or expired"
  • }


If you're using the wrong base URL, the server will respond with a 401 error:

  • {
  •    "error": "not_authorized",
  •    "errorDescription": "Access token is unknown or invalid"
  • }

5. Refreshing access token [RFC6749, 6.]

The access token is refreshed by a POST request to a token URL with a refresh token. Please bear in mind that you initially get a pair of tokens by querying the https://www.wrike.com/oauth2/token endpoint, but to refresh the token you need to use the specific base URL, which you built based on the "host" parameter passed to you in the second step.

For users located on the USA data center, you should use the https://www.wrike.com/oauth2/token endpoint to get a new access token and for users located on the EU data center you should use https://app-eu.wrike.com/oauth2/token.

POST https://www.wrike.com/oauth2/token
//Parameters:
client_id=<client_id>
client_secret=<client_secret>
grant_type=refresh_token
refresh_token=<refresh_token>

All parameters here are mandatory. See details about them in the table below:

client_id Required The client_id you obtained in the Initial Setup.
client_secret Required The client_secret you obtained in the Initial Setup
grant_type Required Must be refresh_token
refresh_token Required The refresh token you retrieved in step 3
Copy to clipboard
CURL example:
curl -X POST -d "client_id=<client_id>&client_secret=<client_secret>&grant_type=refresh_token&refresh_token=<refresh_token>" https://www.wrike.com/oauth2/token

Permanent access token

Generally for production purposes, OAuth 2.0 is the prefered method of authorization in the Wrike API. However if you’d like to simply test the API features or create an application which is not intended to be used by multiple users, you can use an alternative approach — the permanent token.

The permanent token is a normal token that never expires: you can obtain it once and then use it as long as you want without needing to refresh or re-authenticate. This means you can build standalone integrations without any web server to support the OAuth 2.0 authorization flow.

Obtaining a permanent token

To receive a permanent token you need to open your application on App Console and click the “Obtain token” link. That’s it. That’s why the permanent token is the best way to get started with the Wrike API. But be careful! The permanent token allows applications to gain access to all data in Wrike on your behalf. Keep your permanent token private and revoke it once you don’t need it.

Please note that created token will be shown only once - write it down in a safe place

Revoking a permanent token

To revoke a previously created permanent token, you need to open your application App Console, find your token, and click “Revoke token” link.

Next Steps

Explore API methods to get maximum value from your Wrike integration. If you have any questions or feedback, feel free to contact Wrike Support Team or visit our API Community section on the Wrike Help portal.

Task description can be set and received in HTML format with a limited set of tags. See table below for a list of allowed tags.

Formatting Option HTML Tags Notes
Line Break <br>
Headers <h1>, <h2>, <h3>, <h4>, <h5>, <h6>
Bold <strong>, <b>
Italics <em>, <i>
Underline <u>
Strikethrough <s>
Highlight Text <span style="color:{hex}"> Insert color code instead of {hex}
Links <a href="https://www.wrike.com"> Add 'rel="nofollow"' for all links that direct you out of the Wrike Workspace. Allowed protocols: http, https, ftp, mailto
Insert Image <img> Only task attachments can be used as an image source
Ordered List <ol> List items should be wrapped in an <li> tag
Unordered List <ul> List items should be wrapped in an <li> tag
List item <li> For both ordered and unordered lists
Table <table> Only regular NxM tables are supported, without merged and split cells
Table row <tr>
Table cell <td>

Comments can be set and received in HTML format with a limited set of tags. See table below for the list of allowed tags. If you query task comments with the parameter "plainText = true" the comment will be returned without any tags.

Formatting Option HTML Tags Notes
Line Break <br>
Links <a href="https://www.wrike.com"> Add 'rel="nofollow"' for all links that direct you out of the Wrike Workspace. Allowed protocols: http, https, ftp, mailto
@mention <a class="stream-user-id avatar" rel="userID">@John Doe</a> Put user ID inside "rel" parameter. @ corresponds to the @ symbolz
Quote of a comment <blockquote data-entrytype="comment" data-entryid="${Comment ID}" data-user="${User ID}" data-date="${timestamp}">
Quote of task description <blockquote data-entrytype="[task|folder]" data-entryid="${Task or Folder ID}" data-title="${Task or Folder title}">Quoted description part</blockquote>

Web-hooks (Beta)

Webhooks allow you to subscribe to notifications about changes in Wrike instead of having to rely on periodic polling. When webhooks are in place, a small package of information (‘payload’) is sent to your HTTP endpoint when specific changes occur.

We support the following scopes for webhooks:

  1. Folder webhooks - fire notifications about changes to tasks within a single Folder or Project. You must subscribe to Folders/Projects individually — subscribing to a Folder/Project does not subscribe you to its Subfolders/Subprojects.
  2. Account webhooks - fire notifications about changes to any tasks in the Account. Includes changes to all tasks (which are shared with you) in the account.

API Methods

REST-style API methods allow you to create webhooks, get lists of your webhooks and their states, update webhook states, and delete webhooks.

Create Webhooks

  • [POST] /folders/{folderId}/webhooks — Creates a webhook for a target Folder / Project.
    • Parameters: hookUrl - URL of the server which will receive the payload.
  • [POST] /accounts/{accountId}/webhooks — Creates a webhook for a particular account.
    • Parameters: hookUrl - URL of the server which will receive the payload.

Get Webhook(s) State

  • [GET] /webhooks — Returns a list of all existing webhooks
  • [GET] /accounts/{accountId}/webhooks — Returns a list of webhooks in a specified account.
  • [GET] /webhooks/{webhookId},{webhookId},... [up to 100 IDs] — Returns information for the specified webhooks.
  • The response model for these methods includes the following data for each hook:
       webhook ID, account ID, Folder ID (optional), your server's URL and status (Active | Suspended).

Update Webhook State

  • [PUT] /webhooks/{webhookId} — Modifies the webhooks state to suspend or resume. Suspended webhooks do not send notifications.
    • Parameters: status = Active | Suspended

Delete Webhooks

  • [DELETE] /webhooks/{webhookId} — Deletes webhook by ID.

Sample Payloads

Below is an example of the most basic payload which can be received. This payload is sent when a new task is created (note the “eventType”):

  • [{
  •        "webhookId": "IEAADQQLKQAKAOPB",
  •        "eventAuthorId": "KQAKAOPB",
  •        "eventType": "TaskCreated",
  •        "taskId": "IEAADQQLKQAKAOPB",
  •        "lastUpdatedDate": "2016-10-10T11:33:28Z"
  • }]

Note, even single notifications are sent as JSON-array. For simplicity, we’ll write payloads as single JSON-objects in the text below.

Some payloads can contain values which designate what the data was before the change, i.e. for the TaskTitleChanged event you see the old and new task title:

  • {
  •    "oldValue": "Old task title",
  •    "title": "New task title",
  •    "taskId": "IEAADQQLKQAKOFAB",
  •    "webhookId": "IEAADQQLJAAAAULL",
  •    "eventAuthorId": "KUAALDRX",
  •    "eventType": "TaskTitleChanged",
  •    "lastUpdatedDate": "2016-11-22T10:25:50Z"
  • }

Another example with old/new values is TaskStatusChanged:

  • {
  •    "oldStatus": "Active",
  •    "status": "Completed",
  •    "taskId": "IEAADQQLKQAKOFAB",
  •    "webhookId": "IEAADQQLJAAAAULN",
  •    "eventAuthorId": "KUAALDRX",
  •    "eventType": "TaskStatusChanged",
  •    "lastUpdatedDate": "2016-11-22T11:09:58Z"
  • }

Task statuses mentioned in “oldStatus” and “status” fields are described for “status” param of “query-tasks” API method.

For events related to task child entities, i.e. attachments, payload will contain corresponding entity ID. Example is AttachmentAdded event:

  • {
  •    "webhookId": "IEAADQQLKQAKAOPB",
  •    "eventAuthorId": "KQAKAOPB",
  •    "lastUpdatedDate": "2016-10-10T11:33:28Z",
  •    "eventType": "AttachmentAdded",
  •    "taskId": "IEAADQQLKQAKAOPB",
  •    "attachmentId": "IEAADQQLKQAKAOPD"
  • }

To get detailed information about the attachment you'll need to use Get Attachments method - with the ID you'd received.

Event Types

Currently we support only events related to tasks, not to Folders/Projects (i.e. webhook won’t fire if comment is added to the Folder itself).

Show supported events
Event Description Includes Old Value
TaskCreated Fired when user creates a new task
TaskDeleted

Per-account hooks: Fired when a user deletes a task

Per-Folder hooks: Not fired

TaskTitleChanged Fired when task title changed +
TaskImportanceChanged Fired when task importance changed +
TaskStatusChanged Fired when task status changed +
TaskDatesChanged Fired when start, finish dates, duration, or the “Work on weekends” flag is changed +
TaskParentsAdded Fired when a task is added to a Folder
TaskParentsRemoved Fired when a task is removed from a Folder
TaskResponsiblesAdded Fired when a new assignee is added to a task, including all Wrike users (and Collaborators) and users with pending invitations.
TaskResponsiblesRemoved Fired when someone is unassigned from a task
TaskSharedsAdded Fired when a task is shared
TaskSharedsRemoved Fired when a task is unshared
TaskDescriptionChanged Fired when a task’s description is changed. Note: Notifications related to description field changes are fired with a 5 min delay (approximately)
AttachmentAdded Fired when a new attachment is added to a task
AttachmentDeleted Fired when attachment was deleted from task or comment with attachment was deleted
CommentAdded Fired when a new comment is added. Not fired for comments without text, i.e. comments with attachments only
CommentDeleted Fired when a comment is deleted
TimelogChanged Fired when a Timelog record is added, updated, or removed
The following events are not yet supported (and do not trigger notifications):

Example of Usage

Use Case Example

Let’s assume a task is related to the development process and a “Completed” status means that all code was committed/pushed to the source repository. You could have this change trigger a CI build via some CI REST endpoint.

Step 1

Create an account-wide webhook.

Get your accountId using the following CURL command:
Copy to clipboard

curl -g -X GET -H 'Authorization: bearer <access_token>' 'https://www.wrike.com/api/v3/accounts'

The response contains a list of your accounts:

  • {
  •    "kind": "accounts",
  •    "data": [
  •        {
  •            "id": "IEAADQQL",
  •            "name": "My Personal Account",
  •            "dateFormat": "MM/dd/yyyy",
  •            "firstDayOfWeek": "Mon",
  •            "workDays":
  •            [
  •                "Sun",
  •                "Mon",
  •                "Tue",
  •                "Wed",
  •                "Thu",
  •                "Fri",
  •                "Sat"
  •            ],
  •            "rootFolderId": "IEAAAOVII7777777",
  •            "recycleBinId": "IEAAAOVII7777776",
  •            "createdDate": "2013-12-30T12:17:24Z",
  •            "joinedDate": "2015-08-04T13:56:13Z"
  •        }
  •    ]
  • }

You will need “id” field for future requests (“IEAADQQL” in the example above).

Step 2

Execute the following CURL command to create a new account-wide webhook and subscribe your endpoint (https://yourwebhookserver.com/event-handler) to notifications.

Get your accountId using the following CURL command:
Copy to clipboard

curl -g -X POST -H 'Authorization: bearer <access_token>' -d 'hookUrl=https://yourwebhookserver.com/event-handler' 'https://www.wrike.com/api/v3/accounts/IEAADQQL/webhooks'

You’ll see the following response:

  • {
  •    "kind": "webhooks",
  •    "data": [
  •        {
  •            "id": "IEAADQQLJAAAAULN",
  •            "accountId": "IEAADQQL",
  •            "hookUrl": "https://yourwebhookserver.com/event-handler",
  •            "status": "Active"
  •        }
  •    ]
  • }

Step 3

Next, change a task in the account, i.e. change a task’s status from Active to Completed. You’ll receive the following payload on your endpoint:

  • {
  •    "oldStatus": "Active",
  •    "status": "Completed",
  •    "taskId": "IEAADQQLKQAKOFAB",
  •    "webhookId": "IEAADQQLJAAAAULN",
  •    "eventAuthorId": "KUAALDRX",
  •    "eventType": "TaskStatusChanged",
  •    "lastUpdatedDate": "2016-11-22T11:09:58Z"
  • }

Suspended Webhooks

If you shut down your endpoint or it is not accessible via the internet, then we automatically suspend the webhook after three retries. In this case, the following request by given webhook ID returns the Suspended state for webhook:
Copy to clipboard

curl -g -X POST -H 'Authorization: bearer <access_token>' 'https://www.wrike.com/api/v3/webhooks/IEAADQQLJAAAAULN'

Response reflecting suspended state:

  • {
  •    "kind": "webhooks",
  •    "data": [
  •        {
  •            "id": "IEAADQQLJAAAAULN",
  •            "accountId": "IEAADQQL",
  •            "hookUrl": "https://yourwebhookserver.com/event-handler",
  •            "status": "Suspended"
  •        }
  •    ]
  • }

Restart Webhooks

Restart the webhook using the following PUT request:
Copy to clipboard

curl -g -X POST -H 'Authorization: bearer <access_token>' 'https://www.wrike.com/api/v3/webhooks/IEAADQQLJAAAAULN'

Response:

  • {
  •    "kind": "webhooks",
  •    "data": [
  •        {
  •            "id": "IEAADQQLJAAAAULN",
  •            "accountId": "IEAADQQL",
  •            "hookUrl": "https://yourwebhookserver.com/event-handler",
  •            "status": "Active"
  •        }
  •    ]
  • }

You can get a list of your webhooks (and their states) at any time:
Copy to clipboard

curl -g -X POST -H 'Authorization: bearer <access_token>' 'https://www.wrike.com/api/v3/accounts/IEAADQQL/webhooks'

Response will contain JSON with all of webhooks created by you. Similar to:

  • {
  •    "kind": "webhooks",
  •    "data": [
  •        {
  •            "id": "IEAADQQLJAAAAULN",
  •            "accountId": "IEAADQQL",
  •            "hookUrl": "https://yourwebhookserver.com/event-handler",
  •            "status": "Active"
  •        }
  •    ]
  • }