> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usecobalt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup

**The Cobalt Link** flow has the following steps:

1. Call  `https://api.usecobalt.com/link/token/create` to create a `link_token` and pass it to your app's client.
2. Use the `link_token` to open Link for your user. In the `onSuccess` callback, Link will provide a temporary `public_token`.
3. Call `https://api.usecobalt.com/link/token/exchange` to exchange the `public_token` for a permanent `access_token`.
4. Store the `access_token` and use it to make API requests.

## Detailed Steps

### Create Link Token

The `/link/token/create` endpoint creates a `link_token`, which is required as a parameter when initializing Link. Once Link has been initialized, it returns a `public_token`, which can then be exchanged for an `access_token` via `/link/token/exchange` as part of the main Link flow.

<aside>
  💡 The `link_token` expires after 20 minutes. Once a token expires, it can no longer be used and you will have to call the endpoint again to get a new one.
</aside>

```bash theme={null}
curl -X POST https://api.usecobalt.com/link/token/create \
-H 'Content-Type: application/json' \
-H 'client_id: "%COBALT_CLIENT_ID%"' \
-H 'client_secret: "%COBALT_CLIENT_SECRET%"' \
-d '{
  "user_id": "%REFERENCE_USER_ID%",
  "org_id": "%REFERENCE_ORG_ID%"
}'
```

The request requires the following parameters:

* `client_id`  this is your Cobalt API client id.
* `client_secret` this is your Cobalt API secret.
* `user_id`  this is a unique ID representing the end user. Typically, this will be a user ID number from your application. Personally identifiable information, such as an email address or phone number, should not be used in the `user_id`.
* `org_id`  this is a unique identifier for the organization that this user belongs to in your system. This is often a clinic or hospital. This association is important to handle any custom settings that an org has. You choose this identifier - it can be any string that uniquely identifies the organization in your system.

#### Creating a New Organization

If this is the first user from a new organization, you'll need to provide additional parameters to create the organization:

* `emr_name` **(required for new orgs)** - The name of the EMR system. Contact support for a list of supported EMR systems.
* `emr_instance_domain` **(required for new orgs)** - The EMR instance URL (e.g., `https://mypractice.example.com`). Domain requirements vary by EMR.

**Example request for a new organization:**

```bash theme={null}
curl -X POST https://api.usecobalt.com/link/token/create \
-H 'Content-Type: application/json' \
-H 'client_id: "%COBALT_CLIENT_ID%"' \
-H 'client_secret: "%COBALT_CLIENT_SECRET%"' \
-d '{
  "user_id": "%REFERENCE_USER_ID%",
  "org_id": "%REFERENCE_ORG_ID%",
  "emr_name": "%EMR_NAME%",
  "emr_instance_domain": "https://your-emr-instance.com"
}'
```

Example response:

```bash theme={null}
{
    "success": true,
    "token": "189hisdf78w9r3ysdfhi" // used in next step.
}
```

### Initialize Client Link

**Lightbox Mode**

<aside>
  ❗ When using Lightbox Mode you’ll need to register your application domain with Cobalt. Please contact [bryan@usecobalt.com](mailto:bryan@usecobalt.com) to set this up.
</aside>

Lightbox Mode will activate the Cobalt Link experience in a modal rather than having the element appear directly embedded elsewhere on the page. The lightbox takes up the entire user's screen, darkening the background content with a semi-transparent overlay of the page and centering Cobalt’s Link UI in a modal located at the center of the user's screen.

To utilize Lightbox mode, include the Javascript snippet on your site, before the closing `</body>` tag. Make sure to attach a button's `onClick` event to call the `launch_cobalt()` function. Alternatively, you can call the `window.CobaltLink.init()` function directly within an event callback of your choice.

`CobaltLink.init` accepts one argument, a configuration `Object`. The configuration object requires the following parameters:

* `token` this is the temporary `link_token` from the [create link token step](https://www.notion.so/Getting-Started-9d469ab83e1e421abfc770feed375c65?pvs=21).
* `onSuccess` this callback is called when a user successfully links their account. It takes one argument: the `public_token`. The `public_token` can then be used in the [exchange public token step](https://www.notion.so/Getting-Started-9d469ab83e1e421abfc770feed375c65?pvs=21).

**New Window Mode**

If you prefer to not include the Cobalt Link code in your site you can use the Cobalt dashboard to generate a Link to share with your users so they can enter their credentials. You will then be able to view the access\_token in the Cobalt dashboard.

### Exchange Public Token

The `/link/token/exchange` endpoint exchanges a `public_token` for an `access_token`.

```bash theme={null}
curl -X GET "https://api.usecobalt.com/link/token/exchange" \
-H 'Content-Type: application/json' \
-H 'client_id: "%COBALT_CLIENT_ID%"' \
-H 'client_secret: "%COBALT_CLIENT_SECRET%"' 
-G \
--data-urlencode "public_token=234p852489035y29083y4" \
```

The request requires the following parameters:

* `client_id`  this is your Cobalt API client id.
* `client_secret` this is your Cobalt API secret.
* `public_token` this is the token acquired during the Initialize Client Link step.

Example response:

```bash theme={null}
{
    "success": true,
    "token": "9872394hjkldsfh987re9iwqhjosdffh9sdychosdofc"
}
```

## Examples

### Code snippet

```jsx theme={null}
<script async defer src="https://link.usecobalt.com/init.js"></script>

<script>
    function launch_cobalt() {
        window.CobaltLink.init({
            token: "%TEMPORARY_LINK_TOKEN%",
            onSuccess: (public_token) => {
              // send the public_token to your server so it can exchange it for an access_token
            },
        })
    }
</script>
```

### Javascript

```jsx theme={null}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cobalt Demo</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>
    <div id="button-container">
        <button id="loadAppButton">Link account</button>
    </div>

    <script src="https://link.usecobalt.com/init.js"></script>
    
    <script type="text/javascript">
        document.getElementById('loadAppButton').addEventListener('click', async function() {

            // Fetch the link token from the Cobalt API
            try {
                const publicTokenResponse = await fetch('https://api.usecobalt.com/link/token/create', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'client_id': '%COBALT_CLIENT_ID%',
                        'client_secret': '%COBALT_CLIENT_SECRET%'
                    },
                    body: JSON.stringify({ user_id: '%REFERENCE_USER_ID%', org_id: '%REFERENCE_ORG_ID%' })
                });
                const publicTokenData = await publicTokenResponse.json();
                
                if (publicTokenData && publicTokenData.token) {
                    // Initialize Cobalt Link with the fetched token
                    window.CobaltLink.init({
                        token: publicTokenData.token,
                        onSuccess: async (public_token) => {
                            console.log('got the public_token: ', public_token);
	                            
                            // Exchange the public token for the access token
                            const accessTokenResponse = await fetch(`https://api.usecobalt.com/link/token/exchange?public_token=${public_token}`, {
					                    method: 'GET',
					                    headers: {                        
						                    'Content-Type': 'application/json',
						                    'client_id': '%COBALT_CLIENT_ID%',
						                    'client_secret': '%COBALT_CLIENT_SECRET%'
						                  },
					                  });
						                const accessTokenData = await accessTokenResponse.json();
						                console.log('got the access_token: ', accessTokenData.token);
						                // Now you can save the access_token and use it to call the API
                    });
                } else {
                    console.error('Failed to obtain link token:', data.message);
                    messageEl.innerText = "Error: " + data.message;
                }
            } catch (err) {
                console.error('Failed to setup integration:', err);
                messageEl.innerText = "Error: " + err.message;
            }
        });
    </script>
</body>
</html>
```

### React

```jsx theme={null}
import React, { useCallback, useState, useEffect } from "react";

// Custom hook from Cobalt for handling link operations.
// Run `npm i @cobalt-technology/react-link` to install the package. 
import { useCobaltLink } from "@cobalt-technology/react-link";

export default function CobaltLinkDemo() {
    const [linkToken, setLinkToken] = useState(null); // State to store the link token received from the Cobalt API
    const [publicToken, setPublicToken] = useState(""); // State to store the public token received from the onSuccess callback
    const [isReadyToInit, setIsReadyToInit] = useState(false); // State to determine if the component is ready to initialize the Cobalt link

    // Callback function to handle success after receiving public token
    const onSuccess = useCallback((public_token) => {
        console.log("got the public_token: ", public_token);
        setPublicToken("Public token: " + public_token);
        
        // Exchange the public token for the access token
        const accessTokenResponse = await fetch(`https://api.usecobalt.com/link/token/exchange?public_token=${public_token}`, {
	        method: 'GET',
	        headers: {                        
		        'Content-Type': 'application/json',
		        'client_id': '%COBALT_CLIENT_ID%',
		        'client_secret': '%COBALT_CLIENT_SECRET%'
		      },
				});
				const accessTokenData = await accessTokenResponse.json();
				console.log('got the access_token: ', accessTokenData.token);
				// Now you can save the access_token and use it to call the API
    }, []);

    // Destructuring the necessary methods and states from the useCobaltLink hook
    const { init, loading } = useCobaltLink({
        token: linkToken,
        onSuccess,
    });

    // Effect to initialize the Cobalt link once conditions are met
    useEffect(() => {
        if (isReadyToInit && linkToken && !publicToken) {
            init();
        }
    }, [isReadyToInit, linkToken, init]);

    // Function to request a link token from the Cobalt API
    const initLink = async () => {
        try {
            const response = await fetch(
                "https://api.usecobalt.com/link/token/create", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                        client_id: "%COBALT_CLIENT_ID%",
                        client_secret: "%COBALT_CLIENT_SECRET%",
                    },
                    body: JSON.stringify({ user_id: "%REFERENCE_USER_ID%", org_id: "%REFERENCE_ORG_ID%" }),
                }
            );
            const data = await response.json();
            if (data && data.token) {
                setLinkToken(data.token);
                setIsReadyToInit(true);
            } else {
                console.error("Failed to obtain link token:", data.message);
            }
        } catch (err) {
            console.error("Failed to setup integration:", err);
        }
    };

    // Render a button that triggers the initLink function
    return (
        <div>
            <button disabled={loading} onClick={initLink}>
                Link Account
            </button>
        </div>
    );
}
```
