SketchUp C API: SUExtensionLicense

Any vendors here know if SketchUp C API works properly and is reliable to use?

I’m calling SUExtensionLicenseState and I always get very weird returns in my tests. I generated test licenses from extension warehouse and i can’t get it to return anything besides SUExtensionLicenseState_Licensed and SUExtensionLicenseState_NotLicensed. Super weird.

I’m trying to understand an intermittent Extension Warehouse licensing issue that affects some users who have purchased my extensions.

Every now and then I get messages from users saying that one of my extensions reports them as unlicensed, even though they say they purchased it and their Extension Warehouse / account state appears to show the extension as active. In these cases, the extension itself is installed correctly and the native runtime/DLL loads correctly, but the license validation result returned to the extension says the user is not licensed.

For context, my extension uses the SketchUp C API:

SUGetExtensionLicense(extension_id, &license)

where extension_id is the Extension Warehouse UUID for the extension.

I added extra diagnostics and now log:

  • SUResult returned by SUGetExtensionLicense
  • license.is_licensed
  • license.state
  • license.days_remaining
  • license.error_description
  • my own mapped status/result

In the failing cases, the important situation is roughly:

  • The extension is installed correctly.
  • The native runtime loads correctly.
  • The user says the extension is purchased/active in Extension Warehouse.
  • But the licensing API can still return a result that maps to NotLicensed.

I have also done some testing myself and I’m a bit confused by the caching/refresh behavior. For example, after logging out of SketchUp, I can sometimes still get a licensed result. I’m also not fully sure how Extension Warehouse test licenses behave, because test licenses I assign seem to keep returning as licensed, and I don’t know whether that is because they are cached locally, tied to the current signed-in account, or handled differently from production purchases/trials.

So I’m trying to understand the intended lifecycle and best practices before assuming this is a bug.

My current understanding from the C API docs is:

  • SUGetExtensionLicense returning SU_ERROR_NONE only means the API call succeeded.
  • SUExtensionLicense::is_licensed is the main allow/deny flag.
  • SUExtensionLicense::state is additional status detail.
  • SUExtensionLicense::days_remaining is informational/debug display only.
  • SUExtensionLicense::error_description is for debugging only and should not be parsed for behavior.

In my extension, the license can be checked when the user interacts with the extension, for example when opening the UI or running a command/generation action. Is that the recommended pattern? Or is it also acceptable to also check during extension load/startup? (I do both)

The documentation for SketchUp 2025+ says SUGetExtensionLicense can automatically try to fetch a license from Extension Warehouse if the license is missing on the current device, but that automatic fetching is skipped during SketchUp startup for performance reasons. Does that mean extension-load/startup checks should be avoided, and license checks should only happen after explicit user interaction?

I would appreciate clarification on the technical side:

  1. Should extensions always use SUExtensionLicense::is_licensed as the authoritative allow/deny value, and treat state/days_remaining as informational?

  2. Is Extension Warehouse license data cached locally by SketchUp?
    If yes, is that cache per SketchUp version, per operating system user profile, per Trimble account, or shared across installed SketchUp versions?

  3. What is expected after logout/login or switching Trimble accounts?
    If a user logs out, is it expected that the C API may still return a licensed result because of local/offline cache?

  4. What is the recommended way for a user to force a license refresh?
    Restart SketchUp, sign out/in, press “Update License” in Extension Manager, reinstall from Extension Warehouse, or something else?

  5. How are Extension Warehouse test licenses handled?
    Do test licenses have the same caching and refresh behavior as real purchases/trials?

  6. In SketchUp 2025+, when SUGetExtensionLicense attempts to automatically fetch a missing license from Extension Warehouse, what are the exact conditions for that fetch?
    Does it require the user to be signed in, online, and not during startup? Are there other conditions?

  7. Are there known cases where Extension Manager / Extension Warehouse account state shows the extension as active, but SUGetExtensionLicense still returns NotLicensed until the user refreshes, reinstalls, or signs in again?

I would also appreciate confirmation on the enum and ABI expectations. The SDK header defines:

enum SUExtensionLicenseState {
SUExtensionLicenseState_Licensed,
SUExtensionLicenseState_Expired,
SUExtensionLicenseState_Trial,
SUExtensionLicenseState_TrialExpired,
SUExtensionLicenseState_NotLicensed
};

Since the values are not explicitly assigned, I assume the C/C++ numeric mapping is:

0 = Licensed
1 = Expired
2 = Trial
3 = TrialExpired
4 = NotLicensed

Is that correct and stable across supported SketchUp versions?

Also, is the expected struct layout exactly:

bool is_licensed;
SUExtensionLicenseState state;
size_t days_remaining;
char error_description[512];

I’m asking because I’m calling the C API from a native runtime loaded by a Ruby extension, so I want to make sure I’m not accidentally relying on an ABI assumption that could differ between SDK/runtime versions or compilers.

I want my extensions to follow the intended API behavior and give users the right troubleshooting steps when Extension Warehouse/account state and the local API result appear to disagree.

If anyone from Trimble or anyone with deeper Extension Warehouse licensing experience can clarify this, I’d really appreciate it.

@CraigTrickett

Could you please have someone from the team help me with this?

I’m getting emails from frustrated users saying that their licenses are invalid. I can’t tell if this is a problem in my implementation or something stale/inconsistent in the Extension Warehouse licensing system, so I’d really appreciate someone from Trimble taking a look or explaining the expected behavior.

@ene_su Perhaps another article on Licensing for the Developer Learn pages?

As of right now, there seems to be an Extension Warehouse bug with license generation. (EW-4072)

As for the C API, it’s not really my area of expertise. You can try doing similar licensing checks from the Ruby API in the Ruby Console to see if there are C-API specific errors.

As for how the licensing works in general, when you install an extension from EW inside of SketchUp, SketchUp fetches a license and adds it to the local license file. For this to work, you need to be signed in. Then the license is cached locally and works offline too, possibly also when signed out or if another user signs in, but I’m not sure.

You can make a “dummy” license check at load time to tell SketchUp “hey, this is a paid extension”. Then SketchUp can show the notification toast if the license is missing. The main license check is typically done as you interact with the extension, like clicking its toolbar buttons. That’s also when the extension is expected to show an error message if it’s not licensed.

With SketchUp 2025, SketchUp started fetching licenses from EW automatically when a license check is done and there is no local license. This prevents you from having to reinstall or find the hidden Update License button in Extension Manager if you purchase a license after a trial has expired, as well as getting extensions to be licensed when migrating between SU versions.

The missing license not fetching at startup is not something you need to worry about as an API user. It’s to prevent SketchUp from bogging down making a bunch of server requests. As an API user, you don’t use the output of this startup license check anyway. It’s just a way of stating it’s a paid extension.

Correct. In the C API, the return value generally tells if the function itself was successful.

Yes. Make the call and check this state when the user interacts with the extension to either allow such interaction or display an error message.

Yes. This can be used to customize the error message, e.g. saying “Your trial has expired” or “License is missign” before tellign them to go to Extension Warehouse to purchase a license.

I’m not sure how this is intended to be used. Maybe for messaging how many days are left in an extension About or Licensing window. However I’m not sure what value it shows for perpetual licenses and I would avoid displaying it anywhere without first confirming it’s a temporary/timed license. Maybe state gives you that information but I’m not sure the API has been updated since termed licenses were added. I would not use this to test if the extension is allowed to run.

Yup, for writing to log files and the like. I would not display it to the end user in the UI as it has a technical license code. It’s also not localized. Parsing it would be a more complicated and less stable way to get the value already present in state.

Yes. Make the API call and check this value when the extension is interacted with, like clicking its toolbar button.

Yes, by user and SketchUp version. On the Extension Warehouse submission page there is a button you can press to generate your own license and instructions where the file you need to place it in is located.

I think the license just keeps working but I’m not sure.

For end users, this should happen automatically in SU 2025 and later. As a develoepr you need to manually place the license into the license file.

Completely manual. You click a button on the website, copy a string and place it in a lcoal file.

No other conditions that I’m aware of.

Extension Warehouse shows whether you have an entitlement. You may still be missing a local license if there’s networking issues, if you are not signed in, if the extension has not used the licensing API to check its licensing state, or if the extension only did the license check at load time and not later when the user tried interatcing with the extension.

Extension Manager is unaware an extension is supposed to be paid and fails to display license error messaging unless the extension has a licensing check. If the extension has made a license check, other than one at load time, Extension Manager should show the same licensing state as the licensing API returns.

The issue that me and Christina were seeing yesterday is not happening now. I don’t see any specific fix that was done, but could you ask one of your users who had a problem, to try again now? It may need them to uninstall and reinstall the extension, to get a fresh attempt at getting a good license.

From what they told me, they tried everything SketchUp support recommended them, including reinstalling the extension, signing out, and the other troubleshooting steps and it didn’t help, and then it started working normally again today.

I was convinced the issue was related to how I was handling the C API, but based on what ene_su wrote, the code appears to be fine on my end.

We don’t know exactly when something was changed at our end. Anything they tried yesterday most likely failed. Could any one of them try again today?

Yeah, like I said everything appears to be working normally for them since today.

Sounds good then! Thanks.