# Setting and modifying Headers and Cookies

It is also possible to set headers and cookies on the response that your Twilio Function returns. The `Response` object exposes the following methods to allow you to customize what headers are sent in response to incoming requests.

* [Headers](#headers)
  * [setHeaders()](#setheaders)
  * [appendHeader()](#appendheader)
* [Cookies](#cookies)
  * [setCookie()](#setcookie)
  * [removeCookie()](#removecookie)

## Headers

### `setHeaders(headers)` \[#setheaders]

This method allows you to set multiple headers in a single command. It accepts an object of key-value pairs of headers and their corresponding values. You may also set multi-value headers by making the intended header an array.

If you include the `Set-Cookie` header in this object, cookies will also be set to that value in addition to any other changes. Cookies must be strings with the key and value delimited by an `=` sign, such as `'Key=Value'` or as a list of values such as `['Key=Value', 'Agent=Smith']`.

**Method Parameters**

| Name    | Type                                 |
| ------- | ------------------------------------ |
| headers | `Object<string, string \| string[]>` |

**Examples**

```js
exports.handler = (context, event, callback) => {
  const response = new Twilio.Response();
  response.setHeaders({
    // Set a single header
    'content-type': 'application/json',
    // You can set a header with multiple values by providing an array
    'cache-control': ['no-cache', 'private'],
    // You may also optionally set cookies via the "Set-Cookie" key
    'set-cookie': 'Foo=Bar',
  });

  return callback(null, response);
};
```

```js
exports.handler = (context, event, callback) => {
  const response = new Twilio.Response();
  response.setHeaders({
    // You may also set cookie attributes by including a semicolon
    // (`;`) delimited list of attributes
    'set-cookie': ['Foo=Bar;Max-Age=86400', 'Agent=Smith;HttpOnly;Secure'],
  });

  return callback(null, response);
};
```

### `appendHeader(key, value)` \[#appendheader]

This method allows you to add a single header to the response. It accepts the name of the header and its intended value.

> \[!NOTE]
>
> If `Response.appendHeader` is called with the name of a header that already exists, that header will be converted from a string to an array, and the provided value will be concatenated to that array of values.

**Method Parameters**

| Name  | Type                 | Example              |
| ----- | -------------------- | -------------------- |
| key   | `string`             | `'content-type'`     |
| value | `string \| string[]` | `'application/json'` |

**Examples**

```js
exports.handler = (context, event, callback) => {
  const response = new Twilio.Response();
  response
    .appendHeader('content-type', 'application/json')
    // You can append a multi-value header by passing a list of strings
    .appendHeader('yes', ['no', 'maybe', 'so'])
    // Instead of setting the header to an array, it's also valid to
    // pass a comma-separated string of values
    .appendHeader('cache-control', 'no-store, max-age=0');

  return callback(null, response);
};
```

```js
exports.handler = (context, event, callback) => {
  const response = new Twilio.Response();
  response
    .appendHeader('never', 'gonna')
    // Appending a header that already exists will convert that header to
    // a multi-value header and concatenate the new value
    .appendHeader('never', 'give')
    .appendHeader('never', 'you')
    .appendHeader('never', 'up');
    // The header is now `'never': ['gonna', 'give', 'you', 'up']`

  return callback(null, response);
};
```

## Cookies

> \[!NOTE]
>
> Commands to set, modify, and delete cookies are only available when your Function is running `@twilio/runtime-handler` version `1.2.0` or later. Consult the [Runtime Handler guide](/docs/serverless/functions-assets/handler) to learn more about the latest version and how to update.

### `setCookie(key, value, attributes?)` \[#setcookie]

This method allows you to add a cookie to your Function's response. It accepts the name of the cookie, its value, and any optional attributes to be assigned to the cookie.

**Method Parameters**

| Name                  | Type                 | Example                                                      |
| --------------------- | -------------------- | ------------------------------------------------------------ |
| key                   | `string`             | `'tz'`                                                       |
| value                 | `string \| string[]` | `'America/Los_Angeles'`                                      |
| attributes (optional) | `string[]?`          | `['HttpOnly', 'Secure', 'SameSite=Strict', 'Max-Age=86400']` |

**Examples**

```js
exports.handler = (context, event, callback) => {
  const response = new Twilio.Response();
  response
    .setCookie('has_recent_activity', 'true')
    .setCookie('tz', 'America/Los_Angeles', [
      'HttpOnly',
      'Secure',
      'SameSite=Strict',
      'Max-Age=86400',
    ]);

  return callback(null, response);
};
```

> \[!NOTE]
>
> Cookie attributes such as `HttpOnly` and `Secure` are shown in these examples, however, you don't need to add them yourself. Runtime automatically adds the `HttpOnly` and `Secure` attributes to your cookies by default unless you have already manually set those values.
>
> If you do not set a `Max-Age` or `Expires` on a cookie, it will be considered a [Session cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_the_lifetime_of_a_cookie). If you set both `Max-Age` and `Expires` on a cookie, `Max-Age` takes precedence.

> \[!CAUTION]
>
> If you set the `Max-Age` or `Expires` of a cookie to greater than 24 hours, your Function will return a `400` error: `Cookies max-age cannot be greater than a day`.

### `removeCookie(key)` \[#removecookie]

This method allows you to effectively remove a specific cookie from the response of your Twilio Function. It accepts the name of the cookie to be removed, and sets the `Max-Age` attribute of the cookie equal to 0 so that clients and browsers will remove the cookie upon receiving the response.

#### Method Parameters

| Name | Type     | Example |
| ---- | -------- | ------- |
| key  | `string` | `'tz'`  |

#### Examples

In the following example, the client may contain a cookie `tz` and send it along with the request. Upon receiving this response from your Function, `tz` will be removed from the client's cookie store and not sent with subsequent requests to your Function's domain.

```js
exports.handler = (context, event, callback) => {
  const response = new Twilio.Response();
  response.removeCookie('tz');

  return callback(null, response);
};
```

## What's next?

Now that you more about how to set and modify the headers in your Function responses, let's go over some of the [limitations on headers and cookies](/docs/serverless/functions-assets/functions/headers-and-cookies/limitations) so that you don't encounter as many errors.
