> ## Documentation Index
> Fetch the complete documentation index at: https://help.cryptolens.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Keys

> This method will return a list of keys for a given product. Please keep in mind that although each license key will be of the License Key type, the fields related to...

This method will return a list of keys for a given [product](https://app.cryptolens.io/Feature/Product). Please keep in mind that although each license key will be of the
[License Key](/api-reference/generated/model/LicenseKey) type, the fields related to signing operations will be left empty. Instead, if you want to
get a signed license key (for example, to achieve [offline key activation](https://help.cryptolens.io/examples/offline-verification)), please use
the [Activation](/api-reference/generated/Activate) instead.

This method is accessed by [https://api.cryptolens.io/api/product/GetKeys](https://api.cryptolens.io/api/product/GetKeys)

### Parameters

| **Parameter** | **Description** | **Remarks** |
| - | - | - |
| ProductId | the product id (=\*\*\[ProductId] \*\*) | required |
| Page | If there are more than 100 keys, only 99 will be returned on the first page. in order to obtain the remaining licenses, increment this parameter by 1. | optional. 1 by default. |
| [OrderBy](/api-reference/generated/GetKeys#remarks) | Specifies the way to order the result. More information is found in [Remarks](/api-reference/generated/GetKeys#remarks) | optional. "ID ascending" by default. |
| [SearchQuery](/api-reference/generated/GetKeys#remarks) | Sorts the result so that only the license keys that satisfy the criterion will be displayed. More information. is found in [Remarks](/api-reference/generated/GetKeys#remarks) | optional. empty string by default. |
| GlobalId | If you need to find a specific license key, you can instead set this parameter to its ID, to get a faster response. | optional. 0 by default. |
| v | Method version. | optional. by default, it's 1. |

### Results

| **Parameter** | **Description** | **Remarks** |
| - | - | - |
| LicenseKeys | A list of [License Key](/api-reference/generated/model/LicenseKey) objects. | returned if successful |
| Returned | The number of licenses returned in the request, eg. size of the returned list. | always returned |
| Total | The total number of keys available that satisfy the condition. For example, if *search query* is empty, the **total** is the number of license keys in the entire product. Otherwise, it's the number of results of that query. By default, only 99 license keys will be returned in a single request. There may still be more license keys, which are obtained by increasing the **Page** parameter. | always returned |
| PageCount | Since not all keys will be returned if the number of them is more than 99, you can increment the **Page** parameter to list the remaining ones. This value is the limit of the number of pages available (this makes it easier to iterate through all the keys). | always returned |
| Result | This is either **0**(=success) or **1**(=error). | always returned |
| Message | The message that provides additional information about the result. If it's a successful result, either **null** or the **new key** (if using SKGL) will be returned. Otherwise, in case of an error, a short message will be returned describing the error. | always returned. |

### Example results

```text theme={null}
{"licenseKey":[{"productId":1234,"id":1,"key":"AAAAA-AAAAA-AAAAA-AAAAA","created":"2015-08-27T00:00:00","expires":"2018-11-03T00:00:00","period":1023,"f1":true,"f2":false,"f3":false,"f4":false,"f5":false,"f6":false,"f7":false,"f8":false,"notes":"this key is used as an example in one of the test cases.","block":false,"globalId":24963,"customer":{"id":3,"name":"Bob","email":"bob@example.com","companyName":"SKM","created":"2015-09-04T16:11:14.453"},"activatedMachines":[{"mid":"5632812","ip":"10.1.1.1","time":"2016-03-25T18:56:34.647"},{"mid":"7632812","ip":"10.1.1.2","time":"2016-04-06T15:05:35.733"},{"mid":"85256631","ip":"10.1.1.5","time":"2016-04-07T22:18:26.673"}],"trialActivation":false,"maxNoOfMachines":10,"allowedMachines":"","dataObjects":[],"signDate":"2016-04-11T09:45:06","signature":null}],"returned":99,"total":106,"pageCount":2,"result":0,"message":""}
```

### Remarks

* The fields *SignDate* and *Signature* will be empty. Please use [Activation](/api-reference/generated/Activate) in order to get each license signed.
* The *order by* field has the following structure: **fieldName \[ascending|descending]**. For example, If you want to order by the feature field 1 (F1), you should use **F1**. If you want it in descending order, please add the **descending** keywords right after the field, eg. **F1 descending**. The **ascending** keyword is the default, hence optional.
* The *search query* field accepts the same queries as the search box on the product page. You can read about the format [here](https://help.cryptolens.io/web-interface/linq-search-product).
* The **key lock** does not have any effect on this method, eg. you will still be able to retrieve all keys even if the key lock is set to a certain key.

### Errors

| **Error** |
| - |
| Access denied. |
| The input parameters were incorrect. |
| Could not find the product. |
| The search query causes problems. Please check that it follows the standard: [https://help.cryptolens.io/web-interface/linq-search-product](https://help.cryptolens.io/web-interface/linq-search-product) |
| The 'order by' field causes problems. Please check the remarks section for this method. |

### FAQ

#### How do I find licenses without a customer?

Set `SearchQuery` to `customer.id=-1`. You can enter the same query in the product page's search box:

```text theme={null}
customer.id=-1
```

These search results represent an absent customer with a customer object whose `Id` is `-1`.
Use this ID check rather than a null check. API calls require `ProductId` and a token granting `GetKeys`
with access to that product.

#### Can I find a license using its machine ID?

Yes. To find a registered activation, set `SearchQuery` to `ActivatedMachines.Count(it.Mid="machine code") > 0`.
Replace `machine code` with the device's actual machine code. The same expression works in the product page's search box.

| **What to find** | **SearchQuery or dashboard query** |
| - | - |
| A device in the registered activation list | `ActivatedMachines.Count(it.Mid="machine code") > 0` |
| Text in the configured machine whitelist | `allowedmachines.contains("machine code")` |

A whitelisted device may never have activated the license. The activated-machine query searches stored node-locked registrations;
it does not measure current floating-seat usage. API calls require the `GetKeys` permission and `ProductId`.

#### How many licenses were created this year?

Filter by `Created`, then read `Total` (`total` in JSON).
For the **2026 UTC calendar year**, use an inclusive start and exclusive end:

```text theme={null}
created >= DateTime(2026,1,1) and created < DateTime(2027,1,1)
```

Replace both years for the year you want to count. In the dashboard, enter that expression in the product search box.
To obtain the count through the API, use this POST request. Replace `YOUR_GETKEYS_ACCESS_TOKEN` with a token granting
`GetKeys` and access to the product, and `YOUR_PRODUCT_ID` with the integer product ID.

```text theme={null}
curl -X POST https://api.cryptolens.io/api/product/GetKeys \
  --data-urlencode "token=YOUR_GETKEYS_ACCESS_TOKEN" \
  --data-urlencode "ProductId=YOUR_PRODUCT_ID" \
  --data-urlencode "Page=1" \
  --data-urlencode "SearchQuery=created >= DateTime(2026,1,1) and created < DateTime(2027,1,1)"
```

Example response excerpt; other fields are omitted:

```text theme={null}
{ "returned": 99, "total": 237, "pageCount": 3, "result": 0 }
```

Here, the answer is **237**. `Returned` and the returned license array describe only the current page;
counting that page would give 99 and undercount the matches. `Total` already counts all matches for the query in that product,
so you do not need to fetch every page just to count. Check `result` before using the count.
For an account-wide count, query each relevant product and sum its filtered `Total` once.
