You can use App Check to protect non-Google custom backend resources for
your app, like your own self-hosted backend. To do so, you'll need to do both of
the following:

- Modify your app client to send an App Check token along with each request to your backend, as described on this page.
- Modify your backend to require a valid App Check token with every request, as described in [Verify App Check tokens from a custom backend](https://firebase.google.com/docs/app-check/custom-resource-backend.md.txt).

## Before you begin

Add App Check to your app, using either the
[reCAPTCHA Enterprise provider](https://firebase.google.com/docs/app-check/web/recaptcha-enterprise-provider.md.txt)
or a [custom provider](https://firebase.google.com/docs/app-check/web/custom-provider.md.txt).

## Send App Check tokens with backend requests

In your app client, before each request, get a valid, unexpired, App Check
token with `appCheck().getToken()`. The App Check library will refresh the
token if necessary.

Once you have a valid token, send it along with the request to your backend. The
specifics of how you accomplish this are up to you, but *don't send
App Check tokens as part of URLs*, including in query parameters, as this
makes them vulnerable to accidental leakage and interception. The following
example sends the token in a custom HTTP header, which is the recommended
approach.

### Web

```javascript
import { initializeAppCheck, getToken } from 'firebase/app-check';

const appCheck = initializeAppCheck(
    app,
    { provider: provider } // ReCaptchaV3Provider or CustomProvider
);

const callApiWithAppCheckExample = async () => {
  let appCheckTokenResponse;
  try {
      appCheckTokenResponse = await getToken(appCheck, /* forceRefresh= */ false);
  } catch (err) {
      // Handle any errors if the token was not retrieved.
      return;
  }

  // Include the App Check token with requests to your server.
  const apiResponse = await fetch('https://yourbackend.example.com/yourApiEndpoint', {
      headers: {
          'X-Firebase-AppCheck': appCheckTokenResponse.token,
      }
  });

  // Handle response from your backend.
};
```

### Web

```javascript
const callApiWithAppCheckExample = async () => {
  let appCheckTokenResponse;
  try {
      appCheckTokenResponse = await firebase.appCheck().getToken(/* forceRefresh= */ false);
  } catch (err) {
      // Handle any errors if the token was not retrieved.
      return;
  }

  // Include the App Check token with requests to your server.
  const apiResponse = await fetch('https://yourbackend.example.com/yourApiEndpoint', {
      headers: {
          'X-Firebase-AppCheck': appCheckTokenResponse.token,
      }
  });

  // Handle response from your backend.
};
```

### Replay protection (beta)

When making a request to an endpoint for which you've enabled
[replay protection](https://firebase.google.com/docs/app-check/custom-resource-backend.md.txt#replay-protection),
acquire a token using `getLimitedUseToken()` instead of `getToken()`:

```javascript
import { getLimitedUseToken } from "firebase/app-check";

// ...

appCheckTokenResponse = await getLimitedUseToken(appCheck);
```