> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-actions-triggers-prototype.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Learn how to use a single logical API in Auth0 to represent and control access to multiple APIs.

# Configure Logical API for Multiple APIs

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

export const codeExample = `https://{yourDomain}/authorize?
   scope=read:contacts%20read:calendar&
   audience=organize&
   response_type=id_token%20token&
   client_id={yourClientId}&
   redirect_uri=http://localhost:3000&
   nonce={nonce}
`;

If you have multiple distinct API implementations that are all logically a part of the same API, you can simplify your authorization process by representing them with a single logical API in the <Tooltip tip="Auth0 Dashboard: Auth0's main product to configure your services." cta="View Glossary" href="/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip>. Doing this allows you to implement just one <Tooltip tip="Auth0 Dashboard: Auth0's main product to configure your services." cta="View Glossary" href="/docs/glossary?term=authorization+flow">authorization flow</Tooltip>, while still controlling access to the individual APIs by assigning the appropriate scopes.

The following sections describe how to use and represent multiple APIs as a single <Tooltip tip="Resource Server: Server hosting protected resources. Resource servers accept and respond to protected resource requests." cta="View Glossary" href="/docs/glossary?term=Resource+Server">Resource Server</Tooltip> in Auth0. We will use the following sample application in the examples. The sample application uses a microservices architecture and contains:

* 2 Node.js APIs: `contacts` and `calendar` (you can think of them as microservices)
* 1 Resource Server representing the 2 APIs
* 2 Namespaced scopes: `read:contacts` and `read:calendar`
* The Implicit Grant flow to obtain an `access_token` that works for both APIs

We will represent the two APIs using just one Auth0 API called `Organizer Service`. We will then create two scopes to demonstrate how you can use the [Implicit Flow](/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) to access the `calendar` and `contacts` APIs from the SPA.

You need to complete the following steps:

1. Enable a connection for your application
2. Create a test user
3. Register a logical API in Auth0
4. Configure scopes for the logical API
5. Grant access to the logical API
6. (Optional) Implement single logout (SLO) or single sign-on (SSO)

## Prerequisites

* [Register your application](/docs/get-started/auth0-overview/create-applications/single-page-web-apps).

  * Select an **Application Type** of **Single-Page App**.
  * Add **Allowed Callback URLs** of `http://localhost:3000` and `http://localhost:3000/callback.html`.
* Download the [sample application](https://github.com/auth0-samples/auth0-api-auth-implicit-sample). To learn how to set up the sample app, read the [README](https://github.com/auth0-samples/auth0-api-auth-implicit-sample#readme).

## Enable a connection for your application

You will need a source of users for your newly-registered application, so you will need to configure a [connection](/docs/authenticate/identity-providers). For the purpose of this sample, we'll create a simple [Database Connection](/docs/authenticate/database-connections) that asks only for the user's email address and a password. To learn more, read [Set Up Database Connections](/docs/get-started/applications/set-up-database-connections).

## Create a test user

Since you're working with a newly-created connection, there won't be any users associated with it. Before we can test the sample application's login process, we'll need to create and associate a user with the connection, so make sure you choose your newly-created Connection when you create your user. To learn more, read [Create Users](/docs/manage-users/user-accounts/create-users).

## Register a logical API in Auth0

Register a single logical API that you will use to represent the multiple APIs contained within the sample application. For the purpose of this sample, call your API `Organizer Service` and set its unique identifier to `organize`. By default, the <Tooltip tip="Signing Algorithm: Algorithm used to digitally sign tokens to ensure the token has not been tampered with." cta="View Glossary" href="/docs/glossary?term=signing+algorithm">signing algorithm</Tooltip> for the tokens obtained for this API is **RS256**, which you should leave as is. To learn more, read [Register APIs](/docs/get-started/auth0-overview/set-up-apis).

## Configure permissions for the logical API

To allow the logical API to represent the APIs included within the sample application, you will need to create the proper permissions (scopes).

Scopes allow you to define which API actions will be accessible to calling applications. One scope will represent one API/action combination. For the purpose of this sample, you want calling applications to be able to `read` from one API called `calendar` and another one called `contacts`, so you will need to create the following permissions:

* `read:calendar`
* `read:contacts`

You can think of each one as a microservice. To learn more, read [Add API Permissions](/docs/get-started/apis/add-api-permissions) and [API Scopes](/docs/get-started/apis/scopes/api-scopes).

## Grant access to the logical API

You are now ready to provide access to your APIs by allowing the logical API to obtain <Tooltip tip="Access Token: Authorization credential, in the form of an opaque string or JWT, used to access an API." cta="View Glossary" href="/docs/glossary?term=Access+Tokens">Access Tokens</Tooltip>. By including the necessary scopes, you can control an application's access to the APIs represented by the logical API. The following steps use the [Implicit Flow](/docs/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post) to reflect the sample. However, you can use whichever flow best suits your needs. For example:

* If you have a **Machine-to-Machine Application**, you can authorize it to request Access Tokens for your API by executing a [Client Credentials Flow](/docs/get-started/authentication-and-authorization-flow/client-credentials-flow).
* If you are building a **Native App**, you can implement the [Authorization Code Flow with Proof Key for Code Exchange (PKCE)](/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce).

To learn about Authorization flows, read [Authentication and Authorization Flows](/docs/get-started/authentication-and-authorization-flow).

1. The user clicks Login within the SPA, and the app redirects the user to the Auth0 Authorization Server (`/authorize` endpoint). To learn more about the call's parameters, see our tutorial: [Call Your API Using the Authorization Code Flow with PKCE](/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce/call-your-api-using-the-authorization-code-flow-with-pkce).

   <AuthCodeBlock children={codeExample} language="http" />

   <Frame>
     <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/M4e_wjkc6eywZ_wO/docs/images/cdy7uua7fh8z/1ogYIaeDdyGL3Qo511m6Sh/5ab97c1535b2b62523a367594d44d66f/home.png?fit=max&auto=format&n=M4e_wjkc6eywZ_wO&q=85&s=86779073dc51f0a23f67d0b03fdaf303" alt="Example application sign in page" width="750" height="579" data-path="docs/images/cdy7uua7fh8z/1ogYIaeDdyGL3Qo511m6Sh/5ab97c1535b2b62523a367594d44d66f/home.png" />
   </Frame>
2. Your Auth0 Authorization Server redirects the user to the login page, where the user authenticates using one of the configured login options.

   <Frame>
     <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/4MaQENhfcY-1egb6/docs/images/cdy7uua7fh8z/6z6aA5nfA1uwOyx8srhvvI/2435a0909cfe44a57bef3ff27ef24e5b/lock.png?fit=max&auto=format&n=4MaQENhfcY-1egb6&q=85&s=fed465bdd1b49f5d61ae71dd17a42710" alt="Lock login page" width="750" height="579" data-path="docs/images/cdy7uua7fh8z/6z6aA5nfA1uwOyx8srhvvI/2435a0909cfe44a57bef3ff27ef24e5b/lock.png" />
   </Frame>
3. If this is the first time the user has been through this flow, they see a consent prompt listing the permissions Auth0 will give to the SPA. In this case, the user is asked to consent to the app reading their contacts and calendar.

   <Frame>
     <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/M4e_wjkc6eywZ_wO/docs/images/cdy7uua7fh8z/1te4FYRbu0aFcdohdXY2Rv/116bed5515eb2114c39374fb0a258912/consent-screen.png?fit=max&auto=format&n=M4e_wjkc6eywZ_wO&q=85&s=4737432fcf68a1530b43c09a1a1a0d8b" alt="Example application Lock Consent screen" width="750" height="579" data-path="docs/images/cdy7uua7fh8z/1te4FYRbu0aFcdohdXY2Rv/116bed5515eb2114c39374fb0a258912/consent-screen.png" />
   </Frame>
4. If the user consents, Auth0 redirects the user back to the SPA with tokens in the hash fragment of the URI. The SPA can now extract the tokens from the hash fragment using JavaScript and use the Access Token to call your APIs on behalf of the user.

   ```javascript lines theme={null}
   function getParameterByName(name) {
     var match = RegExp('[#&]' + name + '=([^&]*)').exec(window.location.hash);
     return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
   }

   function getAccessToken() {
     return getParameterByName('access_token');
   }
   ```

   In our sample, after you successfully log in, you will see buttons that allow you to call either of your APIs using the Access Token obtained from the logical API.

   <Frame>
     <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/I9SBuhVKpyu444Ha/docs/images/cdy7uua7fh8z/2pGWG5Wa7U1tBPhAJZ7Bat/7e194066560605cc842f20624b80d958/apis.png?fit=max&auto=format&n=I9SBuhVKpyu444Ha&q=85&s=d82b0069cfc68038b12c1e72c877d990" alt="Example application user authorized screen" width="750" height="579" data-path="docs/images/cdy7uua7fh8z/2pGWG5Wa7U1tBPhAJZ7Bat/7e194066560605cc842f20624b80d958/apis.png" />
   </Frame>

### Implement single logout (SLO) or single sign-on (SSO)

In some multi-application scenarios, where Single Logout is desired (a user logging out of one application needs to be logged out of other applications), an application can be set up to periodically poll Auth0 using `checkSession()` to see if a session exists. If the session does not exist, you can then log the user out of the application. The same polling method can be used to implement silent authentication for a <Tooltip tip="Single Sign-On (SSO): Service that, after a user logs into one applicaton, automatically logs that user in to other applications." cta="View Glossary" href="/docs/glossary?term=Single+Sign-on">Single Sign-on</Tooltip> (SSO) scenario.

The poll interval between checks to `checkSession()` should be at least 15 minutes between calls to avoid any issues in the future with rate limiting of this call.

## Learn more

* [Register APIs](/docs/get-started/auth0-overview/set-up-apis)
* [Add API Permissions](/docs/get-started/apis/add-api-permissions)
* [API Scopes](/docs/get-started/apis/scopes/api-scopes)
