Hex-Rays Blog: IDA Pro Tutorials & Reverse Engineering Tips

IDA 9.5: Managing IDA Licenses Through the API

Written by Bartek Budny | Oct 8, 2026

IDA plugins used to be small scripts that ran inside one analyst's session. Today many are products in their own right: add-ons with their own UI, headless tools built on idat or idalib, and pipelines that run IDA on a license shared by a whole team. All of them depend on what the IDA underneath is licensed for. Is the ARM64 decompiler included? Is Lumina? Is there a usable license at all? And what if you need a different one?

Until now, IDA had no supported way to answer these questions from code, and we kept seeing new workarounds to fill the gap. IDA 9.5 gives you one: a licensing API that answers all of them, and lets you act on the answers.

What’s New

Code built on the IDA API can now read and change IDA's licensing state: inspect the active license, check whether an add-on is available, or switch to a different license entirely. It comes as a License class in the C++ SDK and IDAPython, and as a license module in IDA Domain.

The API covers three jobs.

Reading the License

Start with the basics of the active license: its id, product and edition, whether it is usable, when its activation period ends, and which add-ons it includes.

lic = ida_license.License()
print(f"License {lic.id}: {lic.product} ({lic.edition})")
print(f"Usable: {lic.valid}")
if lic.end:
    print(f"Activation period ends: {datetime.date.fromtimestamp(lic.end)}")
for code in lic.add_ons:
    print(f"Usable add-on: {code}")
License XX-XXXX-XXXX-XX: IDAXXX (ida-XXX)
Usable: True
Activation period ends: 20XX-XX-XX
Usable add-on: HEXX64
Usable add-on: HEXARM64

Checking What You Can Use

This is the part most plugins care about: is the feature I need actually available? has_add_on() answers that, using the same product codes you see in the License Manager, such as HEXARM64 or TEAMS. The answer already accounts for everything: whether the license is still valid, whether the add-on's own period has run out, and, for a floating license, whether this IDA currently holds a seat. One question, one yes or no.

Python>lic.valid

True
Python>lic.has_add_on("HEXX64")

True
Python>lic.decompiler_available

True
Python>lic.has_add_on("TEAMS")

False

For the most common question there is a shortcut: decompiler_available tells you whether the open database can be decompiled at all, whatever its architecture.

Switching Licenses

You can also change the license source at run time, pointing IDA at a license file or a license server, and activate any license that source offers.

def checkout_with(add_on):
    lic = ida_license.License()
    if lic.has_add_on(add_on):
        return True
    for lid in lic.source_ids:
        if lid != lic.id and lic.checkout(lid) and lic.has_add_on(add_on):
            return True
    return False

In short, everything the License Manager dialog shows and does is now available from code.

The full API will be documented at  docs.hex-rays.com at release time, and the SDK ships two complete examples: src/plugins/licinfo/licinfo.cpp and src/plugins/idapython/examples/misc/print_license_info.py.

Why It Matters

With the license state fully scriptable, your tools can react to it instead of guessing. That matters most for plugins with several features, headless analysis scripts and shared automation.

Plugins can offer only what the license supports, instead of failing when a user reaches for it:

lic = ida_license.License()
if lic.has_add_on("TEAMS"):
    ida_kernwin.register_action(lumina_related_action)

Headless scripts can check their requirements up front and fail with a clear message before doing any work:

lic = ida_license.License()
if not lic.valid:
    raise SystemExit("no usable IDA license")
if not lic.has_add_on("HEXX64"):
    raise SystemExit("the x64 decompiler is not part of this license")

Automated pipelines can manage licenses properly, without workarounds. Picture a pool of floating licenses shared by several workers, where each worker finds a license with the add-on it needs, uses it, and hands it back:

# search through available licenses in the pool and find one that has the required add-on
def checkout_with(add_on):
    lic = ida_license.License()
    if lic.has_add_on(add_on):
        return True
    for lid in lic.source_ids:
        if lid != lic.id and lic.checkout(lid) and lic.has_add_on(add_on):
            return True
    return Falselic = ida_license.License()
if not lic.set_server("licsrv.example.com", 65434, True): # True: use TLS raise SystemExit("license server unreachable or no seat available") try: if not checkout_with(lic, "HEXARM64"): raise SystemExit("no license with the ARM64 decompiler is free right now") # analysis ... finally: lic.checkin() # immediately return the license to make it available for the rest of the group

You could even add a check that warns you before a license expires. The point is simple: anything license related can now happen in code, the same code that does the actual work. We hope this removes friction for everyone building on the IDA API, and retires the hacks people have relied on until now.

Behind the Scenes

People were rebuilding parts of this long before IDA offered it. Not for fun: a plugin has to decide what it can offer, and a headless tool has to know whether it can run at all. Some hacks people resorted to:

  • conflating the return value of init_hexrays_plugin() with "is the decompiler licensed"
  • searching for idaXXX_*.hexlic in the user directory to guess the capabilities of the IDA install based on the edition of the licenses

And our favorite:

  • reverse engineering libida's license manager (shoutout)

Each of those can now be properly queried from IDA with one call: has_add_on("HEXX64") / decompiler_available, edition, valid.

If that was you, good news: you can go back to reverse engineering your samples instead of IDA. :)

Where You’ll Find It

The licensing API is available in the IDA 9.5 C++ SDK, in IDAPython, and in IDA Domain.

Try It Out

IDA 9.5 is currently in beta and available from the customer portal at https://my.hex-rays.com. If you maintain a plugin or pipeline that works around licensing today, we would love to hear how the new API fits. Share your feedback on the community forum or through support.