# {{projectName}} [![GitHub release][release-image]][release-url] [![NPM Version][npm-image]][npm-url]

This is a [preview version](https://forum.asana.com/t/try-an-early-preview-of-our-new-node-js-and-python-sdks/394881) of Asana's new node client library. For feedback and feature requests, please leave a comment on [this forum thread](https://forum.asana.com/t/try-an-early-preview-of-our-new-node-js-and-python-sdks/394881) or through [the feedback form on our documentation site](https://form-beta.asana.com/?k=C4sELCq6hAUsoWEY0kJwAA&d=15793206719)

- API version: {{appVersion}}
- Package version: {{projectVersion}}
{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}

## Installation

### For [Node.js](https://nodejs.org/)

#### npm install from [npmjs](https://www.npmjs.com/package/asana-preview)

```shell
npm install {{{projectName}}} --save
```

### For browser

Include the latest release directly from GitHub:

```html
<script src="https://github.com/Asana/node-asana-preview/releases/download/v{{projectVersion}}/asana-min.js"></script>
```

Example usage (**NOTE**: be careful not to expose your access token):

```html
<script>
    {{#hasAuthMethods}}
    let client = {{{moduleName}}}.ApiClient.instance;{{#authMethods}}{{#isBasic}}
    // Configure HTTP basic authorization: {{{name}}}
    let {{{name}}} = client.authentications['{{{name}}}'];
    {{{name}}}.username = 'YOUR USERNAME';
    {{{name}}}.password = 'YOUR PASSWORD';{{/isBasic}}{{#isApiKey}}
    // Configure API key authorization: {{{name}}}
    let {{{name}}} = client.authentications['{{{name}}}'];
    {{{name}}}.apiKey = 'YOUR API KEY';
    // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
    //{{{name}}}.apiKeyPrefix = 'Token';{{/isApiKey}}{{#isOAuth}}
    // Configure OAuth2 access token for authorization: {{{name}}}
    let {{{name}}} = client.authentications['{{{name}}}'];
    {{{name}}}.accessToken = '<YOUR_ACCESS_TOKEN>';{{/isOAuth}}{{#isBearer}}
    let token = client.authentications['token'];
    token.accessToken = '<YOUR_ACCESS_TOKEN>';{{/isBearer}}
    {{/authMethods}}
    {{/hasAuthMethods}}

    let usersApiInstance = new {{{moduleName}}}.UsersApi();
    let user_gid = "me";
    let opts = {};

    usersApiInstance.getUser(user_gid, opts).then((result) => {
        console.log('API called successfully. Returned data: ' +  JSON.stringify(result.data, null, 2));
    }, (error) => {
        console.error(error.response.body);
    });
</script>
```

### Webpack Configuration

Using Webpack you may encounter the following error: "Module not found: Error:
Cannot resolve module", most certainly you should disable AMD loader. Add/merge
the following section to your webpack config:

```javascript
module: {
  rules: [
    {
      parser: {
        amd: false
      }
    }
  ]
}
```

## Getting Started

Please follow the [installation](#installation) instruction and execute the following JS code:

```javascript
{{>code_sample_client}}

let usersApiInstance = new {{{moduleName}}}.UsersApi();
let user_gid = "me"; // String | A string identifying a user. This can either be the string \"me\", an email, or the gid of a user.
let opts = { 
    "opt_fields": "email,name,photo,photo.image_1024x1024,photo.image_128x128,photo.image_21x21,photo.image_27x27,photo.image_36x36,photo.image_60x60,workspaces,workspaces.name" // [String] | This endpoint returns a compact resource, which excludes some properties by default. To include those optional properties, set this query parameter to a comma-separated list of the properties you wish to include.
};

usersApiInstance.getUser(user_gid, opts).then((result) => {
    console.log('API called successfully. Returned data: ' +  JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});
```

### Example: GET, POST, PUT, DELETE on tasks

#### GET - get multiple tasks
```javascript
{{>code_sample_client}}

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let opts = { 
    "limit": 50, // Number | Results per page. The number of objects to return per page. The value must be between 1 and 100.
    "project": "<YOUR_PROJECT_GID>", // String | The project to filter tasks on.
    "modified_since": "2012-02-22T02:06:58.158Z", // Date | Only return tasks that have been modified since the given time.  *Note: A task is considered “modified” if any of its properties change, or associations between it and other objects are modified (e.g.  a task being added to a project). A task is not considered modified just because another object it is associated with (e.g. a subtask) is modified. Actions that count as modifying the task include assigning, renaming, completing, and adding stories.*
    "opt_fields": "actual_time_minutes,approval_status,assignee,assignee.name,assignee_section,assignee_section.name,assignee_status,completed,completed_at,completed_by,completed_by.name,created_at,created_by,custom_fields,custom_fields.asana_created_field,custom_fields.created_by,custom_fields.created_by.name,custom_fields.currency_code,custom_fields.custom_label,custom_fields.custom_label_position,custom_fields.date_value,custom_fields.date_value.date,custom_fields.date_value.date_time,custom_fields.description,custom_fields.display_value,custom_fields.enabled,custom_fields.enum_options,custom_fields.enum_options.color,custom_fields.enum_options.enabled,custom_fields.enum_options.name,custom_fields.enum_value,custom_fields.enum_value.color,custom_fields.enum_value.enabled,custom_fields.enum_value.name,custom_fields.format,custom_fields.has_notifications_enabled,custom_fields.is_formula_field,custom_fields.is_global_to_workspace,custom_fields.is_value_read_only,custom_fields.multi_enum_values,custom_fields.multi_enum_values.color,custom_fields.multi_enum_values.enabled,custom_fields.multi_enum_values.name,custom_fields.name,custom_fields.number_value,custom_fields.people_value,custom_fields.people_value.name,custom_fields.precision,custom_fields.resource_subtype,custom_fields.text_value,custom_fields.type,dependencies,dependents,due_at,due_on,external,external.data,followers,followers.name,hearted,hearts,hearts.user,hearts.user.name,html_notes,is_rendered_as_separator,liked,likes,likes.user,likes.user.name,memberships,memberships.project,memberships.project.name,memberships.section,memberships.section.name,modified_at,name,notes,num_hearts,num_likes,num_subtasks,offset,parent,parent.created_by,parent.name,parent.resource_subtype,path,permalink_url,projects,projects.name,resource_subtype,start_at,start_on,tags,tags.name,uri,workspace,workspace.name" // [String] | This endpoint returns a compact resource, which excludes some properties by default. To include those optional properties, set this query parameter to a comma-separated list of the properties you wish to include.
};

// GET - get multiple tasks
tasksApiInstance.getTasks(opts).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});
```

#### POST - create a task
```javascript
{{>code_sample_client}}

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let body = {
    "data": {
        "name": "New Task",
        "approval_status": "pending",
        "assignee_status": "upcoming",
        "completed": false,
        "external": {
            "gid": "1234",
            "data": "A blob of information.",
        },
        "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
        "is_rendered_as_separator": false,
        "liked": true,
        "assignee": "me",
        "projects": ["<YOUR_PROJECT_GID>"],
    },
};
let opts = {};

// POST - Create a task
tasksApiInstance.createTask(body, opts).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});
```

#### PUT - update a task
```javascript
{{>code_sample_client}}

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let task_gid = "<YOUR_TASK_GID>";
let body = {
    "data": {
        "name": "Updated Task",
    },
};
let opts = {};

// PUT - Update a task
tasksApiInstance.updateTask(body, task_gid, opts).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});
```

#### DELETE - delete a task
```javascript
{{>code_sample_client}}

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let task_gid = "<YOUR_TASK_GID>";

// DELETE - Delete a task
tasksApiInstance.deleteTask(task_gid).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});
```

## Documentation for API Endpoints

All URIs are relative to *{{basePath}}*

Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{moduleName}}.{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}

## Optional fields

Our `opt_fields` feature allows you to request for properties of a resource that you want to be returned in the response (more information [here](https://developers.asana.com/docs/inputoutput-options)).

**NOTE**: by default, endpoints that return an array of results (EX: [Get multiple tasks](https://developers.asana.com/reference/gettasks), [Get multiple projects](https://developers.asana.com/reference/getprojects)), will return a compact version of those results (EX: [Get multiple tasks](https://developers.asana.com/reference/gettasks) returns an array of [TaskCompact](https://developers.asana.com/reference/tasks#taskcompact) objects).

### EX: [Get multiple tasks](https://developers.asana.com/reference/gettasks) / [**getTasks**](docs/TasksApi.md#getTasks) without `opt_fields`

#### Example Request
```javascript
{{>code_sample_client}}

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let opts = {
    "limit": 2,
    "project": "<YOUR_PROJECT_GID>"
};

// GET - get multiple tasks
tasksApiInstance.getTasks(opts).then((result) => {
    console.log(JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});
```

#### Example Response
```javascript
[
  {
    "gid": "123",
    "name": "Task 1",
    "resource_type": "task",
    "resource_subtype": "default_task"
  },
  {
    "gid": "456",
    "name": "Task 2",
    "resource_type": "task",
    "resource_subtype": "default_task"
  }
]
```

### EX: [Get multiple tasks](https://developers.asana.com/reference/gettasks) / [**getTasks**](docs/TasksApi.md#getTasks) with `opt_fields`

#### Example Request
```javascript
{{>code_sample_client}}

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let opts = { 
    "limit": 1,
    "project": "<YOUR_PROJECT_GID>",
    "opt_fields": "actual_time_minutes,approval_status,assignee,assignee.name,assignee_section,assignee_section.name,assignee_status,completed,completed_at,completed_by,completed_by.name,created_at,created_by,custom_fields,custom_fields.asana_created_field,custom_fields.created_by,custom_fields.created_by.name,custom_fields.currency_code,custom_fields.custom_label,custom_fields.custom_label_position,custom_fields.date_value,custom_fields.date_value.date,custom_fields.date_value.date_time,custom_fields.description,custom_fields.display_value,custom_fields.enabled,custom_fields.enum_options,custom_fields.enum_options.color,custom_fields.enum_options.enabled,custom_fields.enum_options.name,custom_fields.enum_value,custom_fields.enum_value.color,custom_fields.enum_value.enabled,custom_fields.enum_value.name,custom_fields.format,custom_fields.has_notifications_enabled,custom_fields.is_formula_field,custom_fields.is_global_to_workspace,custom_fields.is_value_read_only,custom_fields.multi_enum_values,custom_fields.multi_enum_values.color,custom_fields.multi_enum_values.enabled,custom_fields.multi_enum_values.name,custom_fields.name,custom_fields.number_value,custom_fields.people_value,custom_fields.people_value.name,custom_fields.precision,custom_fields.resource_subtype,custom_fields.text_value,custom_fields.type,dependencies,dependents,due_at,due_on,external,external.data,followers,followers.name,hearted,hearts,hearts.user,hearts.user.name,html_notes,is_rendered_as_separator,liked,likes,likes.user,likes.user.name,memberships,memberships.project,memberships.project.name,memberships.section,memberships.section.name,modified_at,name,notes,num_hearts,num_likes,num_subtasks,offset,parent,parent.created_by,parent.name,parent.resource_subtype,path,permalink_url,projects,projects.name,resource_subtype,start_at,start_on,tags,tags.name,uri,workspace,workspace.name"
};

// GET - get multiple tasks
tasksApiInstance.getTasks(opts).then((result) => {
    console.log(JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});
```

#### Example Response
```javascript
[
  {
    "gid": "129839839",
    "actual_time_minutes": null,
    "assignee": {
      "gid": "120938293",
      "name": "user@example.com"
    },
    "assignee_status": "upcoming",
    "assignee_section": {
      "gid": "1094838938",
      "name": "Recently assigned"
    },
    "completed": false,
    "completed_at": null,
    "completed_by": null,
    "created_at": "2023-01-01T20:31:21.717Z",
    "created_by": {
      "gid": "1201784467042440",
      "resource_type": "user"
    },
    "custom_fields": [
      {
        "gid": "191859815",
        "enabled": true,
        "name": "Estimated time",
        "description": "Asana-created. Estimate time to complete a task.",
        "number_value": null,
        "precision": 0,
        "format": "duration",
        "currency_code": null,
        "custom_label": null,
        "created_by": null,
        "custom_label_position": null,
        "display_value": null,
        "resource_subtype": "number",
        "is_formula_field": false,
        "is_value_read_only": false,
        "type": "number"
      }
    ],
    "dependencies": [],
    "dependents": [],
    "due_at": "2025-01-20T02:06:58.000Z",
    "due_on": "2025-01-19",
    "followers": [
      {
        "gid": "120938293",
        "name": "user@example.com"
      }
    ],
    "hearted": true,
    "hearts": [
      {
        "gid": "594849843",
        "user": {
          "gid": "120938293",
          "name": "user@example.com"
        }
      }
    ],
    "html_notes": "<body>Example task notes</body>",
    "is_rendered_as_separator": false,
    "liked": true,
    "likes": [
      {
        "gid": "58303939",
        "user": {
          "gid": "120938293",
          "name": "user@example.com"
        }
      }
    ],
    "memberships": [
      {
        "project": {
          "gid": "4567",
          "name": "Example Project"
        },
        "section": {
          "gid": "8900",
          "name": "Untitled section"
        }
      }
    ],
    "modified_at": "2023-01-25T21:24:06.996Z",
    "name": "Task 1",
    "notes": "Example task notes",
    "num_hearts": 1,
    "num_likes": 1,
    "num_subtasks": 0,
    "parent": null,
    "permalink_url": "https://app.asana.com/0/58303939/129839839",
    "projects": [
      {
        "gid": "4567",
        "name": "Example Project"
      }
    ],
    "start_at": null,
    "start_on": null,
    "tags": [],
    "resource_subtype": "default_task",
    "workspace": {
      "gid": "111111",
      "name": "Example Workspace"
    }
  }
]
```

## Pagination

By default, endpoints that return an array of results (EX: [Get multiple tasks](https://developers.asana.com/reference/gettasks), [Get multiple projects](https://developers.asana.com/reference/getprojects)), will return a [Collection](src/utils/collection.js) object.
This collection object contains a `nextPage` method that can be used to fetch for the next page of results. **NOTE**: in order to use `nextPage` you must have provided a `limit` query parameter argument in the initial request.

### Use case

You may run into the following error when making a request to an endpoint that has >1000 results:

> "The result is too large. You should use pagination (may require specifying a workspace)!"

In this scenario you will want to use pagaintion to gather your results. To do this, you will need to provide a `limit` query parameter argument in your request. This `limit` query param represents the number of results per page. NOTE: the `limit` can only be between 1 and 100.

EX: Pagination gather all resources
```javascript
{{>code_sample_client}}

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let opts = {
    "project": "<YOUR_PROJECT_GID>"
    "limit": 100
};

async function getAllTasks(opts) {
    let tasks = await tasksApiInstance.getTasks(opts).then(async (firstPage) => {
        let res = []
        res = res.concat(firstPage.data);
        // Get the next page
        let nextPage = await firstPage.nextPage();
        // Keep fetching for the next page until there are no more results
        while(nextPage.data) {
            res = res.concat(nextPage.data);
            nextPage = await nextPage.nextPage();
        }
        return res;
    }, (error) => {
        console.error(error.response.body);
    });
    // Do something with the tasks. EX: print out results
    console.log('Tasks: ' + JSON.stringify(tasks, null, 2));
}

getAllTasks(opts);
```

EX: Pagination do something per page
```javascript
{{>code_sample_client}}

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let opts = {
    'project': "<YOUR_PROJECT_GID>",
    'limit': 10
};

pageIndex = 1;

tasksApiInstance.getTasks(opts).then(async (firstPage) => {
    // Do something with the first <LIMIT> results. EX: print out results
    console.log(`Page ${pageIndex}: ` + JSON.stringify(firstPage.data, null, 2));

    // Get the next page
    let nextPage = await firstPage.nextPage();
    // Keep fetching for the next page until there are no more results
    while(nextPage.data) {
        // Do something with the next <LIMIT> results. EX: print out results
        pageIndex += 1;
        console.log(`Page ${pageIndex}: ` + JSON.stringify(nextPage.data, null, 2));
        // Get the next page
        nextPage = await nextPage.nextPage();
    }
}, (error) => {
    console.error(error.response.body);
});
```

### Turning off Pagination

If you do not want a [Collection](src/utils/collection.js) object returned and want to implement your own pagination, you can disable pagination by setting `RETURN_COLLECTION` to `false`:

EX: Turning off pagination
```javascript
{{>code_sample_client}}

// Turn off pagination
client.RETURN_COLLECTION = false;

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let opts = {
    'project': "<YOUR_PROJECT_GID>",
    'limit': 1
};
tasksApiInstance.getTasks(opts).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result, null, 2));
})
```

Sample response:
```
API called successfully. Returned data: {
  "data": [
    {
      "gid": "<TASK_GID>",
      "name": "Task 1",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
  ],
  "next_page": {
    "offset": "gjJl2xAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmHilbI6IltcIlZ5IixcIjlaWlhVMkkzUUdOoXcEIsMTIwNDYxNTc0NTypNDI3MF0iLCJpYXQiOjE2OTc4MjgsSkjjQsImV4cCI6MTY5NzgyOTM2NH0.5VuMfKvqexoEsKfoPFtayWBNWiKvfR7_hN6MJaaIkx8",
    "path": "/tasks?project=123456&limit=1&offset=gjJl2xAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmHilbI6IltcIlZ5IixcIjlaWlhVMkkzUUdOoXcEIsMTIwNDYxNTc0NTypNDI3MF0iLCJpYXQiOjE2OTc4MjgsSkjjQsImV4cCI6MTY5NzgyOTM2NH0.5VuMfKvqexoEsKfoPFtayWBNWiKvfR7_hN6MJaaIkx8",
    "uri": "https://app.asana.com/api/1.0/tasks?project=123456&limit=1&offset=gjJl2xAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmHilbI6IltcIlZ5IixcIjlaWlhVMkkzUUdOoXcEIsMTIwNDYxNTc0NTypNDI3MF0iLCJpYXQiOjE2OTc4MjgsSkjjQsImV4cCI6MTY5NzgyOTM2NH0.5VuMfKvqexoEsKfoPFtayWBNWiKvfR7_hN6MJaaIkx8"
  }
}
```

## Getting events

In order to get events you will need a sync token. This sync token can be acquired in the error message from the initial
request to [getEvents](docs/EventsApi.md#getEvents).

```javascript
{{>code_sample_client}}

let eventsApiInstance = new {{{moduleName}}}.EventsApi();
let resource = "<YOUR_TASK_OR_PROJECT_GID>"; // String | A resource ID to subscribe to. The resource can be a task or project.
let opts = {
    "sync": ""
};
const timeouts = 5000

// Used to fetch for initial sync token
const setSyncToken = async () => {
    await eventsApiInstance.getEvents(resource, opts).then((result) => {
        console.log(JSON.stringify(result.data, null, 2));
    }, (error) => {
        let syncToken = error.response.body.sync;
        opts['sync'] = syncToken;
    });
}

const getEvents = async () => {
    console.log("Setting sync token");
    await setSyncToken();
    // Fetch for new events every 5 seconds
    console.log(`Fetching events every ${timeouts/1000} second(s)`);
    while(true) {
        await eventsApiInstance.getEvents(resource, opts).then((result) => {
            // Print response
            console.log(`Fetching events since sync: ${opts['sync']}`);
            console.log(JSON.stringify(result.data, null, 2));

            // Update the sync token with the new sync token provided in the response
            opts['sync'] = result._response.sync;
        }, (error) => {
            if (error.status === 412) {
                let syncToken = error.response.body.sync;
                opts['sync'] = syncToken;
                console.log(`412 error new sync token: ${syncToken}`);
            } else{
                console.error(error.response.text);
            }
        });
        await new Promise(resolve => setTimeout(resolve, timeouts));
    }
}

getEvents();
```

## Accessing repsonse data

```javascript
.
.
.
tasksApiInstance.getTask(task_gid, opts).then((task) => {
    let taskName = task.data.name;
    let taskNotes = task.data.notes;
    console.log(`taskName: ${taskName}`);
    console.log(`taskNotes: ${taskNotes}`);
}, (error) => {
    console.error(error.response.body);
});
```

## Accessing response status code and headers
Use the `<METHOD_NAME>WithHttpInfo` (EX: `getTaskWithHttpInfo`) method to make a request that returns a response with headers.

```javascript
{{>code_sample_client}}

let tasksApiInstance = new {{{moduleName}}}.TasksApi();
let task_gid = "<YOUR_TASK_GID>";
let opts = {};

tasksApiInstance.getTaskWithHttpInfo(task_gid, opts).then((response_and_data) => {
    let data = response_and_data.data;
    let response = response_and_data.response;
    let task = data.data;
    let headers = response.headers;
    console.log(task);
    console.log(headers);
}, (error) => {
    console.error(error.response.body);
});
```

## Adding deprecation flag: "asana-enable" or "asana-disable" header

EX: Asana-Enable header
```javascript
{{>code_sample_client}}

// Add asana-enable header for the client
client.defaultHeaders['asana-enable'] = 'new_goal_memberships';
```

EX: Asana-Disable header
```javascript
{{>code_sample_client}}

// Add asana-disable header for the client
client.defaultHeaders['asana-disable'] = 'new_goal_memberships';
```

## Using the `callApi` method

Use the `callApi` method to make http calls when the endpoint does not exist in the current library version or has bugs

### Example: GET, POST, PUT, DELETE on tasks

#### GET - get a task
```javascript
{{>code_sample_client}}

// GET - get a task
client.callApi(
    path='/tasks/{task_gid}',
    httpMethod='GET',
    pathParams={"task_gid": "<YOUR_TASK_GID>"},
    queryParams={},
    headerParams={},
    formParams={},
    bodyParam=null,
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let task = result.data;
    console.log(task.name);
}, (error) => {
    console.error(error.response.body);
});
```

#### GET - get multiple tasks -> with opt_fields
```javascript
{{>code_sample_client}}

// GET - get multiple tasks -> with opt_fields
client.callApi(
    path='/tasks',
    httpMethod='GET',
    pathParams={},
    queryParams={
        "limit": 50,
        "modified_since": '2012-02-22T02:06:58.158Z', // OR new Date("2012-02-22T02:06:58.158Z")
        "project": '<YOUR_PROJECT_GID>',
        "opt_fields": 'name,notes'
    },
    headerParams={},
    formParams={},
    bodyParam=null,
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let tasks = result.data;
    if (tasks.length > 0) {
        console.log(`Task 1 Name: ${tasks[0].name}`);
        console.log(`Task 1 Notes: ${tasks[0].notes}`);
    }
}, (error) => {
    console.error(error.response.body);
});
```

#### POST - create a task
```javascript
{{>code_sample_client}}

// POST - create a task
client.callApi(
    path='/tasks',
    httpMethod='POST',
    pathParams={},
    queryParams={},
    headerParams={},
    formParams={},
    bodyParam={
        data: {
            "name": "New Task",
            "approval_status": "pending",
            "assignee_status": "upcoming",
            "completed": false,
            "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
            "is_rendered_as_separator": false,
            "liked": true,
            "assignee": "me",
            "projects": ["<YOUR_PROJECT_GID>"],
        }
    },
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let task = result.data;
    console.log(task.name);
}, (error) => {
    console.error(error.response.body);
});
```

#### PUT - update a task
```javascript
{{>code_sample_client}}

// PUT - update a task
client.callApi(
    path='/tasks/{task_gid}',
    httpMethod='PUT',
    pathParams={task_gid: "<YOUR_TASK_GID>"},
    queryParams={},
    headerParams={},
    formParams={},
    bodyParam={
        "data": {
            "name": "Updated Task",
            "html_notes": "<body>Updated task notes</body>",
            "due_at": "2025-01-20T02:06:58.147Z"
        }
    },
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let task = result.data;
    console.log(task.name);
}, (error) => {
    console.error(error.response.body);
});
```

#### DELETE - delete a task
```javascript
{{>code_sample_client}}

// DELETE - delete a task
client.callApi(
    path='/tasks/{task_gid}',
    httpMethod='DELETE',
    pathParams={"task_gid": "<YOUR_TASK_GID>"},
    queryParams={},
    headerParams={},
    formParams={},
    bodyParam=null,
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let result = result.data;
    console.log(result);
}, (error) => {
    console.error(error.response.body);
});
```

[release-image]: https://img.shields.io/github/release/asana/node-asana-preview.svg
[release-url]: https://github.com/Asana/node-asana-preview/releases/tag/v{{projectVersion}}
[npm-image]: http://img.shields.io/npm/v/asana-preview.svg?style=flat-square
[npm-url]: https://www.npmjs.org/package/asana-preview
