# Accessing headers and cookies

> \[!NOTE]
>
> Access to incoming headers and cookies is 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.

## Accessing headers

Within a Function, headers are stored on the `event.request.headers` object and can be accessed by name in lowercase.

> \[!WARNING]
>
> The names of all headers are lowercased before being passed into your Function. Please reference headers with the correct casing to avoid errors.
>
> For example, the key of the `Content-Type` header will be `content-type`.

For example, if the following request is received by your Function:

```bash
GET /example HTTP/1.1
Host: test-4321.twil.io
Authorization: 123abc
Content-Type: application/json
Content-Length: 23

{
  "body": "Ahoy!"
}
```

You can access various headers in the following ways:

```js
exports.handler = (context, event, callback) => {
  // Access the `Authorization` header via dot notation
  const authHeader = event.request.headers.authorization; 
  console.log(authHeader); // '123abc'

  // Access the `Authorization` header via bracket notation
  const alsoTheAuthHeader = event.request.headers['authorization']; 
  console.log(alsoTheAuthHeader); // '123abc'

  // Access headers that include hyphens and other non-alphanumeric
  // characters with bracket notation
  const contentType = event.request.headers['content-type']; 
  console.log(contentType); // 'application/json'

  return callback();
}
```

### Accessing headers with multiple values

It is possible for a request to contain multiple values for a single header.

For example, consider the following incoming request:

```bash
GET /example HTTP/1.1
Host: test-4321.twil.io
Content-Type: application/json
Cache-Control: no-cache
Cache-Control: private
Content-Length: 23

{
  "body": "Ahoy!"
}
```

Here, both `no-cache` and `private` have been assigned to the `cache-control` header. Since `cache-control` now has multiple values instead of a single value, it will return an array of strings when accessed:

```js
exports.handler = (context, event, callback) => {
  // Access a multivalued header. In this case, `Cache-Control`
  const cacheControl = event.request.headers['cache-control'];
  console.log(cacheControl); // ['no-cache', 'private'];

  return callback();
}
```

> \[!NOTE]
>
> The order of multivalued headers in a request is preserved.
>
> If you know for certain that the value of interest lies at a particular index of a header, you may access it directly. e.g. `event.request.headers['cache-control'][1]`

## Accessing cookies

Cookies are stored on a separate `event.request.cookies` object, and can be accessed similarly.

> \[!WARNING]
>
> Cookie names are *not* forced to be lowercase like other headers and should be accessed using the casing in the request.

Given an incoming request like this to your Function:

```bash
GET /example HTTP/1.1
Host: test-4321.twil.io
Content-Type: application/json
Cookie: Cookie_1=yummy; sessionToken=abc123
Content-Length: 23

{
  "body": "Ahoy!"
}
```

The following code provides examples of how to access the provided cookie values:

```js
exports.handler = (context, event, callback) => {
  // Access the `sessionToken` cookie via dot notation
  const sessionToken = event.request.cookies.sessionToken
  console.log(sessionToken); // 'abc123'

  // Access the `sessionToken` cookie via bracket notation
  const alsoTheSessionToken = event.request.cookies['sessionToken'];
  console.log(alsoTheSessionToken); // 'abc123' 

  // The cookie header can contain multiple cookies
  const { cookies } = event.request;
  console.log(cookies); // { Cookie_1: 'yummy', sessionToken: 'abc123' }

  return callback();
}
```

### Accessing cookies with multiple values

Just like headers, is possible for a request to contain multiple cookies with the same name.

> \[!WARNING]
>
> In the case of multiple cookies with the same name, the Runtime Handler will only make the first value accessible. It will not convert that cookie into an array that contains all values.

For example, consider the following incoming request:

```bash
GET /example HTTP/1.1
Host: test-4321.twil.io
Content-Type: application/json
Cookie: foo=bar; foo=baz
Content-Length: 23

{
  "body": "Ahoy!"
}
```

If you were to access the cookie `foo`, you will notice that only the **first** value of `'bar'` is returned instead of both:

```js
exports.handler = (context, event, callback) => {
  // Access the cookie `foo`
  const foo = event.request.cookies.foo
  console.log(foo); // 'bar'

  return callback();
}
```

What determines the order of cookies when they share the same name? According to [RFC-6265](https://datatracker.ietf.org/doc/html/rfc6265#section-5.4):

* Cookies with longer paths are listed before cookies with shorter paths.
* Among cookies that have equal-length path fields, cookies with earlier creation times are listed before cookies with later creation times.

## What's next?

Now that you know how to access incoming headers and cookies, let's take a look at how you can [set and modify headers on your Function responses](/docs/serverless/functions-assets/functions/headers-and-cookies/setting-and-modifying).
