diff --git a/inventory_provider/config.py b/inventory_provider/config.py
index d62dbb82e23c4277824a1c2e19d74f10d765f1e7..950ad31076a818bf869949f58a2a1c84c562b0f1 100644
--- a/inventory_provider/config.py
+++ b/inventory_provider/config.py
@@ -201,13 +201,36 @@ CONFIG_SCHEMA = {
             'items': {
                 'type': 'object',
                 'properties': {
-                  'nren': {'type': 'string'},
-                  'asn': {'type': 'integer'}
+                    'nren': {'type': 'string'},
+                    'asn': {'type': 'integer'}
                 },
                 'required': ['nren', 'asn'],
                 'additionalProperties': False
             },
-        }
+        },
+        'aai': {
+            'type': 'object',
+            'properties': {
+                'discovery_endpoint_url': {'type': 'string'},
+                'inventory_provider': {'type': 'object',
+                                       'properties': {
+                                           'client_id': {'type': 'string'},
+                                           'secret': {'type': 'string'}
+                                       },
+                                       'required': ['client_id', 'secret'],
+                                       'additionalProperties': False}
+            },
+            'required': ['discovery_endpoint_url', 'inventory_provider'],
+            'additionalProperties': False
+        },
+        'orchestrator': {
+            'type': 'object',
+            'properties': {
+                'url': {'type': 'string'},
+            },
+            'required': ['url'],
+            'additionalProperties': False
+        },
     },
 
     'type': 'object',
@@ -225,8 +248,13 @@ CONFIG_SCHEMA = {
         },
         'managed-routers': {'type': 'string'},
         'lab-routers': {
-            'type': 'array',
-            'items': {'type': 'string'}
+            'type': 'object',
+            'properties': {
+                '^[a-zA-Z0-9.-]+$': {
+                    'type': 'string',
+                    'enum': ['nokia', 'juniper']
+                }
+            }
         },
         'unmanaged-interfaces': {
             'type': 'array',
@@ -237,7 +265,8 @@ CONFIG_SCHEMA = {
         'nokia-community-inventory-provider': {'type': 'string'},
         'nokia-community-dashboard': {'type': 'string'},
         'nokia-community-brian': {'type': 'string'},
-
+        'aai': {'$ref': '#/definitions/aai'},
+        'orchestrator': {'$ref': '#/definitions/orchestrator'}
     },
     'oneOf': [
         {
@@ -249,7 +278,9 @@ CONFIG_SCHEMA = {
                 'ims',
                 'managed-routers',
                 'gws-direct',
-                'nren-asn-map']
+                'nren-asn-map',
+                'aai',
+                'orchestrator']
         },
         {
             'required': [
@@ -260,7 +291,9 @@ CONFIG_SCHEMA = {
                 'ims',
                 'managed-routers',
                 'gws-direct',
-                'nren-asn-map']
+                'nren-asn-map',
+                'aai',
+                'orchestrator']
         }
     ],
     'additionalProperties': False
diff --git a/inventory_provider/gap.py b/inventory_provider/gap.py
new file mode 100644
index 0000000000000000000000000000000000000000..7e2da432682c58a280c5bf6e66f3f707f5ff0499
--- /dev/null
+++ b/inventory_provider/gap.py
@@ -0,0 +1,124 @@
+import logging
+
+import requests
+
+from inventory_provider.tasks.config import inventory_provider_config
+
+logger = logging.getLogger(__name__)
+
+
+class Orchestrator:
+    GRANT_TYPE = 'client_credentials'
+    SCOPE = 'openid profile email aarc'
+
+    def __init__(self):
+        self.config = inventory_provider_config['aai']['inventory_provider']
+        self.base_url = f'{inventory_provider_config["orchestrator"]["url"]}/api/graphql'
+
+    @staticmethod
+    def _get_token_endpoint() -> str:
+        response = requests.get(inventory_provider_config['aai']['discovery_endpoint_url'])
+        response.raise_for_status()
+        return response.json()['token_endpoint']
+
+    def _get_token(self) -> str:
+        response = requests.post(
+            self._get_token_endpoint(),
+            data={
+                'grant_type': self.GRANT_TYPE,
+                'scope': self.SCOPE,
+                'client_id': self.config['client_id'],
+                'client_secret': self.config['secret']
+            }
+        )
+        response.raise_for_status()
+        return response.json()['access_token']
+
+    def _get_headers(self) -> dict:
+        token = self._get_token()
+        return {
+            'Authorization': f'Bearer {token}'
+        }
+
+    def _make_request(self, url: str, body: dict) -> dict:
+        headers = self._get_headers()
+        response = requests.post(url, headers=headers, json=body)
+        response.raise_for_status()
+        return response.json()
+
+    def _extract_router_info(self, device: dict) -> dict or None:
+        tag_to_key_map = {
+            "RTR": "router",
+            "OFFICE_ROUTER": "office_router",
+            "Super_POP_SWITCH": "super_pop_switch"
+        }
+
+        tag = device.get("product", {}).get("tag")
+        key = tag_to_key_map.get(tag)
+        subscription_id = device.get("subscriptionId")
+
+        if key is None or subscription_id is None:
+            logger.warning(f"Skipping device with invalid tag or subscription ID: {device}")
+            return None
+
+        query = f"""
+        query {{
+                subscriptions(
+                    filterBy: {{ field: "subscriptionId", value: "{subscription_id}" }}
+                ) {{
+                    page {{
+                        subscriptionId
+                        productBlockInstances {{
+                            productBlockInstanceValues
+                        }}
+                    }}
+                }}
+            }}
+            """
+
+        response = self._make_request(self.base_url, body={'query': query})
+        page_data = response.get('data', {}).get('subscriptions', {}).get('page')
+
+        if not page_data:
+            logger.warning(f"No data for subscription ID: {subscription_id}")
+            return None
+
+        instance_values = page_data[0].get('productBlockInstances', [{}])[0].get('productBlockInstanceValues', [])
+
+        fqdn = next((item.get('value') for item in instance_values if item.get('field') == f'{key}Fqdn'), None)
+        vendor = next((item.get('value') for item in instance_values if item.get('field') == 'vendor'), None)
+
+        if fqdn and vendor:
+            return {'fqdn': fqdn, 'vendor': vendor}
+        else:
+            logger.warning(f"Skipping device with missing FQDN or vendor: {device}")
+            return None
+
+    def load_routers_from_orchestrator(self) -> dict:
+        query = """
+        {
+            subscriptions(
+                filterBy: {field: "status", value: "ACTIVE"},
+                query: "tag:(RTR|OFFICE_ROUTER|Super_POP_SWITCH)"
+                
+            ) {
+                page {
+                    subscriptionId
+                    product {
+                        tag
+                    }
+                }
+            }
+        }
+        """
+        routers = {}
+        response = self._make_request(self.base_url, body={'query': query})
+        try:
+            devices = response['data']['subscriptions']['page']
+        except TypeError:
+            devices = []
+        for device in devices:
+            router_info = self._extract_router_info(device)
+            if router_info is not None:
+                routers[router_info['fqdn']] = router_info['vendor']
+        return routers
diff --git a/inventory_provider/routes/poller.py b/inventory_provider/routes/poller.py
index 45634297e78c08effbb9aafa804da806816d4681..4de3d461ecd74470ebe57394e6951c5269aa6f5d 100644
--- a/inventory_provider/routes/poller.py
+++ b/inventory_provider/routes/poller.py
@@ -932,14 +932,17 @@ def load_error_report_interfaces(
                 )
             )
 
-    def transform_interface(interface: dict):
+    def get_vendor(router: str) -> str | None:
+        current_redis = common.get_current_redis()
+        netdash_equipment = json.loads(current_redis.get('netdash').decode('utf-8'))
+        return netdash_equipment.get(router)
+
+    def transform_interface(interface: dict) -> dict:
         return {
             "router": interface["router"],
             "name": interface["name"],
             "description": interface["description"],
-            # TODO: This is a complete hack until we have a proper way to determine
-            # router vendor
-            "vendor": "nokia" if interface["router"].startswith("rt0") else "juniper"
+            "vendor": get_vendor(interface["router"]),
         }
 
     return sorted(
diff --git a/inventory_provider/tasks/worker.py b/inventory_provider/tasks/worker.py
index 82c0699cd5b44e5453e3cec646a776e5f92fcb1f..813af6f0e39db275872535697e318e6aa3a89207 100644
--- a/inventory_provider/tasks/worker.py
+++ b/inventory_provider/tasks/worker.py
@@ -20,6 +20,7 @@ from ncclient.transport import TransportError
 
 from inventory_provider.db import ims_data
 from inventory_provider.db.ims import IMS
+from inventory_provider.gap import Orchestrator
 from inventory_provider.routes.poller import load_error_report_interfaces, load_interfaces_to_poll
 from inventory_provider.tasks.app import app
 from inventory_provider.tasks.common \
@@ -454,14 +455,6 @@ def check_task_status(task_id, parent=None, forget=False):
 
     yield result
 
-
-def get_router_vendors():
-    c = InventoryTask.config["ims"]
-    ds = \
-        IMS(c['api'], c['username'], c['password'], c.get('verify-ssl', False))
-    return {r.lower(): v.lower() for r, v in ims_data.get_router_vendors(ds)}
-
-
 @app.task(base=InventoryTask, bind=True, name='update_entry_point')
 @log_task_entry_and_exit
 def update_entry_point(self):
@@ -476,52 +469,37 @@ def update_entry_point(self):
             warning_callback=self.log_warning
         )
         lab_routers = InventoryTask.config.get('lab-routers', [])
-
-        ims_rv = get_router_vendors()
-
-        def _get_router_vendor(router):
-            return ims_rv.get(router.lower().split('.geant.')[0], 'unknown')
-
-        def _get_lab_router_vendor(router):
-            _rv = ims_rv.get(router.lower().split('.geant.')[0])
-            if not _rv:
-                _rv = ims_rv.get(router.lower().split('.office.')[0],
-                                 'unknown')
-            return _rv
-
-        rv = {r: _get_router_vendor(r) for r in routers}
-        lab_rv = {r: _get_lab_router_vendor(r) for r in lab_routers}
         chord(
             (
                 ims_task.s().on_error(task_error_handler.s()),
                 chord(
-                    (reload_router_config_juniper.s(r) for r, v in rv.items()
+                    (reload_router_config_juniper.s(r) for r, v in routers.items()
                      if v == 'juniper'),
                     empty_task.si('juniper router tasks complete')
                 ),
                 chord(
                     (reload_lab_router_config_juniper.s(r)
-                     for r, v in lab_rv.items() if v == 'juniper'),
+                     for r, v in lab_routers.items() if v == 'juniper'),
                     empty_task.si('juniper lab router tasks complete')
                 ),
                 chord(
-                    (reload_router_config_nokia.s(r) for r, v in rv.items()
+                    (reload_router_config_nokia.s(r) for r, v in routers.items()
                      if v == 'nokia'),
                     empty_task.si('nokia router tasks complete')
                 ),
                 chord(
                     (reload_router_config_nokia.s(r, True)
-                     for r, v in lab_rv.items() if v == 'nokia'),
+                     for r, v in lab_routers.items() if v == 'nokia'),
                     empty_task.si('nokia lab router tasks complete')
                 ),
                 chord(
-                    (reload_router_config_try_all.s(r) for r, v in rv.items()
+                    (reload_router_config_try_all.s(r) for r, v in routers.items()
                      if v == 'unknown'),
                     empty_task.si('unknown router tasks complete')
                 ),
                 chord(
                     (reload_router_config_try_all.s(r, True)
-                     for r, v in lab_rv.items() if v == 'unknown'),
+                     for r, v in lab_routers.items() if v == 'unknown'),
                     empty_task.si('unknown lab router tasks complete')
                 )
             ),
@@ -552,8 +530,7 @@ def retrieve_and_persist_neteng_managed_device_list(
     netdash_equipment = None
     try:
         info_callback('querying netdash for managed routers')
-        netdash_equipment = list(juniper.load_routers_from_netdash(
-            InventoryTask.config['managed-routers']))
+        netdash_equipment = Orchestrator().load_routers_from_orchestrator()
     except Exception as e:
         warning_callback(f'Error retrieving device list: {e}')
 
diff --git a/test/conftest.py b/test/conftest.py
index 47a350147bfd1b244e5742b15db437e891cb2c3b..bd976e63f94394dc9e9207c0583ac5476c72aa95 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -69,7 +69,6 @@ def data_config_filename():
                 "username": "ims_username",
                 "password": "ims_password"
             },
-            "managed-routers": "bogus url",
             "unmanaged-interfaces": [
                 {
                     "address": "99.99.99.99",
@@ -102,7 +101,17 @@ def data_config_filename():
                     "nren": "BAZ",
                     "asn": 1853
                 }
-            ]
+            ],
+            "aai": {
+                "discovery_endpoint_url": "https://smaple.discovery.endpoint",
+                "inventory_provider": {
+                    "client_id": "sample-client-id",
+                    "secret": "sample-secret"
+                }
+            },
+            "orchestrator": {
+                "url": "https://orchestrator.url"
+            }
         }
 
         config['gws-direct'] = read_json_test_data('gws-direct.json')