# Identifying S-Sign Licensing

S-Sign supports two seated licensing models.

Some orgs use only one model. Some orgs manage both at the same time.

Check both sources when the org mixes licensing models:

* Licensing managed inside S-Sign.
* Licensing managed through Salesforce package licensing.

{% hint style="info" %}
Both licensing models can also be reviewed manually in the Salesforce UI.
{% endhint %}

This is useful before a user generates a document or runs an envelope action.

### Option 1: Licensing managed inside S-Sign

Use this when seat assignment is handled by S-Sign.

#### Class and method

Use `SSign.SSLicensesController.getSSignLicensedUsers()`.

This method returns the `User` IDs that currently hold S-Sign seats.

#### Apex example

Run this in **Developer Console** using **Execute Anonymous**.

```apex
List<Id> licensedUserIds = SSign.SSLicensesController.getSSignLicensedUsers();

List<User> licensedUsers = [
    SELECT Id, Name, Email, IsActive
    FROM User
    WHERE Id IN :licensedUserIds
    ORDER BY Name
];

System.debug('Total S-Sign licensed users: ' + licensedUsers.size());

for (User userRecord : licensedUsers) {
    System.debug(
        'Name: ' + userRecord.Name +
        ' | Id: ' + userRecord.Id +
        ' | Email: ' + userRecord.Email +
        ' | Active: ' + userRecord.IsActive
    );
}
```

#### What this check gives you

* The users assigned S-Sign seats.
* The current seat count.
* Each user's active status.

### Option 2: Licensing managed through Salesforce

Use this when S-Sign licensing is assigned through Salesforce package licensing.

#### Salesforce objects to query

* `PackageLicense`
* `UserPackageLicense`

#### Apex example

Run this in **Developer Console** using **Execute Anonymous**.

```apex
List<PackageLicense> packageLicenses = [
    SELECT AllowedLicenses, UsedLicenses
    FROM PackageLicense
    WHERE NamespacePrefix = 'SSIGN'
    LIMIT 1
];

if (packageLicenses.isEmpty()) {
    System.debug('No S-Sign package license was found.');
    return;
}

PackageLicense packageLicense = packageLicenses[0];

System.debug('=== S-Sign license summary ===');

if (packageLicense.AllowedLicenses == -1) {
    System.debug('License type: Site license');
    System.debug('Assigned users: ' + packageLicense.UsedLicenses);
} else {
    System.debug('License type: Seated license');
    System.debug('Seats purchased: ' + packageLicense.AllowedLicenses);
    System.debug('Seats assigned: ' + packageLicense.UsedLicenses);
    System.debug('Seats remaining: ' + (packageLicense.AllowedLicenses - packageLicense.UsedLicenses));
}

List<UserPackageLicense> assignedUsers = [
    SELECT UserId, User.Name, User.Email, User.IsActive
    FROM UserPackageLicense
    WHERE PackageLicense.NamespacePrefix = 'SSIGN'
    ORDER BY User.Name
];

System.debug('--- Assigned user list ---');

for (UserPackageLicense assignedUser : assignedUsers) {
    System.debug(
        'Name: ' + assignedUser.User.Name +
        ' | Id: ' + assignedUser.UserId +
        ' | Email: ' + assignedUser.User.Email +
        ' | Active: ' + assignedUser.User.IsActive
    );
}
```

#### What this check gives you

* Whether the org uses a seated or site license.
* The total seats available in Salesforce.
* The total seats assigned in Salesforce.
* The users assigned the package license.

### Which check should you use?

Use the S-Sign method when seat assignment is managed inside the product.

Use the Salesforce queries when seats are assigned through package licensing.

Some customers manage both models in the same org.

In that setup, do not assume one check is enough. Run both checks and compare the results.

Use the S-Sign method to find users assigned through in-product licensing.

Use the Salesforce queries to find users assigned through package licensing.

Treat these as separate sources of truth. One result does not replace the other.

If you need a complete licensing picture for the org, aggregate both result sets in your own Apex logic.

### Common use case

Use these checks to confirm that the user initiating the process is properly licensed before they:

* generate a document
* prepare an envelope
* send an envelope for signature

### Recommended approach for mixed-license orgs

If the customer manages both licensing models, use this sequence:

1. Query `PackageLicense` and `UserPackageLicense`.
2. Call `SSign.SSLicensesController.getSSignLicensedUsers()`.
3. Compare the two user sets.
4. Report each source separately or merge them for your own audit output.

{% hint style="warning" %}
When both models are used, seat counts can overlap or diverge depending on how the customer assigns access. Do not report totals from one source as the full S-Sign license count unless you have confirmed the org uses only that model.
{% endhint %}

### Where to run these examples

Both examples are intended to run in **Developer Console** using **Execute Anonymous**.


---

# Agent Instructions: 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://help.sdocs.com/developer-hub/s-sign/page-4.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.
