<commit_before>---
title: intercept
---

Spy and stub network requests and responses.

<Alert type="warning">

We highly recommend you read the [Network Requests](/guides/guides/network-requests) guide first.

</Alert>

<Alert type="warning">

`cy.intercept()` is the successor to `cy.route()` as of Cypress 6.0.0. See [Comparison to `cy.route`](#Comparison-to-cy-route).

</Alert>

<Alert type="warning">

All intercepts are automatically cleared before every test.

</Alert>

## Syntax

```js
// spying only
cy.intercept(url)
cy.intercept(method, url)
cy.intercept(routeMatcher)

// spying and response stubbing
cy.intercept(url, staticResponse)
cy.intercept(method, url, staticResponse)
cy.intercept(routeMatcher, staticResponse)
cy.intercept(url, routeMatcher, staticResponse)

// spying, dynamic stubbing, request modification, etc.
cy.intercept(url, routeHandler)
cy.intercept(method, url, routeHandler)
cy.intercept(routeMatcher, routeHandler)
cy.intercept(url, routeMatcher, routeHandler)
```

### Usage

**<Icon name="check-circle" color="green"></Icon> Correct Usage**

```js
// spying
cy.intercept('/users/**')
cy.intercept('GET', '/users*')
cy.intercept({
  method: 'GET',
  url: '/users*',
  hostname: 'localhost',
})

// spying and response stubbing
cy.intercept('POST', '/users*', {
  statusCode: 201,
  body: {
    name: '<NAME>',
  },
})

// spying, dynamic stubbing, request modification, etc.
cy.intercept('/users*', { hostname: 'localhost' }, (req) => {
  /* do something with request and/or response */
})
```

### Arguments

#### **<Icon name="angle-right"></Icon> method** **_(String)_**

Specify the [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`, etc.) to match on. This is an optional argument, but if no `method` is provided, Cypress will match _any_ HTTP method (`*`) by default.

#### **<Icon name="angle-right"></Icon> url** **_(String, Glob, RegExp)_**

Specify the URL to match. See [Matching `url`](#match-url) for examples.

Alternatively, specify the URL via the [`routeMatcher`][arg-routematcher] argument (below).

#### **<Icon name="angle-right"></Icon> routeMatcher** **_(`RouteMatcher`)_**

`routeMatcher` is an object used to match the incoming HTTP requests with this intercepted route.

All properties are optional but all those that are set must match for the request to be intercepted. If a `string` is passed to any property, it will be glob-matched against the request using [`Cypress.minimatch`](/api/utilities/minimatch).

| Option     | Description                                                                                     |
| ---------- | ----------------------------------------------------------------------------------------------- |
| auth       | HTTP Basic Authentication (`object` with keys `username` and `password`)                        |
| headers    | HTTP request headers (`object`)                                                                 |
| hostname   | HTTP request hostname                                                                           |
| https      | `true`: only secure (https://) requests, `false`: only insecure (http://) requests              |
| method     | HTTP request method (matches any method by default)                                             |
| middleware | `true`: match route first and in defined order, `false`: match route in reverse order (default) |
| path       | HTTP request path after the hostname, including query parameters                                |
| pathname   | Like `path`, but without query parameters                                                       |
| port       | HTTP request port(s) (`number` or `Array`)                                                      |
| query      | Parsed query string (`object`)                                                                  |
| times      | Maximum number of times to match (`number`)                                                     |
| url        | Full HTTP request URL                                                                           |

See [examples](#With-RouteMatcher) below.

#### <Icon name="angle-right"></Icon> staticResponse (<code>[StaticResponse][staticresponse]</code>)

By passing in a `StaticResponse` as the last argument, you can [statically define (stub) a response](#Stubbing-a-response) for matched requests including the body of the response, as well as the headers and HTTP status code:

| Option     | Description                                            |
| ---------- | ------------------------------------------------------ |
| statusCode | HTTP response status code                              |
| headers    | HTTP response headers                                  |
| body       | Serve a static string/JSON object as the response body |
| fixture    | Serve a fixture as the HTTP response body              |

`StaticResponse` also provides options for simulating a degraded or broken network connection:

| Option            | Description                                                                 |
| ----------------- | --------------------------------------------------------------------------- |
| forceNetworkError | Force an error by destroying the browser connection                         |
| delay             | Minimum network latency or delay to add to the response time (milliseconds) |
| throttleKbps      | Maximum data transfer rate of the response (kilobits/second)                |

**Note:** All properties are optional.

See [Stubbing a response with a `StaticResponse` object](#With-a-StaticResponse-object) for an example.

See also [`StaticResponse` objects](#StaticResponse-objects).

#### <Icon name="angle-right"></Icon> routeHandler (<code>Function</code>)

The `routeHandler` function is called whenever a request is matched, with the first argument being the request object. From inside the callback, you have access to the entire request-response where you can modify the outgoing request, send a response, access the real response, and more.

See ["Intercepted requests"][req] and [Request/Response Modification with `routeHandler`](#Request-Response-Modification-with-routeHandler).

### Yields [<Icon name="question-circle"/>](/guides/core-concepts/introduction-to-cypress#Subject-Management)

- `cy.intercept()` yields `null`.
- `cy.intercept()` can be aliased, but otherwise cannot be chained further.
- Waiting on an aliased `cy.intercept()` route using [cy.wait()](/api/commands/wait) will yield an object that contains information about the matching request/response cycle. See [Using the yielded object](#Using-the-yielded-object) for examples of how to use this object.

## Examples

<Alert type="info">

`cy.intercept` can be used solely for spying: to passively listen for matching routes and apply [aliases](#Aliasing-a-Route) to them without manipulating the request or its response in any way. This alone is powerful as it allows you to [wait](#Waiting-on-a-request) for these requests, resulting in more reliable tests.

</Alert>

### Matching `url`

You can provide the exact [URL](#Arguments) to match or use pattern-matching to match many URLs at once, either with globs or with regex. See [Glob Pattern Matching URLs](#Glob-Pattern-Matching-URLs).

```js
// match any request that exactly matches the URL
cy.intercept('https://prod.cypress.io/users')

// match any request that satisfies a glob pattern
cy.intercept('/users?_limit=*')

// match any request that satisfies a regex pattern
cy.intercept(/\/users\?_limit=(3|5)$/)
```

### Matching `method`

<Alert type="warning">

If you don't pass in a [`method` argument][arg-method], then all HTTP methods (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`, etc.) will match.

</Alert>

```js
cy.intercept('/users')
// matches this: GET http://localhost/users
// ...and this, too: POST http://localhost/users

cy.intercept('GET', '/users')
// matches this: GET http://localhost/users
// ...but not this: POST http://localhost/users
```

### Aliasing an intercepted route

While `cy.intercept` doesn't yield anything, you can chain [`.as`](/api/commands/as) to it to create an [alias](/guides/core-concepts/variables-and-aliases#Aliases) which can be used to [wait on a request](#Waiting-on-a-request).

```js
cy.intercept('GET', '/users').as('getAllUsers')
cy.intercept('POST', '/users').as('createUser')
```

### Aliasing individual requests

Aliases can be set on a per-request basis by setting the `alias` property of the intercepted request. This is especially useful when intercepting GraphQL requests:

```js
cy.intercept('POST', '/graphql', (req) => {
  if (req.body.hasOwnProperty('query') && req.body.query.includes('mutation')) {
    req.alias = 'gqlMutation'
  }
})

// assert that a matching request has been made
cy.wait('@gqlMutation')
```

<Alert type="info">

For more guidance around aliasing requests with GraphQL, see [Working with GraphQL](/guides/testing-strategies/working-with-graphql)

</Alert>

### Matching `url` and `method` with [RouteMatcher](#routeMatcher-RouteMatcher)

Specifying a `method` and `url` to match can also be acheived by passing the `routeMatcher` object into `cy.intercept` instead:

```js
// These both yield the same result:
cy.intercept({ method: 'GET', url: '**/users' })
cy.intercept('GET', '**/users')
```

### Pattern Matching

```js
// match updates to the `/users` endpoint
cy.intercept({
  method: '+(PUT|PATCH)',
  url: '**/users/*',
})
// matches:
//   PUT /users/1
//   PATCH /users/1
//   doesn't match
//   GET /users
//   GET /users/1

// same as above, but using regex
cy.intercept({
  method: '/PUT|PATCH/',
  url: '**/users/*',
})
```

### Waiting on a request

Use [cy.wait()](/api/commands/wait) with [aliasing an intercepted route](#aliasing-an-intercepted-route) to wait for the request/response cycle to complete.

#### With URL

```js
cy.intercept('http://example.com/settings').as('getSettings')
// once a request to http://example.com/settings responds, this 'cy.wait' will resolve
cy.wait('@getSettings')
```

#### With [RouteMatcher](#routeMatcher-RouteMatcher)

```js
cy.intercept({
  url: 'http://example.com/search*',
  query: { q: 'expected terms' },
}).as('search')

// once any type of request to http://example.com/search with a querystring containing
// 'q=expected+terms' responds, this 'cy.wait' will resolve
cy.wait('@search')
```

```js
cy.intercept({
  pathname: '/search',
  query: {
    q: 'some terms',
  },
}).as('searchForTerms')
// this 'cy.wait' will only resolve once a request is made to '/search'
// with the query paramater 'q=some+terms'
cy.wait('@searchForTerms')
```

<!-- TODO move these examples to more appropriate sections (DX-374) -->

```js
cy.intercept(
  {
    // this RegExp matches any URL beginning with 'http://api.example.com/' and ending with '/edit' or '/save'
    url: /^http:\/\/api\.example\.com\/.*\/(edit|save)/,
    headers: {
      'x-requested-with': 'exampleClient',
    },
  },
  (req) => {
    // only requests to URLs starting with 'http://api.example.com/widgets'
    // and having the header 'x-requested-with: exampleClient' will be intercepted
  }
})

// in this example, the supplied URL `/users` is merged with the RouteMatcher
// passed as the second argument
cy.intercept('/users', { middleware: true }, (req) => {
  req.headers['authorization'] = `Bearer ${bearerToken}`
})

// this example will cause 1 request to `/temporary-error` to receive a network error
// and subsequent requests will not match this `RouteMatcher`
cy.intercept('/temporary-error', { times: 1 }, { forceNetworkError: true })
```

#### Using the yielded object

Using [cy.wait()](/api/commands/wait) on a `cy.intercept()` route alias yields an interception object which represents the request/response cycle:

```js
cy.wait('@someRoute').then((interception) => {
  // 'interception' is an object with properties 'id', 'request' and 'response'
})
```

You can chain [`.its()`](/api/commands/its) and [`.should()`](/api/commands/should) to assert against request/response cycles:

```js
// assert that a request to this route was made with a body that included 'user'
cy.wait('@someRoute').its('request.body').should('include', 'user')

// assert that a request to this route received a response with HTTP status 500
cy.wait('@someRoute').its('response.statusCode').should('eq', 500)

// assert that a request to this route received a response body that includes 'id'
cy.wait('@someRoute').its('response.body').should('include', 'id')
```

#### Waiting on errors

You can use [cy.wait()](/api/commands/wait) to wait on requests that end with network errors:

```js
cy.intercept('GET', '/should-err', { forceNetworkError: true }).as('err')

// assert that this request happened, and that it ended in an error
cy.wait('@err').should('have.property', 'error')
```

### Stubbing a response

#### With a string

```js
// requests to '/update' will be fulfilled with a body of "success"
cy.intercept('/update', 'success')
```

#### With a fixture

```js
// requests to '/users.json' will be fulfilled
// with the contents of the "users.json" fixture
cy.intercept('/users.json', { fixture: 'users.json' })
```

#### With a `StaticResponse` object

A [`StaticResponse`][staticresponse] object represents a response to an HTTP request, and can be used to stub routes:

```js
const staticResponse = {
  /* some StaticResponse properties here... */
}

cy.intercept('/projects', staticResponse)
```

Stub a response with a JSON body:

```js
cy.intercept('/projects', {
  body: [{ projectId: '1' }, { projectId: '2' }],
})
```

Stub headers, status code, and body all at once:

```js
cy.intercept('/not-found', {
  statusCode: 404,
  body: '404 Not Found!',
  headers: {
    'x-not-found': 'true',
  },
})
```

See also [`StaticResponse` objects][staticresponse].

### Intercepting a request

<Alert type="info">

By specifying [`routeHandler`][arg-routehandler] as the last argument to `cy.intercept`, you'll have access to the entire request-response session, enabling you to modify the outgoing request, manipulate the real response, make assertions, etc.

</Alert><commit_msg>update routehandler example section<commit_after>---
title: intercept
---

Spy and stub network requests and responses.

<Alert type="warning">

We highly recommend you read the [Network Requests](/guides/guides/network-requests) guide first.

</Alert>

<Alert type="warning">

`cy.intercept()` is the successor to `cy.route()` as of Cypress 6.0.0. See [Comparison to `cy.route`](#Comparison-to-cy-route).

</Alert>

<Alert type="warning">

All intercepts are automatically cleared before every test.

</Alert>

## Syntax

```js
// spying only
cy.intercept(url)
cy.intercept(method, url)
cy.intercept(routeMatcher)

// spying and response stubbing
cy.intercept(url, staticResponse)
cy.intercept(method, url, staticResponse)
cy.intercept(routeMatcher, staticResponse)
cy.intercept(url, routeMatcher, staticResponse)

// spying, dynamic stubbing, request modification, etc.
cy.intercept(url, routeHandler)
cy.intercept(method, url, routeHandler)
cy.intercept(routeMatcher, routeHandler)
cy.intercept(url, routeMatcher, routeHandler)
```

### Usage

**<Icon name="check-circle" color="green"></Icon> Correct Usage**

```js
// spying
cy.intercept('/users/**')
cy.intercept('GET', '/users*')
cy.intercept({
  method: 'GET',
  url: '/users*',
  hostname: 'localhost',
})

// spying and response stubbing
cy.intercept('POST', '/users*', {
  statusCode: 201,
  body: {
    name: '<NAME>',
  },
})

// spying, dynamic stubbing, request modification, etc.
cy.intercept('/users*', { hostname: 'localhost' }, (req) => {
  /* do something with request and/or response */
})
```

### Arguments

#### **<Icon name="angle-right"></Icon> method** **_(String)_**

Specify the [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`, etc.) to match on. This is an optional argument, but if no `method` is provided, Cypress will match _any_ HTTP method (`*`) by default.

#### **<Icon name="angle-right"></Icon> url** **_(String, Glob, RegExp)_**

Specify the URL to match. See [Matching `url`](#match-url) for examples.

Alternatively, specify the URL via the [`routeMatcher`][arg-routematcher] argument (below).

#### **<Icon name="angle-right"></Icon> routeMatcher** **_(`RouteMatcher`)_**

`routeMatcher` is an object used to match the incoming HTTP requests with this intercepted route.

All properties are optional but all those that are set must match for the request to be intercepted. If a `string` is passed to any property, it will be glob-matched against the request using [`Cypress.minimatch`](/api/utilities/minimatch).

| Option     | Description                                                                                     |
| ---------- | ----------------------------------------------------------------------------------------------- |
| auth       | HTTP Basic Authentication (`object` with keys `username` and `password`)                        |
| headers    | HTTP request headers (`object`)                                                                 |
| hostname   | HTTP request hostname                                                                           |
| https      | `true`: only secure (https://) requests, `false`: only insecure (http://) requests              |
| method     | HTTP request method (matches any method by default)                                             |
| middleware | `true`: match route first and in defined order, `false`: match route in reverse order (default) |
| path       | HTTP request path after the hostname, including query parameters                                |
| pathname   | Like `path`, but without query parameters                                                       |
| port       | HTTP request port(s) (`number` or `Array`)                                                      |
| query      | Parsed query string (`object`)                                                                  |
| times      | Maximum number of times to match (`number`)                                                     |
| url        | Full HTTP request URL                                                                           |

See [examples](#With-RouteMatcher) below.

#### <Icon name="angle-right"></Icon> staticResponse (<code>[StaticResponse][staticresponse]</code>)

By passing in a `StaticResponse` as the last argument, you can [statically define (stub) a response](#Stubbing-a-response) for matched requests including the body of the response, as well as the headers and HTTP status code:

| Option     | Description                                            |
| ---------- | ------------------------------------------------------ |
| statusCode | HTTP response status code                              |
| headers    | HTTP response headers                                  |
| body       | Serve a static string/JSON object as the response body |
| fixture    | Serve a fixture as the HTTP response body              |

`StaticResponse` also provides options for simulating a degraded or broken network connection:

| Option            | Description                                                                 |
| ----------------- | --------------------------------------------------------------------------- |
| forceNetworkError | Force an error by destroying the browser connection                         |
| delay             | Minimum network latency or delay to add to the response time (milliseconds) |
| throttleKbps      | Maximum data transfer rate of the response (kilobits/second)                |

**Note:** All properties are optional.

See [Stubbing a response with a `StaticResponse` object](#With-a-StaticResponse-object) for an example.

See also [`StaticResponse` objects](#StaticResponse-objects).

#### <Icon name="angle-right"></Icon> routeHandler (<code>Function</code>)

The `routeHandler` function is called whenever a request is matched, with the first argument being the request object. From inside the callback, you have access to the entire request-response where you can modify the outgoing request, send a response, access the real response, and more.

See ["Intercepted requests"][req] and [Request/Response Modification with `routeHandler`](#Request-Response-Modification-with-routeHandler).

### Yields [<Icon name="question-circle"/>](/guides/core-concepts/introduction-to-cypress#Subject-Management)

- `cy.intercept()` yields `null`.
- `cy.intercept()` can be aliased, but otherwise cannot be chained further.
- Waiting on an aliased `cy.intercept()` route using [cy.wait()](/api/commands/wait) will yield an object that contains information about the matching request/response cycle. See [Using the yielded object](#Using-the-yielded-object) for examples of how to use this object.

## Examples

<Alert type="info">

`cy.intercept` can be used solely for spying: to passively listen for matching routes and apply [aliases](#Aliasing-a-Route) to them without manipulating the request or its response in any way. This alone is powerful as it allows you to [wait](#Waiting-on-a-request) for these requests, resulting in more reliable tests.

</Alert>

### Matching `url`

You can provide the exact [URL](#Arguments) to match or use pattern-matching to match many URLs at once, either with globs or with regex. See [Glob Pattern Matching URLs](#Glob-Pattern-Matching-URLs).

```js
// match any request that exactly matches the URL
cy.intercept('https://prod.cypress.io/users')

// match any request that satisfies a glob pattern
cy.intercept('/users?_limit=*')

// match any request that satisfies a regex pattern
cy.intercept(/\/users\?_limit=(3|5)$/)
```

### Matching `method`

<Alert type="warning">

If you don't pass in a [`method` argument][arg-method], then all HTTP methods (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`, etc.) will match.

</Alert>

```js
cy.intercept('/users')
// matches this: GET http://localhost/users
// ...and this, too: POST http://localhost/users

cy.intercept('GET', '/users')
// matches this: GET http://localhost/users
// ...but not this: POST http://localhost/users
```

### Aliasing an intercepted route

While `cy.intercept` doesn't yield anything, you can chain [`.as`](/api/commands/as) to it to create an [alias](/guides/core-concepts/variables-and-aliases#Aliases) which can be used to [wait on a request](#Waiting-on-a-request).

```js
cy.intercept('GET', '/users').as('getAllUsers')
cy.intercept('POST', '/users').as('createUser')
```

### Aliasing individual requests

Aliases can be set on a per-request basis by setting the `alias` property of the intercepted request. This is especially useful when intercepting GraphQL requests:

```js
cy.intercept('POST', '/graphql', (req) => {
  if (req.body.hasOwnProperty('query') && req.body.query.includes('mutation')) {
    req.alias = 'gqlMutation'
  }
})

// assert that a matching request has been made
cy.wait('@gqlMutation')
```

<Alert type="info">

For more guidance around aliasing requests with GraphQL, see [Working with GraphQL](/guides/testing-strategies/working-with-graphql)

</Alert>

### Matching `url` and `method` with [RouteMatcher](#routeMatcher-RouteMatcher)

Specifying a `method` and `url` to match can also be acheived by passing the `routeMatcher` object into `cy.intercept` instead:

```js
// These both yield the same result:
cy.intercept({ method: 'GET', url: '**/users' })
cy.intercept('GET', '**/users')
```

### Pattern Matching

```js
// match updates to the `/users` endpoint
cy.intercept({
  method: '+(PUT|PATCH)',
  url: '**/users/*',
})
// matches:
//   PUT /users/1
//   PATCH /users/1
//   doesn't match
//   GET /users
//   GET /users/1

// same as above, but using regex
cy.intercept({
  method: '/PUT|PATCH/',
  url: '**/users/*',
})
```

### Waiting on a request

Use [cy.wait()](/api/commands/wait) with [aliasing an intercepted route](#aliasing-an-intercepted-route) to wait for the request/response cycle to complete.

#### With URL

```js
cy.intercept('http://example.com/settings').as('getSettings')
// once a request to http://example.com/settings responds, this 'cy.wait' will resolve
cy.wait('@getSettings')
```

#### With [RouteMatcher](#routeMatcher-RouteMatcher)

```js
cy.intercept({
  url: 'http://example.com/search*',
  query: { q: 'expected terms' },
}).as('search')

// once any type of request to http://example.com/search with a querystring containing
// 'q=expected+terms' responds, this 'cy.wait' will resolve
cy.wait('@search')
```

```js
cy.intercept({
  pathname: '/search',
  query: {
    q: 'some terms',
  },
}).as('searchForTerms')
// this 'cy.wait' will only resolve once a request is made to '/search'
// with the query paramater 'q=some+terms'
cy.wait('@searchForTerms')
```

<!-- TODO move these examples to more appropriate sections (DX-374) -->

```js
cy.intercept(
  {
    // this RegExp matches any URL beginning with 'http://api.example.com/' and ending with '/edit' or '/save'
    url: /^http:\/\/api\.example\.com\/.*\/(edit|save)/,
    headers: {
      'x-requested-with': 'exampleClient',
    },
  },
  (req) => {
    // only requests to URLs starting with 'http://api.example.com/widgets'
    // and having the header 'x-requested-with: exampleClient' will be intercepted
  }
})

// in this example, the supplied URL `/users` is merged with the RouteMatcher
// passed as the second argument
cy.intercept('/users', { middleware: true }, (req) => {
  req.headers['authorization'] = `Bearer ${bearerToken}`
})

// this example will cause 1 request to `/temporary-error` to receive a network error
// and subsequent requests will not match this `RouteMatcher`
cy.intercept('/temporary-error', { times: 1 }, { forceNetworkError: true })
```

#### Using the yielded object

Using [cy.wait()](/api/commands/wait) on a `cy.intercept()` route alias yields an interception object which represents the request/response cycle:

```js
cy.wait('@someRoute').then((interception) => {
  // 'interception' is an object with properties 'id', 'request' and 'response'
})
```

You can chain [`.its()`](/api/commands/its) and [`.should()`](/api/commands/should) to assert against request/response cycles:

```js
// assert that a request to this route was made with a body that included 'user'
cy.wait('@someRoute').its('request.body').should('include', 'user')

// assert that a request to this route received a response with HTTP status 500
cy.wait('@someRoute').its('response.statusCode').should('eq', 500)

// assert that a request to this route received a response body that includes 'id'
cy.wait('@someRoute').its('response.body').should('include', 'id')
```

#### Waiting on errors

You can use [cy.wait()](/api/commands/wait) to wait on requests that end with network errors:

```js
cy.intercept('GET', '/should-err', { forceNetworkError: true }).as('err')

// assert that this request happened, and that it ended in an error
cy.wait('@err').should('have.property', 'error')
```

### Stubbing a response

#### With a string

```js
// requests to '/update' will be fulfilled with a body of "success"
cy.intercept('/update', 'success')
```

#### With a fixture

```js
// requests to '/users.json' will be fulfilled
// with the contents of the "users.json" fixture
cy.intercept('/users.json', { fixture: 'users.json' })
```

#### With a `StaticResponse` object

A [`StaticResponse`][staticresponse] object represents a response to an HTTP request, and can be used to stub routes:

```js
const staticResponse = {
  /* some StaticResponse properties here... */
}

cy.intercept('/projects', staticResponse)
```

Stub a response with a JSON body:

```js
cy.intercept('/projects', {
  body: [{ projectId: '1' }, { projectId: '2' }],
})
```

Stub headers, status code, and body all at once:

```js
cy.intercept('/not-found', {
  statusCode: 404,
  body: '404 Not Found!',
  headers: {
    'x-not-found': 'true',
  },
})
```

See also [`StaticResponse` objects][staticresponse].

### Using the **`routeHandler`** function

By specifying a [`routeHandler`][arg-routehandler] function as the last argument to `cy.intercept`, you'll have access to the entire request-response session, enabling you to modify the outgoing request, manipulate the real response, make assertions, etc.

The `routeHandler` takes the incoming HTTP request (`IncomingHTTPRequest`) as the first argument.

```js
cy.intercept('/users*', (req) => {
  /* do something with request and/or response */
})
```

<Alert type="info">

Throughout these examples we will refer to the incoming HTTP request as `req`. Those of you with [Express.js](https://expressjs.com/) [middleware](https://expressjs.com/en/guide/writing-middleware.html) experience should be familiar with this syntax.

</Alert>
{'fraction_non_alphanumeric': 0.15815902479567806, 'fraction_numerical': 0.00207785011774484, 'mean_word_length': 3.00291100637649, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 80, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 50, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1190224', 'n_tokens_mistral': 8178, 'n_tokens_neox': 7817, 'n_words': 2806}