> For the complete documentation index, see [llms.txt](https://apps.developer.homey.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://apps.developer.homey.app/the-basics/devices/pairing/system-views/oauth2-login.md).

# OAuth2 Login

**Usage:** `"template": "login_oauth2"`

{% hint style="warning" %}
The example below is for completeness only. Pleaser read [OAuth2](/cloud/oauth2.md) to learn how to integrate with OAuth2 APIs the easy way.
{% endhint %}

{% code title="/drivers/\<driver\_id>/driver.compose.json" %}

```javascript
{
  "name": { "en": "My Driver" },
  "images": {
    "small": "/drivers/my_driver/assets/images/small.png",
    "large": "/drivers/my_driver/assets/images/large.png"
  },
  "pair": [
    {
      "id": "login_oauth2",
      "template": "login_oauth2",
      "options": {
        "hint": "Login with your credentials",
        "button": "Log-in"
      }
    },
    {
      "id": "list_devices",
      "template": "list_devices",
      "navigation": { "next": "add_devices" }
    },
    {
      "id": "add_devices",
      "template": "add_devices"
    }
  ]
}
```

{% endcode %}

## **Options**

| Key        | Type                                                          | Default | Description |
| ---------- | ------------------------------------------------------------- | ------- | ----------- |
| `title`    | [translation object](/the-basics/app/internationalization.md) |         |             |
| `subtitle` | [translation object](/the-basics/app/internationalization.md) |         |             |
| `hint`     | [translation object](/the-basics/app/internationalization.md) | `""`    |             |
| `button`   | [translation object](/the-basics/app/internationalization.md) | `""`    |             |

When either `hint` or `button` are set to a value, a button will appear and wait for the user to click it before opening the popup.

{% tabs %}
{% tab title="JavaScript" %}
{% code title="/drivers/\<driver\_id>/driver.js" %}

```javascript
const Homey = require("homey");

const API_URL = "https://api.myservice.com/oauth2/authorise?response_type=code";
const CALLBACK_URL = "https://callback.athom.com/oauth2/callback/";
const CLIENT_ID = Homey.env.CLIENT_ID;
const OAUTH_URL = `${API_URL}&client_id=${CLIENT_ID}&redirect_uri=${CALLBACK_URL}`;

class Driver extends Homey.Driver {
  async onPair(session) {
    const myOAuth2Callback = await this.homey.cloud.createOAuth2Callback(OAUTH_URL);

    myOAuth2Callback
      .on("url", (url) => {
        // send the URL to the front-end to open a popup
        session.emit("url", url);
      })
      .on("code", (code) => {
        // ... swap your code here for an access token

        // tell the front-end we're done
        session.emit("authorized");
      });
  }
}

module.exports = Driver;
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
{% code title="/drivers/\<driver\_id>/driver.js" %}

```mts
import Homey from "homey";

const API_URL = "https://api.myservice.com/oauth2/authorise?response_type=code";
const CALLBACK_URL = "https://callback.athom.com/oauth2/callback/";
const CLIENT_ID = Homey.env.CLIENT_ID;
const OAUTH_URL = `${API_URL}&client_id=${CLIENT_ID}&redirect_uri=${CALLBACK_URL}`;

export default class Driver extends Homey.Driver {
  async onPair(session: Homey.Driver.PairSession): Promise<void> {
    const myOauth2Callback = await this.homey.cloud.createOAuth2Callback(OAUTH_URL);

    myOauth2Callback
      .on("url", (url: string) => {
        // send the URL to the front-end to open a popup
        session.emit("url", url);
      })
      .on("code", (code: string) => {
        // ... swap your code here for an access token

        // tell the front-end we're done
        session.emit("authorized", undefined);
      });
  }
}

```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code title="/drivers/\<driver\_id>/driver.py" %}

```python
import asyncio

from homey import driver
from homey.homey import Homey
from homey.pair_session import PairSession

API_URL = "https://api.myservice.com/oauth2/authorise?response_type=code"
CALLBACK_URL = "https://callback.athom.com/oauth2/callback/"
CLIENT_ID = Homey.env.CLIENT_ID
OAUTH_URL = f"{API_URL}&client_id={CLIENT_ID}&redirect_uri={CALLBACK_URL}"


class Driver(driver.Driver):
    async def on_pair(self, session: PairSession) -> None:
        my_oauth2_callback = await self.homey.cloud.create_oauth2_callback(OAUTH_URL)

        def on_url(url: str):
            # send the URL to the front-end to open a popup
            asyncio.create_task(session.emit("url", url))

        def on_code(code: str | Exception):
            # ... swap your code here for an access token

            # tell the front-end we're done
            asyncio.create_task(session.emit("authorized"))

        my_oauth2_callback.on_url(on_url)
        my_oauth2_callback.on_code(on_code)


homey_export = Driver

```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://apps.developer.homey.app/the-basics/devices/pairing/system-views/oauth2-login.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
