{"schemaVersion":1,"generated":"2026-10-09T21:41:41.280Z","origin":"https://docs.babelfor.net","pages":[{"path":"index","title":"Babel Documentation","description":"Welcome to the official documentation for Babel software protection and licensing solutions. Here you will find guides, API references and examples for protecting your .NET applications and adding…","section":"home","url":"https://docs.babelfor.net/","md":"/md/index.md","headings":["Products","Getting Started","Licensing API","Key Features","Additional Resources"],"sha256":"f71f801bb83429c31e340d49055bdf7bea608cd4fff38c2f7dfcbc76f6fe2cb4"},{"path":"ai-documentation","title":"Using the Documentation with AI","description":"Give an AI assistant the Babel documentation as plain Markdown, from the web or through the Babel Desktop MCP server","section":"home","url":"https://docs.babelfor.net/ai-documentation","md":"/md/ai-documentation.md","headings":["Files for AI Assistants","Using the Files with Claude, ChatGPT and Other Assistants","Using the Documentation from Babel Desktop"],"sha256":"5daf71a7a1a5e7e65082a206e251f7bce22298cc04ff0063d15d53146cb29da4"},{"path":"obfuscator","title":"Babel Obfuscator","description":"Babel Obfuscator protects .NET assemblies against reverse engineering, from .NET Framework 2.0 to .NET 10, on desktop, mobile, web and server targets. It renames, encrypts and restructures compiled…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator","md":"/md/obfuscator.md","headings":["Why Obfuscate .NET Code","What's New in 12.0","The Ultimate Badge","Protection Features","Built for AI-Assisted Workflows","Platforms and Frameworks","How You Run It","Next Steps"],"sha256":"329cef77f799391115cec9115ec452506cace7b0c6e491ee4176aed60db2af21"},{"path":"obfuscator/introduction","title":"Introduction","description":"Babel Obfuscator protects .NET assemblies against reverse engineering, from .NET Framework 2.0 to .NET 10, on desktop, mobile, web and server targets. It renames, encrypts and restructures compiled…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/introduction","md":"/md/obfuscator/introduction.md","headings":["Why Obfuscate .NET Code","What's New in 12.0","The Ultimate Badge","Protection Features","Built for AI-Assisted Workflows","Platforms and Frameworks","How You Run It","Next Steps"],"sha256":"eb559cf40707881e820c2598e076a32a58abc5a1b900a904bb23476474016272"},{"path":"obfuscator/introduction/general-features","title":"General Features","description":"What Babel Obfuscator does, where it runs, and what it protects. Each section links to the page that shows how to configure the feature.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/introduction/general-features","md":"/md/obfuscator/introduction/general-features.md","headings":["Protects Your Code and Intellectual Property Against Reverse Engineering","Compatible With the Whole .NET Ecosystem","Runs on Windows, macOS and Linux (Ultimate)","Fully Managed Code Encryption and Virtualization","Hardened Against Automated Deobfuscation (Ultimate)","Detects Debugging and Tampering, on Desktop and Mobile","Simplifies Deployment by Merging and Embedding Dependencies","Optimizes Code and Metadata","Integrated With Visual Studio, MSBuild, NuGet and Build Servers","Available as a Command Line Tool, With an AI-Friendly Mode","Operated by AI Assistants Through MCP","Decodes Obfuscated Stack Traces","FIPS-Ready","Extensible With Rules, Attributes and Plugins"],"sha256":"746e183eba91ea1a08525420bee21e18e76ae5702ecbbd023a358f0d46ef0292"},{"path":"obfuscator/getting-started","title":"Getting Started","description":"To get started with Babel Obfuscator, please follow the installation instructions.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/getting-started","md":"/md/obfuscator/getting-started.md","headings":[],"sha256":"6e461f1316cb567a01bd59dacb40b40c183921adced997ac5089d18e48409773"},{"path":"obfuscator/getting-started/install","title":"Install","description":"Babel Obfuscator is available as the Babel Desktop application for Windows, macOS and Linux, as zip packages with the command line tool and the MSBuild task, and as NuGet packages and a dotnet CLI…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/getting-started/install","md":"/md/obfuscator/getting-started/install.md","headings":["Babel Desktop","Command Line and MSBuild Task (zip packages)","Babel NuGet Packages","Create a Local NuGet Feed Using dotnet","Create a Local NuGet Feed Using Visual Studio","Installing Babel CLI dotnet Tool","Update Babel CLI dotnet Tool","Uninstalling Babel CLI dotnet Tool"],"sha256":"75551d56dc86c052f540f8c165d001ff48cde68a0ff3c2070998bb69cb5d327a"},{"path":"obfuscator/getting-started/product-activation","title":"Product Activation","description":"Babel Obfuscator can be used in demo mode without requiring a license. However, during the trial period, users can only utilize the obfuscation renaming feature. It's important to note that…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/getting-started/product-activation","md":"/md/obfuscator/getting-started/product-activation.md","headings":["License File","Activation Key","Floating License Usage","Troubleshooting License File Issues"],"sha256":"a607061f5f255cde4adf1ed20c76821d565a38bc1c2df5b91a6f082cde0b74b6"},{"path":"obfuscator/command-line","title":"Command Line","description":"Babel Obfuscator provides a command line tool on Windows, Mac and Linux. This paragraph will describe how to use Babel Obfuscator from the command line.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/command-line","md":"/md/obfuscator/command-line.md","headings":[],"sha256":"40b8b4bb26ec86826cff067a7db971f052b226508a93f8c34663bc61044f0397"},{"path":"obfuscator/command-line/reference","title":"Command Line Reference","description":"The Babel Obfuscator command line tool accepts different options. A double hyphen character prefixes each option. The following section will describe each option you can enter at the command line.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/command-line/reference","md":"/md/obfuscator/command-line/reference.md","headings":["Miscellaneous","Input Files","Output Files","Plugins","Merge and Embed Assemblies","Renaming","Control Flow Obfuscation","Encryption and Protection","Code Generation"],"sha256":"c26bb675383f2d7c4765192184338a3d0a562fede78b9c6ef4b6bcef084f269f"},{"path":"obfuscator/command-line/ai-friendly-mode","title":"AI-Friendly CLI Mode","description":"Starting with Babel Obfuscator 11.7.0, the command line tool can emit a structured, machine-readable output stream that is well suited to CI pipelines, build orchestrators and AI/agent integrations.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/command-line/ai-friendly-mode","md":"/md/obfuscator/command-line/ai-friendly-mode.md","headings":["Flags","Schema: babel.cli.v1","Machine-readable --help","Machine-readable --version","Backward compatibility"],"sha256":"4f6f1cda5c1e9650f6abbf0a2f14182caeb06445b6d989debaf8b92b514cd806"},{"path":"obfuscator/msbuild-task","title":"MSBuild Task","description":"Babel Obfuscator can be easily integrated with MSBuild to deploy obfuscation in your build process.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/msbuild-task","md":"/md/obfuscator/msbuild-task.md","headings":["AfterBuild and Compile Targets","Configuring Babel Task","Build Performance in Visual Studio with Code Analyzers","Babel Task And Babel Obfuscator NuGet Package"],"sha256":"645962beff6c4439a6a4b054a2bc3ebd65c2b8afe8f842c5d01925cd8505b212"},{"path":"obfuscator/msbuild-task/babel-task-reference","title":"Babel Task Reference","description":"Every attribute of the Babel MSBuild task, grouped by feature, with the command line option each attribute maps to.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/msbuild-task/babel-task-reference","md":"/md/obfuscator/msbuild-task/babel-task-reference.md","headings":["Miscellaneous","Input Files","Output Files","Plugins","Merge and Embed","Renaming","Control Flow Obfuscation","Encryption and Protection","Optimizations","Code Generation","Packages","Task Outputs","Example"],"sha256":"141132ae9c104a943d47bb910f43a8967c9edc7b976edb80f24f881a5a1e3a5a"},{"path":"obfuscator/msbuild-task/customizing-intellisense","title":"Customizing IntelliSense","description":"The MSBuild Babel task attributes are defined in the schema file Babel.Build.xsd, shipped next to Babel.Build.dll in the MSBuild folder of the babel_net* zip packages. Registering this schema with…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/msbuild-task/customizing-intellisense","md":"/md/obfuscator/msbuild-task/customizing-intellisense.md","headings":["Visual Studio","Other Editors"],"sha256":"070718971bc8d9c0d0d0f27541b944f5bcc044eece4457272c98347fc4299bb1"},{"path":"obfuscator/nuget-package","title":"NuGet Package (Ultimate)","description":"The Babel Obfuscator NuGet packages let you run Babel on any build machine or CI server that has the .NET SDK, on Windows, Linux and macOS, without installing the product.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/nuget-package","md":"/md/obfuscator/nuget-package.md","headings":["Why the Package Instead of the Babel Task","Requirements","Quick Start","In This Section","Examples"],"sha256":"b34c4056925360a30312db5b7b1cd4fadeef31b0b2e2a08708879b4fc3b1cc30"},{"path":"obfuscator/nuget-package/setup","title":"Package Setup","description":"How to make the Babel.Obfuscator package available to your builds, reference it from a project, activate the license and verify the first obfuscated build.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/nuget-package/setup","md":"/md/obfuscator/nuget-package/setup.md","headings":["Hosting the Package","Adding the Package Reference","Activating the License","Building and Verifying","Disabling Obfuscation for a Configuration","Updating the Package"],"sha256":"7cf1eff6d17126246dcfd3cefb747c8a7a2c7700886921fed2495873af6dcc0e"},{"path":"obfuscator/nuget-package/configuration","title":"Configuring Obfuscation","description":"With the package installed, every Babel Obfuscator feature is configured with MSBuild properties and items in the project file. This page shows the settings you will use most, feature by feature.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/nuget-package/configuration","md":"/md/obfuscator/nuget-package/configuration.md","headings":["How Settings Reach Babel","Defaults Applied by the Package","Obfuscation Rules","String Encryption","Control Flow Obfuscation","Code Encryption","Value, Resource and Call Protection","Tampering Detection and Anti-Debugging","Managed AES for FIPS Hosts","Merging and Embedding Assemblies","Map Files and Cross-Assembly Renaming","Optimizations","Plugins","Logging and Diagnostics"],"sha256":"71b9b672e5960ff99fb62d2905955f26227c44f0b05d7ce95bb55878af099d68"},{"path":"obfuscator/nuget-package/build-pipeline","title":"Build Pipeline","description":"Where the package runs Babel inside the MSBuild pipeline, how to move that step, the targets you can hook, what happens on publish, and how the build tools are selected.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/nuget-package/build-pipeline","md":"/md/obfuscator/nuget-package/build-pipeline.md","headings":["Where Obfuscation Runs","Moving the Obfuscation Step","Target Sequence and Extension Points","Publishing","Selecting the Build Tools","Build Servers"],"sha256":"9127e0c582131503544ce75ddbb54beea84c9dbf5b747511a7092e9033677d8b"},{"path":"obfuscator/nuget-package/babel-tool","title":"Babel Obfuscator Tool (Ultimate)","description":"Babel.Obfuscator.Tool packages the babel command line as a dotnet tool, so you can run Babel Obfuscator from a terminal or a script on Windows, Linux and macOS with nothing but the .NET SDK installed.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/nuget-package/babel-tool","md":"/md/obfuscator/nuget-package/babel-tool.md","headings":["What the Package Contains","When to Use the Tool","Installing the Tool","Licensing the Tool","Using the Tool","FIPS-Enabled Hosts","Troubleshooting"],"sha256":"87763a0be75337c3c6e730bc02b86b57e5fbb7a5a5208232d174e4206668c39b"},{"path":"obfuscator/nuget-package/reference","title":"Package Reference","description":"Every MSBuild property, item and target defined by the Babel.Obfuscator package, and the mapping between the package properties and the attributes of the Babel task.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/nuget-package/reference","md":"/md/obfuscator/nuget-package/reference.md","headings":["Package Properties","Package Items","Targets","Property Mapping","Setting the String Encryption Algorithm"],"sha256":"78a9f4e0867e986de13adb9bb9d0c0aba95b6c1834639ae3f120e77a857d3714"},{"path":"obfuscator/obfuscation-rules","title":"Obfuscation Rules","description":"Babel Obfuscator can perform a series of tasks according to a set of pre-defined rules (Agent), chosen to avoid some common issues introduced by obfuscation, which might otherwise break the resulting…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/obfuscation-rules","md":"/md/obfuscator/obfuscation-rules.md","headings":[],"sha256":"d2ba2a7a328fe3323cfbfd8e81f40def7486a271be8a9c0f0a7cd31151eb8894"},{"path":"obfuscator/obfuscation-rules/xml-rules","title":"XML Rules","description":"In addition to options specified on the command line or through the MSBuild Babel task, Babel Obfuscator can be controlled and configured using rules defined in external XML files. These XML rules…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/obfuscation-rules/xml-rules","md":"/md/obfuscator/obfuscation-rules/xml-rules.md","headings":["Rules Files","Rules Element","Rule Element","Configuring Rules"],"sha256":"ed00a3d039795204ed1ce5554cc83c24b680636d267b96292f5081cd2df72c9a"},{"path":"obfuscator/obfuscation-rules/xml-rules/example-rules","title":"Example Rules","description":"To tailor the Babel Obfuscator's obfuscation process, users can craft their own XML rules. These guidelines dictate how the obfuscator interacts with particular classes, methods, and properties…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/obfuscation-rules/xml-rules/example-rules","md":"/md/obfuscator/obfuscation-rules/xml-rules/example-rules.md","headings":["Disable Class Renaming","Compiled Generated Code","Anonymous Types","Using Dynamic Proxy Calls Filters","Controlling Obfuscation Agent"],"sha256":"ae77af4b2ce29511455cd824ee3cb1baa84c959e527bf10d6678f3e5816fa5dc"},{"path":"obfuscator/obfuscation-rules/custom-attributes","title":"Custom Attributes","description":"Babel supports declarative obfuscation using the custom attributes System.Reflection.ObfuscationAttribute and System.Reflection.ObfuscateAssemblyAttribute provided by the .NET Framework and .NET.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/obfuscation-rules/custom-attributes","md":"/md/obfuscator/obfuscation-rules/custom-attributes.md","headings":["The ObfuscateAssembly Attribute","The Obfuscation Attribute"],"sha256":"2bc58d660caf2c45455a506221e6b6175d098044700fb4784944be6789b9f00b"},{"path":"obfuscator/obfuscation-rules/obfuscation-agent","title":"Obfuscation Agent","description":"During the obfuscation process, Babel can perform a series of tasks based on a set of pre-defined rules, known as the Obfuscation Agent.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/obfuscation-rules/obfuscation-agent","md":"/md/obfuscator/obfuscation-rules/obfuscation-agent.md","headings":["Overriding Agent Rules"],"sha256":"0ae2e12e6b91d8f88ab0918787caf63b6d69c9a7dc2e402750269c32d0704b3c"},{"path":"obfuscator/merge-and-embed","title":"Merge and Embed","description":"Babel Obfuscator provides the capability to merge and embed multiple .NET assemblies into a single target assembly. By merging and embedding the required assemblies into a single file, it simplifies…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/merge-and-embed","md":"/md/obfuscator/merge-and-embed.md","headings":[],"sha256":"ec95934132879a9038caffc47695524c9f99520ceb895d90b8e192bac927c9eb"},{"path":"obfuscator/merge-and-embed/assembly-merging","title":"Assembly Merging","description":"You can merge assemblies with the babel command line tool, the MSBuild Babel task, or Babel Desktop.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/merge-and-embed/assembly-merging","md":"/md/obfuscator/merge-and-embed/assembly-merging.md","headings":["Merging From Command Line","Merging From MSBuild Babel Task","Merging From Babel Desktop"],"sha256":"4ea20480c780612f0ee3bc556afbca5c5dd907c242aa6df64452f8d3d0592712"},{"path":"obfuscator/merge-and-embed/assembly-embedding","title":"Assembly Embedding","description":"Babel Obfuscator provides a feature to embed multiple assemblies into the main application, which can reduce the overall size of the deployed assembly. When embedding assemblies with Babel…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/merge-and-embed/assembly-embedding","md":"/md/obfuscator/merge-and-embed/assembly-embedding.md","headings":["Embedding From Command Line","Embedding From MSBuild Babel Task","Embedding From Babel Desktop"],"sha256":"507c7d7072bdb885210b44f4bc6bf2dc7913944e3fb17e94325d2ea5f8a6a7d9"},{"path":"obfuscator/symbols-renaming","title":"Symbols Renaming","description":"Babel Obfuscator can rename namespaces, types, methods, properties, events, and fields, making reverse engineering challenging. By default, it uses ASCII for renaming, but you can opt for Unicode for…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/symbols-renaming","md":"/md/obfuscator/symbols-renaming.md","headings":["Configuring Symbols Renaming","Name Prefix","Name Length","Unicode Character Set","Flatten Namespaces","Overloaded Renaming","Virtual Functions","Renaming Local Variables"],"sha256":"8334fb2fe5bad7c8738f42bdcafacc440beaed7f1ec5211bf4d4073e8e12ac06"},{"path":"obfuscator/symbols-renaming/cross-assembly-renaming","title":"Cross Assembly Renaming","description":"During the obfuscation process, Babel Obfuscator renames all the symbols that are not externally visible to the assembly, which includes private and internal symbols. This means that Babel will…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/symbols-renaming/cross-assembly-renaming","md":"/md/obfuscator/symbols-renaming/cross-assembly-renaming.md","headings":["Setup Cross Assembly Renaming","Setup From MSBuild Task","Setup From Babel Desktop"],"sha256":"083c7205e14e8f62f2b228845b206c95228974db817712cf0f607f02ef4c2134"},{"path":"obfuscator/symbols-renaming/decoding-stack-traces","title":"Decoding Stack Traces","description":"Obfuscating an application provides a layer of protection for intellectual property, offering a competitive advantage by making reverse engineering more difficult. However, this added security…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/symbols-renaming/decoding-stack-traces","md":"/md/obfuscator/symbols-renaming/decoding-stack-traces.md","headings":["Decoding Stack Traces in .NET","Generating the Mapping File","Decoding the Obfuscated Stack Trace","Babel Desktop","Command Line","Dynamic Proxy Frames","Automating Stack Trace Deobfuscation","Using PDB Files with Obfuscated Stack Traces"],"sha256":"4d04f846083defc207b1520d99432609f35805fcf7bb8b83dce181ca1526c14c"},{"path":"obfuscator/symbols-renaming/xaml-renaming","title":"XAML Renaming","description":"Windows Presentation Foundation (WPF) and, more recently, MAUI applications use XAML declarative markup language and BAML (compiled XAML) to directly enable visual designers to create user interface…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/symbols-renaming/xaml-renaming","md":"/md/obfuscator/symbols-renaming/xaml-renaming.md","headings":["Aligning string literals with renamed XAML-bound members"],"sha256":"d05e4a0613beac932e72f65a759b71890885db01bc5b3af40bcab737a0d28af2"},{"path":"obfuscator/symbols-renaming/xml-map-files","title":"XML Map Files","description":"Babel Obfuscator uses XML map files to map the original, unobfuscated names of classes, methods, properties, events and fields to their obfuscated names. These files can be generated by the Babel…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/symbols-renaming/xml-map-files","md":"/md/obfuscator/symbols-renaming/xml-map-files.md","headings":["Configuring XML Map File Generation"],"sha256":"9800f46e778d565be26278f22f519ea048d6c0759f41c54f1a73f1105899d996"},{"path":"obfuscator/string-encryption","title":"String Encryption","description":"Babel Obfuscator provides the ability to encrypt code-inline strings using integrated string encryption algorithms. In addition to these built-in encryption algorithms, Babel also allows for custom…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/string-encryption","md":"/md/obfuscator/string-encryption.md","headings":["Configuring String Encryption","Babel Desktop","In This Section"],"sha256":"5c1b18bbbd1873dc5fbd2a8c925e2761b377ef4e8933aca880782c44e7f9403b"},{"path":"obfuscator/string-encryption/standard-algorithms","title":"Standard Algorithms","description":"Babel Obfuscator ships with three built-in string encryption algorithms: XOR, HASH and STREAM. All three are self-contained — they decrypt without any external input — so choosing between them is a…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/string-encryption/standard-algorithms","md":"/md/obfuscator/string-encryption/standard-algorithms.md","headings":["XOR Algorithm","HASH Algorithm","STREAM Algorithm (Ultimate)","Comparing the Algorithms"],"sha256":"2512e4872575562124cc03a3e20d709aeab8e5e3fc1d4f6a1953717ac598b245"},{"path":"obfuscator/string-encryption/custom-string-encryption","title":"Custom Algorithm","description":"Custom string encryption enables users to formulate their own methods for encrypting and decrypting strings, allowing for personalized obfuscation of strings. To leverage custom string encryption…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/string-encryption/custom-string-encryption","md":"/md/obfuscator/string-encryption/custom-string-encryption.md","headings":[],"sha256":"d56386539b636b4a8e485da8a5512782615db2effa0f69ab9460d1afeecba9e8"},{"path":"obfuscator/control-flow-obfuscation","title":"Control Flow Obfuscation","description":"Control flow obfuscation makes a method hard to follow by rewriting the way its instructions branch, while leaving what the method computes unchanged. Babel can make if statements harder to read…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/control-flow-obfuscation","md":"/md/obfuscator/control-flow-obfuscation.md","headings":["Configuring Control Flow Obfuscation","In This Section"],"sha256":"5c042ea152d03a37e0436e2b3decaef5de61465261a94db096cad96765d5081d"},{"path":"obfuscator/control-flow-obfuscation/algorithms","title":"Control Flow Algorithms","description":"Babel Obfuscator provides several control flow algorithms that you enable individually. Most produce verifiable IL and run on every supported runtime; two (token and underflow) do not and are covered…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/control-flow-obfuscation/algorithms","md":"/md/obfuscator/control-flow-obfuscation/algorithms.md","headings":["Verifiable Algorithms","Non-Verifiable Options"],"sha256":"cf48b55255b36893b73261a1661effd94b330ce3aeb86b5333a90b523d5c6451"},{"path":"obfuscator/control-flow-obfuscation/chained-state","title":"Chained State (Ultimate)","description":"Chained State (chain) is the strongest control flow transform in Babel Obfuscator. Like the switch algorithm it flattens a method — it rebuilds the method around a dispatcher so its blocks no longer…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/control-flow-obfuscation/chained-state","md":"/md/obfuscator/control-flow-obfuscation/chained-state.md","headings":["Why Chained State","Compatibility","Performance","Enabling Chained State"],"sha256":"99f9bfaa8375b82e8e75b5819aa2fb67329a1a0737183be77edc942779bbd34e"},{"path":"obfuscator/control-flow-obfuscation/performance","title":"Performance & Tuning","description":"Control flow obfuscation trades a little runtime for protection. The lightweight algorithms are essentially free; the flattening algorithms add a dispatcher that runs on every call and therefore cost…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/control-flow-obfuscation/performance","md":"/md/obfuscator/control-flow-obfuscation/performance.md","headings":["Comparing the Algorithms","Control Flow Iterations","Limiting Control Flow Obfuscation"],"sha256":"c21b2cd888b5665d24f222c761fc3a42982f06439ee190b74c8d4b94c54d2456"},{"path":"obfuscator/code-encryption","title":"Code Encryption","description":"Babel Obfuscator's Code Encryption feature allows users to encrypt their entire code to protect it from reverse engineering.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/code-encryption","md":"/md/obfuscator/code-encryption.md","headings":["Code Encryption Limits","Enabling Code Encryption"],"sha256":"b4c6ff67fbaacfa237eda398261a699845d4422ef9d34497fa47c91e959d2c49"},{"path":"obfuscator/code-encryption/dynamic-code","title":"Dynamic Code","description":"Switching demo to retail code with code encryption.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/code-encryption/dynamic-code","md":"/md/obfuscator/code-encryption/dynamic-code.md","headings":["Demo Application"],"sha256":"34db49510f231017d5230a5651b6abfb4b12027e451ccf5bcc019e81c3ec8a8a"},{"path":"obfuscator/code-encryption/external-code-files","title":"External Code Files","description":"When code encryption is applied to a method, Babel Obfuscator can extract the encrypted code of that method and store it as a separate binary file outside of the target assembly. This binary file…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/code-encryption/external-code-files","md":"/md/obfuscator/code-encryption/external-code-files.md","headings":[],"sha256":"47687bbe19232691b4d39b5689b6021c6da944e2b97b04bdfa205c9e7bcd0b39"},{"path":"obfuscator/code-encryption/hardware-dongle-binding","title":"Hardware Dongle Binding","description":"Bind a .NET application to a hardware licensing dongle so that swapped or stubbed dongle DLLs cannot bypass Code Encryption.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/code-encryption/hardware-dongle-binding","md":"/md/obfuscator/code-encryption/hardware-dongle-binding.md","headings":["The wrong mental model","The right mental model","Glossary","Four defensive layers","Per-customer keying","Threat model summary","Practical checklist","Reference implementation","Related reading"],"sha256":"86239c31802d3b2136579904bb11c140da9b2acd9d47f31fddbe6f9e309418e4"},{"path":"obfuscator/code-encryption/license-bound-code-encryption","title":"License-Bound Code Encryption","description":"License-bound code encryption is a variation of Password Protected Code in which the password that unlocks an encrypted method is not a fixed constant baked into the build, but a value read from the…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/code-encryption/license-bound-code-encryption","md":"/md/obfuscator/code-encryption/license-bound-code-encryption.md","headings":["How it works","Encrypting the code","Reading the password from the license","Works with every license delivery method"],"sha256":"6e5466a5df51be81321134727dde7039e43fde90713b787b88ed45bf33f2c5ba"},{"path":"obfuscator/code-encryption/password-protected-code","title":"Password Protected Code","description":"In some cases, keeping the encrypted code inside the obfuscated assembly may be preferred rather than storing it in external files. In this case, access to the encrypted code is protected by a…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/code-encryption/password-protected-code","md":"/md/obfuscator/code-encryption/password-protected-code.md","headings":[],"sha256":"796dc67603828129a02c3a0b9bed71f49db7434ba04a7e578ad35e5af583107c"},{"path":"obfuscator/dynamic-proxy","title":"Dynamic Proxy","description":"Dynamic Proxy protection is a powerful feature offered by Babel Obfuscator that enhances the obfuscation and protection of your application's code. It allows you to hide method calls to both external…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/dynamic-proxy","md":"/md/obfuscator/dynamic-proxy.md","headings":["How Dynamic Proxy Works","AOT and Platform Compatibility Limitations"],"sha256":"cd56f8eee813bf5f59ea69b417e7ce387c05825cb6c0581a2647b3030c5e54aa"},{"path":"obfuscator/dynamic-proxy/proxy-modes","title":"Internal and External Calls","description":"Dynamic Proxy can be applied to two categories of calls, selected by the proxy mode:","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/dynamic-proxy/proxy-modes","md":"/md/obfuscator/dynamic-proxy/proxy-modes.md","headings":["Internal Proxy Calls","External Proxy Calls"],"sha256":"452c0e697317e39e7c6a4d5bc1a88808de12f7ca46a720fcb50239cdb4050ed9"},{"path":"obfuscator/dynamic-proxy/coverage","title":"Coverage","description":"Dynamic Proxy replaces direct call, callvirt and newobj instructions, covering static, instance, virtual and interface calls, property and event accessors, object construction, calls on generic types…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/dynamic-proxy/coverage","md":"/md/obfuscator/dynamic-proxy/coverage.md","headings":[],"sha256":"04c6143603b65008855b3fb57596bc03689c50781fc32be134a85dce8ac1a775"},{"path":"obfuscator/dynamic-proxy/filters","title":"Dynamic Proxy Filters","description":"Babel Obfuscator provides the flexibility to specify a list of filters to restrict the generation of dynamic proxies to specific methods. This feature gives you fine-grained control over the dynamic…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/dynamic-proxy/filters","md":"/md/obfuscator/dynamic-proxy/filters.md","headings":[],"sha256":"b436b6e6ba22ce094915fe24d2dd0c6fdc37a31f37b70210865897d691c7d981"},{"path":"obfuscator/dynamic-proxy/configuration","title":"Configuration","description":"You can configure Dynamic Proxy from the command-line interface (CLI), the MSBuild Babel task, or Babel Desktop.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/dynamic-proxy/configuration","md":"/md/obfuscator/dynamic-proxy/configuration.md","headings":["Command Line","MSBuild Babel Task","Babel Desktop"],"sha256":"09928e5bc519fb9c56deac3d575ae2c78210fb6403a8d7563961541ac48205c6"},{"path":"obfuscator/dynamic-proxy/performance","title":"Performance","description":"Dynamic Proxy adds two kinds of cost, both small:","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/dynamic-proxy/performance","md":"/md/obfuscator/dynamic-proxy/performance.md","headings":[],"sha256":"0a985dc677812eee75981f7a566b50c839a3989048f727d8eca35131bd72ed03"},{"path":"obfuscator/dynamic-proxy/deobfuscation-resistance","title":"Deobfuscation Resistance","description":"Because the rewritten call sites no longer reference their targets directly and the encoding is varied from build to build, automated deobfuscation tools cannot recover the original call graph by…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/dynamic-proxy/deobfuscation-resistance","md":"/md/obfuscator/dynamic-proxy/deobfuscation-resistance.md","headings":["Best Practices"],"sha256":"f64739ec31e3eb0259a40271d1dbbb660d9d767845a41e12fb2578cd9e7d1958"},{"path":"obfuscator/resource-encryption","title":"Resource Encryption","description":"Babel Obfuscator offers the capability to compress and encrypt embedded resources, providing both resource protection and reducing the overall size of the assembly. When resources are encrypted, they…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/resource-encryption","md":"/md/obfuscator/resource-encryption.md","headings":[],"sha256":"6761043826a2edb1562870d347cff46efd3811e65149bc8dbe5e1b39dab2b860"},{"path":"obfuscator/value-and-array-encryption","title":"Value And Array Encryption","description":"Constant values and arrays declared inline in your code can often contain sensitive information, such as data encryption keys or other critical data that you want to keep hidden from disassemblers or…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/value-and-array-encryption","md":"/md/obfuscator/value-and-array-encryption.md","headings":["How It Works"],"sha256":"5b9424ed4ca3d00164ea56db3f4dc17c2c5148cf694f586cb006d4671ab4da22"},{"path":"obfuscator/value-and-array-encryption/supported-values","title":"Supported Values","description":"Value and Array Encryption can be enabled independently for each data type, so you can protect only what matters and keep the rest untouched. See Configuration for how to select them.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/value-and-array-encryption/supported-values","md":"/md/obfuscator/value-and-array-encryption/supported-values.md","headings":["Encrypted","Left unchanged"],"sha256":"5e282098cc7e3df7c1b3bc748e7493b17604e20d7a268e13a94b82fbbd65bf2c"},{"path":"obfuscator/value-and-array-encryption/configuration","title":"Configuration","description":"There are multiple ways to configure Values and Array Encryption in Babel Obfuscator. You can choose one of the following three methods based on your preference and project setup. See Supported…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/value-and-array-encryption/configuration","md":"/md/obfuscator/value-and-array-encryption/configuration.md","headings":["Command Line","MSBuild Babel Task","Babel Desktop"],"sha256":"7aaad1407ffd3bc1457577bef2552cae69cb6aba94301f63794c209873265df5"},{"path":"obfuscator/value-and-array-encryption/performance","title":"Performance","description":"Value and Array Encryption trades a small amount of runtime cost for keeping your constants and array data out of the decompiled code.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/value-and-array-encryption/performance","md":"/md/obfuscator/value-and-array-encryption/performance.md","headings":[],"sha256":"ab174c2a479ce9b0ee1a71821c1a64f4655c44e0dec268ea397893c89f0dfa93"},{"path":"obfuscator/value-and-array-encryption/deobfuscation-resistance","title":"Deobfuscation Resistance","description":"Once a constant is encrypted, the real value is no longer present in the method body: the IL only carries an index into an encrypted table that is decrypted at runtime. A decompiler therefore shows…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/value-and-array-encryption/deobfuscation-resistance","md":"/md/obfuscator/value-and-array-encryption/deobfuscation-resistance.md","headings":[],"sha256":"c30ca6c1023eff8511238d39a0c77763b07b1f62e333ef288040e02bc764d54c"},{"path":"obfuscator/tampering-detection","title":"Tampering Detection","description":"Tampering detection is a critical aspect of ensuring the integrity and security of software applications. In the context of the .NET, Babel Obfuscator is one powerful tool for detecting tampering. By…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/tampering-detection","md":"/md/obfuscator/tampering-detection.md","headings":["Configuring Tampering Detection","Android (MAUI) Package Integrity (Ultimate)","iOS (MAUI) Package Integrity (Ultimate)","Custom Action on Tampering Detection"],"sha256":"e5b160301a1fceafaef5fc8fc100a465736bd01b51a7ff7273efec315f112850"},{"path":"obfuscator/anti-debugging","title":"Anti Debugging","description":"By injecting anti-debugging code into your assembly, Babel Obfuscator can take proactive measures when a debugger is attached, such as terminating the application or executing custom logic. This…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/anti-debugging","md":"/md/obfuscator/anti-debugging.md","headings":["Configuring Anti Debugging","Custom Action on Debugger Detected"],"sha256":"59c2953ccf048ab04f32859e4c84525e05640927b5f44f056b46c59d53636ae3"},{"path":"obfuscator/enhancing-code-security","title":"Enhancing Code Security","description":"Best practices for enhanced code security.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/enhancing-code-security","md":"/md/obfuscator/enhancing-code-security.md","headings":["Rename and Restructure Your Symbols","Hide Constant Data","Obscure Program Logic","Detect and Deter Runtime Attacks","Strip What You Don't Need to Ship","A Recommended Baseline","Keep a Map File for Support"],"sha256":"8ee479e4c5adb139b766dfeb388211acac9de32caa218830a924657bedc9f41e"},{"path":"obfuscator/fips-compliance","title":"FIPS Compliance","description":"Assemblies protected with Babel Obfuscator run on FIPS-enabled hosts. This page explains how the protection features that rely on runtime decryption — Code Encryption (MSIL), String Encryption…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/fips-compliance","md":"/md/obfuscator/fips-compliance.md","headings":["Background","How it can surface in obfuscated assemblies","Starting on a broken-FIPS host with managed AES","Resolving it in containers","Verifying the environment","If you cannot change the environment"],"sha256":"1d42a3776bd2aed9db4aed5aeff17ba30126225edf2e0964cf59adeaabc19dae"},{"path":"obfuscator/optimizations","title":"Optimizations","description":"Babel Obfuscator can perform a series of optimizations related to both code and metadata. These optimizations encompass various techniques to improve the efficiency, size, and security of the…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/optimizations","md":"/md/obfuscator/optimizations.md","headings":["Babel Desktop"],"sha256":"f27f4858aafe71459de8ed8db42708bb7fb56d8d69f01f640e957150bb2f7ae5"},{"path":"obfuscator/optimizations/code-optimizations","title":"Code Optimizations","description":"Code Optimizations refer to a set of techniques employed by Babel Obfuscator to improve the efficiency and performance of the code during the obfuscation process. These optimizations focus on…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/optimizations/code-optimizations","md":"/md/obfuscator/optimizations/code-optimizations.md","headings":["Inline Expansion","Const Fields Removal"],"sha256":"6deda6356c0f8b15f72fa70f960576e727db568ef1e795f8e0c66653b4a8011b"},{"path":"obfuscator/optimizations/dead-code-removal","title":"Dead Code Removal","description":"Dead Code Removal is a crucial optimization technique offered by Babel Obfuscator. It involves the identification and elimination of code that will never be executed during runtime. This includes…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/optimizations/dead-code-removal","md":"/md/obfuscator/optimizations/dead-code-removal.md","headings":["Additional Entry Points"],"sha256":"899625935fa8a626b11adf10e27536ffd5bc83e1df38c42de209876ffc9eaa18"},{"path":"obfuscator/optimizations/metadata-optimizations","title":"Metadata Optimizations","description":"Metadata optimizations in Babel Obfuscator involve a series of techniques to enhance the obfuscated code's metadata, which contains information about types, members, attributes, and other crucial…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/optimizations/metadata-optimizations","md":"/md/obfuscator/optimizations/metadata-optimizations.md","headings":["Automatic Class Sealing","Unwanted Attributes Removal","System Enum Types Removal","Disgregate Removal"],"sha256":"39c18241c5287fb5d094b35e68727fb8d103a9446c793f80ed8ed26b60da300f"},{"path":"obfuscator/appendix","title":"Appendix","description":"The following table shows the list of warning codes and messages.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/appendix","md":"/md/obfuscator/appendix.md","headings":["Warning Codes"],"sha256":"53c4045c5a957460a642eada1756d85edf05c52ca9435835f89447e8d9bcb2d1"},{"path":"obfuscator/plugins/babel-obfuscator-plugins","title":"Babel Obfuscator Plugins","description":"Babel Obfuscator provides support for custom plug-ins that enable users to extend the functionality of the obfuscator beyond what is provided out of the box. With a custom plugin, you can:","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/plugins/babel-obfuscator-plugins","md":"/md/obfuscator/plugins/babel-obfuscator-plugins.md","headings":["Code Samples","Using Plugin at Command Line","Using Plugin in MSBuild Babel Task","Using Plugins From Babel Desktop"],"sha256":"ffd86688f237322f40c8a6492f547caa0ef97c7d62555951bbaefa75f07642d0"},{"path":"obfuscator/plugins/encrypt-plugin","title":"Encrypt Plugin","description":"The Babel Encrypt plugin is a powerful Babel Obfuscator extension for enhancing the security of encrypted strings. It is designed to work with Babel Obfuscator and provides advanced encryption…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/plugins/encrypt-plugin","md":"/md/obfuscator/plugins/encrypt-plugin.md","headings":["Full Feature Set","License"],"sha256":"199f8bc1020621d04c0ced8fe7289dfaaef30c74abd4d882e5c7db0a9a4fc110"},{"path":"obfuscator/plugins/encrypt-plugin/getting-started","title":"Getting Started","description":"The \"Babel Encrypt\" plugin is a component included in the Babel Obfuscator Ultimate edition. However, for those with the Enterprise edition, it requires a separate purchase. This plugin comes as an…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/plugins/encrypt-plugin/getting-started","md":"/md/obfuscator/plugins/encrypt-plugin/getting-started.md","headings":["Plugin Arguments","Examples","Setup Babel Encrypt in DevOps","Configure Babel Encrypt in Babel Desktop"],"sha256":"2d1d71d0dca6db532b3160b46fd368cf2e94851b60b30ae895c340c18ac74b89"},{"path":"obfuscator/plugins/encrypt-plugin/source-code","title":"Source Code","description":"The plugin is distributed with full C# source code. To build the plugin from the source code, you need the following:","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/plugins/encrypt-plugin/source-code","md":"/md/obfuscator/plugins/encrypt-plugin/source-code.md","headings":["Build Instructions","Changing the Code","Debugging the Plugin"],"sha256":"7cb7a58ad56bd4cc81a064a4c3cb3a6b8ac47ef2e5721535a423e225be11ce38"},{"path":"obfuscator/examples/summary","title":"Examples","description":"A collection of practical use cases and examples that will guide you in straightforwardly integrating Babel Obfuscator into your projects.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/summary","md":"/md/obfuscator/examples/summary.md","headings":["General Samples","Code Encryption","Cross Assembly Renaming","Build Servers (Ultimate)","Babel Obfuscator NuGet (Ultimate)"],"sha256":"b95728c0680e15df44695e38657b1bc57b8b19f5fc97a404f290f3eff11f71c1"},{"path":"obfuscator/examples/general-samples","title":"General Samples","description":"This section provides several code examples and projects to help developers understand how to use Babel Obfuscator effectively in their projects. From simple code snippets to full-fledged projects…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/general-samples","md":"/md/obfuscator/examples/general-samples.md","headings":[],"sha256":"867152e531f0987980edbd276e1c21af1d0b3281a0157d11a35470156bdd6b77"},{"path":"obfuscator/examples/general-samples/blazor-web-app","title":"Blazor Web App","description":"Blazor applications can be protected using Babel Obfuscator, which provides several advantages. One of the main advantages of using Blazor's razor pages is the ability to combine HTML markup and C#…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/general-samples/blazor-web-app","md":"/md/obfuscator/examples/general-samples/blazor-web-app.md","headings":[],"sha256":"bdc94840d617ab34a96c458a05bef0632b1ce6378693ad1ed3f3bf3c46c66254"},{"path":"obfuscator/examples/general-samples/clickonce-deploy","title":"ClickOnce Deploy","description":"In ClickOnce deployment, the Babel task is configured to obfuscate the target assembly just after the Compile step.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/general-samples/clickonce-deploy","md":"/md/obfuscator/examples/general-samples/clickonce-deploy.md","headings":[],"sha256":"5672d21fde6533d8f6618c598d85902ef74aa43ff33483e6780b9be7263b374b"},{"path":"obfuscator/examples/general-samples/detecting-babel-obfuscation","title":"Detecting Babel Obfuscation","description":"Babel Obfuscator is a tool that has gained prominence in the realm of .NET assemblies, primarily due to its ability to make them more resilient against reverse engineering. At its core, Babel doesn't…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/general-samples/detecting-babel-obfuscation","md":"/md/obfuscator/examples/general-samples/detecting-babel-obfuscation.md","headings":[],"sha256":"e44e51e384e8bb26dba456e8fa6a2b69c73597d28e5867be1e27df6bdd36f181"},{"path":"obfuscator/examples/general-samples/obfuscate-.net-maui","title":"Obfuscate .NET MAUI","description":"Babel Obfuscator can obfuscate a .NET MAUI (Multi-platform App UI) application by processing the compiled assembly file (e.g., a DLL or EXE) with its obfuscation engine. The obfuscation process will…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/general-samples/obfuscate-.net-maui","md":"/md/obfuscator/examples/general-samples/obfuscate-.net-maui.md","headings":["Configure the Babel Task","Using NuGet Package","Linking Behavior for .NET MAUI iOS App"],"sha256":"2d14a27c34d03d61f561bc907cbe43d57e2b0db909f69c8c602218f241187587"},{"path":"obfuscator/examples/nuget-package","title":"Babel Obfuscator NuGet Package","description":"The Babel Obfuscator nuget package provides an easy way to integrate the Babel MSBuild task in any .NET project. Once the package is installed, the Babel task is automatically added to the project…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/nuget-package","md":"/md/obfuscator/examples/nuget-package.md","headings":[],"sha256":"53d8d0afed5a7599f4bfc03b568b1db4023f343ace8b70de3b07ded37ad31edc"},{"path":"obfuscator/examples/nuget-package/secret-protection","title":"Protecting Secrets with String and Value Encryption","description":"Almost every application ships secrets in its code — API keys, endpoints, connection strings, license parameters, \"magic\" numbers and lookup tables. A decompiler reads them in seconds. This example…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/nuget-package/secret-protection","md":"/md/obfuscator/examples/nuget-package/secret-protection.md","headings":[],"sha256":"a311dfcadaa501682d140ae1443a481941699c6ada651e1f5671550b7059886d"},{"path":"obfuscator/examples/nuget-package/dynamic-proxy","title":"Hiding the Call Graph with Dynamic Proxy","description":"A decompiler reconstructs a lot from method calls: which framework APIs you use, how your own methods chain together, and even the original names of local variables (inferred from the types you…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/nuget-package/dynamic-proxy","md":"/md/obfuscator/examples/nuget-package/dynamic-proxy.md","headings":[],"sha256":"4c1c039e54e42473cb518f4e16373f02714b1d7c8bc1694a577489f325c48bec"},{"path":"obfuscator/examples/nuget-package/single-file-merge","title":"One Obfuscated File: Merging Dependencies","description":"Shipping an application together with its dependency DLLs gives an attacker more surface, and those libraries are usually not obfuscated at all. This example uses the Babel Obfuscator NuGet package…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/nuget-package/single-file-merge","md":"/md/obfuscator/examples/nuget-package/single-file-merge.md","headings":[],"sha256":"e6338125dfe98b5790a5958a1272f59804121befb17f3a75ccd6d6a10aa4dc5d"},{"path":"obfuscator/examples/nuget-package/defense-in-depth","title":"Defense in Depth: Every Layer in One Build","description":"Strong protection does not come from a single trick — it comes from layers. This example turns on every protection of the Babel Obfuscator NuGet package on one small assembly, so you can see the…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/nuget-package/defense-in-depth","md":"/md/obfuscator/examples/nuget-package/defense-in-depth.md","headings":[],"sha256":"2d167dfcfa8fc60aaf3fe19b4bded478c357f5963111a0648dd5dbd1f0f35c29"},{"path":"obfuscator/examples/nuget-package/android-application","title":"Android Application","description":"In this example project, we will utilize the Babel Obfuscator NuGet package to enable obfuscation in an Android application based on .NET 7. The Babel Obfuscator NuGet package can be easily…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/nuget-package/android-application","md":"/md/obfuscator/examples/nuget-package/android-application.md","headings":[],"sha256":"41198d4ef579c84fac26022c6a19fd4ad1627097b94747221a7281979539668b"},{"path":"obfuscator/examples/build-servers","title":"Build Servers","description":"Continuous Integration (CI) and Build Server are important components of modern software development and deployment. They are used to automate the process of building, testing, and deploying software.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/build-servers","md":"/md/obfuscator/examples/build-servers.md","headings":[],"sha256":"b44be0b1ee733692c0d1fbc06026e0efb07c6300592a15791b869eaaff14343b"},{"path":"obfuscator/examples/build-servers/azure-devops","title":"Azure DevOps","description":"Run Babel Obfuscator on Azure Pipelines by referencing the Babel Obfuscator NuGet package from a private Azure Artifacts feed, with the license supplied as a secret variable.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/build-servers/azure-devops","md":"/md/obfuscator/examples/build-servers/azure-devops.md","headings":["Host the Package on an Azure Artifacts Feed","Reference the Package","Supply the License as a Secret","The Pipeline","Configure the Obfuscation","Verifying the Result"],"sha256":"e590cbb80da5eb1a7a92d5e084e262c46e2def4a5b3cc5545d793b4e1ed1a6ed"},{"path":"obfuscator/examples/build-servers/github-actions","title":"GitHub Actions","description":"GitHub Actions provides a convenient way to automate the obfuscation process for your code by allowing you to specify obfuscation tasks as part of your build and deployment pipeline.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/build-servers/github-actions","md":"/md/obfuscator/examples/build-servers/github-actions.md","headings":[],"sha256":"4f2fc4ca46c7dcfc633ad887da015804e1e6f08d1ab32938a04ae9fe0ba3ff3e"},{"path":"obfuscator/examples/build-servers/appveyor","title":"AppVeyor","description":"Obfuscate on AppVeyor by hosting the Babel Obfuscator NuGet package on your AppVeyor account feed and passing the license through a secure variable.","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/build-servers/appveyor","md":"/md/obfuscator/examples/build-servers/appveyor.md","headings":["Upload the Package to the AppVeyor Feed","Reference the Package","Supply the License","The Build Configuration","Configure the Obfuscation","Verifying the Result"],"sha256":"7da9a10f44898adeb15fbac7dfb008ec5d82f4cec47b03352f1cb4d96a782ea6"},{"path":"obfuscator/examples/build-servers/unit-tests","title":"Unit Tests","description":"When using Babel Obfuscator, it is possible to maintain unit tests even after obfuscating the code. This is achieved by configuring Babel Obfuscator to apply obfuscation to the code and run the unit…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/build-servers/unit-tests","md":"/md/obfuscator/examples/build-servers/unit-tests.md","headings":["Configure Babel for Unit Tests","Run the Sample Project"],"sha256":"79c26f95ab178eab064c65d09c20b9319d8e3ab04f9085e6120fcdd444493c4f"},{"path":"obfuscator/examples/code-encryption","title":"Code Encryption","description":"Code encryption is a powerful feature of obfuscation tools that allows developers to protect their application code from being reverse-engineered by hackers or competitors. With code encryption, the…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/code-encryption","md":"/md/obfuscator/examples/code-encryption.md","headings":[],"sha256":"3b2963182aef7a90585966e138df69a41b5f15a30de9864909700320acd5e4e7"},{"path":"obfuscator/examples/code-encryption/code-encryption-nuget","title":"Protecting an Algorithm with Code Encryption","description":"A proprietary algorithm is often the most valuable thing in an assembly — and the easiest to lift straight out of a decompiler. This example uses the Babel Obfuscator NuGet package to apply MSIL Code…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/code-encryption/code-encryption-nuget","md":"/md/obfuscator/examples/code-encryption/code-encryption-nuget.md","headings":[],"sha256":"886fc5cf974cd96cc84fbd2f9417ff42fb515ec4915211db50a49bcf1c802e79"},{"path":"obfuscator/examples/code-encryption/feature-based-licenses","title":"Feature Based Licenses","description":"Babel Obfuscator includes a licensing feature that allows you to generate feature-based licenses for your obfuscated code. This means that you can create licenses that unlock specific features or…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/code-encryption/feature-based-licenses","md":"/md/obfuscator/examples/code-encryption/feature-based-licenses.md","headings":[],"sha256":"51236df0ef2d5538d01d096c9c39e0ad3142298f53116633050d1c4b8931a75e"},{"path":"obfuscator/examples/code-encryption/license-bound-encryption","title":"License-Bound Code Encryption","description":"This example makes a protected feature cryptographically dependent on a valid license by combining two Babel technologies: MSIL Code Encryption encrypts the body of a sensitive method, and Babel…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/code-encryption/license-bound-encryption","md":"/md/obfuscator/examples/code-encryption/license-bound-encryption.md","headings":[],"sha256":"9ca28d26ba7541deeb9406f58b3d6e8ed5df7a671c9f29d1f46c81a7060b6f40"},{"path":"obfuscator/examples/code-encryption/external-encrypted-code","title":"Feature as an External Encrypted File","description":"This example delivers a premium feature as encrypted code that ships separately from the application, unlocked only when the customer also has a license that grants it. Babel Obfuscator can strip the…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/code-encryption/external-encrypted-code","md":"/md/obfuscator/examples/code-encryption/external-encrypted-code.md","headings":[],"sha256":"19ffff282b5a5360e4d5f86d872450e86ba167bb597f2e603d84875b1d78e884"},{"path":"obfuscator/examples/code-encryption/subscription-license","title":"Subscription License with Encrypted Pro Code","description":"This example shows a time-limited (subscription) license with a grace period, where the subscription-only functionality is protected with Babel Obfuscator MSIL Code Encryption. The pro code can only…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/code-encryption/subscription-license","md":"/md/obfuscator/examples/code-encryption/subscription-license.md","headings":[],"sha256":"0277a713408afd1e6e276f1c5d495842b0eb3b476579204cdf6d44d8580e6495"},{"path":"obfuscator/examples/cross-assembly-renaming","title":"Cross Assembly Renaming","description":"Cross-assembly renaming is an obfuscation technique used to increase the level of security in applications by renaming the public interface of the referenced assemblies. This technique is…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/cross-assembly-renaming","md":"/md/obfuscator/examples/cross-assembly-renaming.md","headings":[],"sha256":"c86fc037fa5c848c5cc0123815c1df2cdff30179265092e855759533a3668281"},{"path":"obfuscator/examples/cross-assembly-renaming/publish-.net-app","title":"Publish .NET App","description":"This example demonstrates how to use the Babel task to configure cross-assembly renaming during the build process of a .NET application. Specifically, the public interface of the MathNet.Numerics…","section":"obfuscator","url":"https://docs.babelfor.net/obfuscator/examples/cross-assembly-renaming/publish-.net-app","md":"/md/obfuscator/examples/cross-assembly-renaming/publish-.net-app.md","headings":[],"sha256":"a12385e28d3201929e77f54c52dc2121cf322079c26c3d03d838dd44ef2e9168"},{"path":"licensing","title":"Babel Licensing","description":"Babel Licensing is a licensing system for .NET applications and components: digitally signed licenses, a licensing service for activation and floating licenses, and the tools to issue, distribute and…","section":"licensing","url":"https://docs.babelfor.net/licensing","md":"/md/licensing.md","headings":["How Babel Licensing Works","What's New","Editions and Badges","Licensing Modes","What a License Can Express","Components","Built for AI-Assisted Workflows","Platforms","Next Steps"],"sha256":"18913c9ab8b95ed6d4a28fa3da349f80a50f8a0cd6cfe98619217993f0d1aede"},{"path":"licensing/introduction","title":"Introduction","description":"Babel Licensing is a licensing system for .NET applications and components: digitally signed licenses, a licensing service for activation and floating licenses, and the tools to issue, distribute and…","section":"licensing","url":"https://docs.babelfor.net/licensing/introduction","md":"/md/licensing/introduction.md","headings":["How Babel Licensing Works","What's New","Editions and Badges","Licensing Modes","What a License Can Express","Components","Built for AI-Assisted Workflows","Platforms","Next Steps"],"sha256":"8a0966028743440e002cb8c16013d9e5fe984386047bac7c7bb4f2837820c2a3"},{"path":"licensing/introduction/general-features","title":"General Features","description":"What Babel Licensing does, where it runs, and which edition includes what. Each section links to the page that shows how to use the feature.","section":"licensing","url":"https://docs.babelfor.net/licensing/introduction/general-features","md":"/md/licensing/introduction/general-features.md","headings":["Fully Managed Licensing System","Based on Digitally Signed Licenses","Compatible With Any .NET Technology","Flexible Licensing Model","Three Licensing Modes","License Tokens (Server)","Babel Licensing Service (Server)","Management From the Desktop (Server)","Management From the Browser (Data Center)","Sell Through WordPress and WooCommerce (Server)","Reporting From the Field","Integrated SDK, MSBuild and Command Line (Server)","Operated by AI Assistants Through MCP (Data Center)","Fully Integrated With Babel Obfuscator","FIPS-Ready"],"sha256":"c83f4ac4f21acacac4f1104c8d73e10bcec4008ac4deb34428b651781f504760"},{"path":"licensing/getting-started","title":"Getting Started","description":"Babel Licensing is a set of components and tools for building and managing licensed applications. Some components run on the server, others inside the client application.","section":"licensing","url":"https://docs.babelfor.net/licensing/getting-started","md":"/md/licensing/getting-started.md","headings":["Supported databases"],"sha256":"49b8fd944c3272fe443353d9552b9d37fb2c7979a195d3aa07d81b17f2d04dcf"},{"path":"licensing/getting-started/install","title":"Install","description":"Babel is distributed in the following packages:","section":"licensing","url":"https://docs.babelfor.net/licensing/getting-started/install","md":"/md/licensing/getting-started/install.md","headings":["Packages","Server Components","Supported databases","Client Components"],"sha256":"350883a5dcd82f77f69301843ed8a7161fcb674b7c746c6be174baee1c637818"},{"path":"licensing/getting-started/windows","title":"Windows","description":"This section provides a step-by-step guide to installing Babel Licensing Service on Windows 11.","section":"licensing","url":"https://docs.babelfor.net/licensing/getting-started/windows","md":"/md/licensing/getting-started/windows.md","headings":["Prerequisites","Install Script","Setup Files","Creating Database","Configuring Babel Licensing Service","Configuring Kestrel","Start Babel Licensing Service","Running as a Windows Service"],"sha256":"7d222d75bba128d740946255a7e5d855156ee54e5a95439a52f55f0bb1daf183"},{"path":"licensing/getting-started/linux-ubuntu","title":"Linux Ubuntu","description":"This section provides a step-by-step guide to installing Babel Licensing Service on Linux Ubuntu.","section":"licensing","url":"https://docs.babelfor.net/licensing/getting-started/linux-ubuntu","md":"/md/licensing/getting-started/linux-ubuntu.md","headings":["Prerequisites","Install Script","Setup Files","Start Babel Licensing Service","Configure As Background Process"],"sha256":"62f55038e2787fe7d79d3ebe24f9df968f664cd77e1d163aaf00517974f2f643"},{"path":"licensing/getting-started/docker","title":"Docker","description":"Docker is a convenient and efficient method to run the Babel Licensing Service for testing purposes. Docker provides a lightweight and isolated environment called a container, which encapsulates the…","section":"licensing","url":"https://docs.babelfor.net/licensing/getting-started/docker","md":"/md/licensing/getting-started/docker.md","headings":["Prerequisites","Create the Dockerfile","Docker Compose","Starting the Service","Stopping the Service","Configure Babel Licensing Service","MSSQL Server Docker Image"],"sha256":"f69b549d3c603f8bc45d11fa878f7f492cb54e9da6dc230eff2f3dcf7fee95f1"},{"path":"licensing/getting-started/client-components","title":"Client Components","description":"To add Babel Licensing to your .NET applications and components, you need to install the Babel Licensing client components. They include the Babel Licensing NuGet package and the Babel Data NuGet…","section":"licensing","url":"https://docs.babelfor.net/licensing/getting-started/client-components","md":"/md/licensing/getting-started/client-components.md","headings":["Babel NuGet Packages","Create a Local NuGet Feed Using dotnet","Create a Local NuGet Feed Using Visual Studio","Installing Babel Licensing Lic CLI Tool"],"sha256":"065c7fa39cb4f4330d2c0d8aee36b2cd5d1dee3f289032bc3c7cb587b5a7130d"},{"path":"licensing/babel-licensing-service","title":"Babel Licensing Service (Server)","description":"Babel Licensing Service serves as a comprehensive and robust licensing solution designed specifically for .NET applications. It provides a wide range of functionalities aimed at managing software…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service","md":"/md/licensing/babel-licensing-service.md","headings":[],"sha256":"a0fd350662d7768c824971b5af7aa004da762ec404b8360eb849764c56061e79"},{"path":"licensing/babel-licensing-service/configuration","title":"Configuration","description":"The configuration of Babel Licensing services is an essential aspect of setting up a secure and reliable licensing infrastructure. One key element of this configuration is the appsettings.json file…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/configuration","md":"/md/licensing/babel-licensing-service/configuration.md","headings":["Serilog","AllowedHosts","Kestrel","Application","IP Filtering","Webhook","Email","Licensing","Reporting","Database"],"sha256":"deb12651df284056985c22ba685f889e16b8b87a4b01349ead41fb8cf92a7f23"},{"path":"licensing/babel-licensing-service/configuration/grpc-ssl-tls","title":"gRPC SSL/TLS","description":"Configuring SSL/TLS in Babel Licensing Service","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/configuration/grpc-ssl-tls","md":"/md/licensing/babel-licensing-service/configuration/grpc-ssl-tls.md","headings":["Self Signed Certificates","Server","Client"],"sha256":"fbe9c7ec5780fa627c36b633abb1875aca70bf90c9bfc979f055f56e76e51ace"},{"path":"licensing/babel-licensing-service/configuration/grpc-web","title":"gRPC Web","description":"Babel Licensing Service supports gRPC Web because it enables a wide range of applications, including Xamarin and UWP, to interact with gRPC services. By using gRPC-Web, these applications can make…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/configuration/grpc-web","md":"/md/licensing/babel-licensing-service/configuration/grpc-web.md","headings":["Server","Client"],"sha256":"e43f4d9de04d673104c84646bcdb5bdc2701624e1cc4e7504b4ab3a042c779b7"},{"path":"licensing/babel-licensing-service/configuration/http-client","title":"HTTP Client","description":"Configuring the HTTP transport in Babel Licensing client applications","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/configuration/http-client","md":"/md/licensing/babel-licensing-service/configuration/http-client.md","headings":["Basic Configuration","Custom HttpClientHandler","UseHttp vs UseGrpc"],"sha256":"150688f9b9ebe96e39977a571dee47e88783487bfbd52142a9c380f4f477c314"},{"path":"licensing/babel-licensing-service/configuration/iis-webdav","title":"IIS WebDAV Configuration","description":"When hosting Babel Licensing Service on Internet Information Services (IIS), you may encounter issues with API callbacks if WebDAV is enabled on your server. This document explains why these…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/configuration/iis-webdav","md":"/md/licensing/babel-licensing-service/configuration/iis-webdav.md","headings":["Understanding the WebDAV Conflict","Symptoms of WebDAV Interference","Resolving WebDAV Conflicts","Web.config Placement","Site-Specific vs. Global Configuration","Verifying the Configuration","Troubleshooting"],"sha256":"9df98ffb191fec6cdcc6b236e563288c4d5c23251062599865ec769f29ce3862"},{"path":"licensing/babel-licensing-service/error-codes","title":"Error Codes","description":"In the Babel Licensing Service, error codes play a crucial role in efficiently communicating and handling various issues that may arise during interactions with the licensing system. These error…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/error-codes","md":"/md/licensing/babel-licensing-service/error-codes.md","headings":[],"sha256":"a4a5ae52f827c002a42c0783a94715a9636ee9fd0e6ea04106633598ced5cc25"},{"path":"licensing/babel-licensing-service/general-features","title":"General Features","description":"Babel Licensing Service is a powerful solution designed to streamline the licensing process, enhance software security, and simplify license management for software vendors. With a comprehensive set…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/general-features","md":"/md/licensing/babel-licensing-service/general-features.md","headings":[],"sha256":"2301f5dc66b2d1e6590e935b24bf78c7d1cbcbd17decccadf25456405f802802"},{"path":"licensing/babel-licensing-service/general-features/deployment","title":"Deployment","description":"Babel Licensing Services offer flexibility in terms of deployment options, allowing them to be hosted either on-premises or in the cloud. This flexibility enables software developers and…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/general-features/deployment","md":"/md/licensing/babel-licensing-service/general-features/deployment.md","headings":["On-Premises Hosting","Cloud Hosting"],"sha256":"55aabe237727d0f62e99c73efd924cc439e23223a697c2656ec38eeb7e8ce3c8"},{"path":"licensing/babel-licensing-service/general-features/license-management","title":"License Management","description":"Babel Licensing Service provides comprehensive license management and enforcement capabilities, empowering software developers to protect their intellectual property and ensure compliance with…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/general-features/license-management","md":"/md/licensing/babel-licensing-service/general-features/license-management.md","headings":["License Validation","License Expiration and Renewal","License Revocation","Custom License Restrictions","Floating License","License Activation","License File"],"sha256":"266b4c24730d94985b99ff2c01ec93ff4a710f92c1069aead3a46f210d7de2c3"},{"path":"licensing/babel-licensing-service/general-features/report-management","title":"Report Management","description":"One of the valuable features of Babel Licensing Services is the capability to collect application fault reports. When integrated into licensed applications, the licensing services can capture and…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/general-features/report-management","md":"/md/licensing/babel-licensing-service/general-features/report-management.md","headings":["Application Fault Reports"],"sha256":"a08465335f62ab206ae2e564e13f712c605824fdaa6d009bf6c2c24cd206dc35"},{"path":"licensing/babel-licensing-service/health-check","title":"Health Check","description":"The Health Check feature in Babel Licensing Service provides a comprehensive mechanism to monitor the health and operational status of the service and its components. This feature is essential for…","section":"licensing","url":"https://docs.babelfor.net/licensing/babel-licensing-service/health-check","md":"/md/licensing/babel-licensing-service/health-check.md","headings":["Configuration","Health Check Components","Best Practices"],"sha256":"9fd07941f31675af18fd27fa600be7fa67618c239b7476ae2bef5795a9f1c735"},{"path":"licensing/license-workflow","title":"License Workflow","description":"The license workflow in Babel Licensing represents the end-to-end process of creating, managing, and deploying software licenses. Understanding this workflow is essential for effectively implementing…","section":"licensing","url":"https://docs.babelfor.net/licensing/license-workflow","md":"/md/licensing/license-workflow.md","headings":["1. Product Definition","2. Assignment of Sign Keys to Products","3. License Template Definition","4. License Deployment Models","Activation Licenses","Floating Licenses","Complete Licensing Workflow"],"sha256":"a561d52b277929515da18af8f93ddff3be54b6a56cede1af7cb55bb069114c19"},{"path":"licensing/license-workflow/floating-license-diagram","title":"Floating License Diagram","description":"This diagram illustrates the complete floating license process including request, usage, heartbeat verification, and release:","section":"licensing","url":"https://docs.babelfor.net/licensing/license-workflow/floating-license-diagram","md":"/md/licensing/license-workflow/floating-license-diagram.md","headings":[],"sha256":"aa73f26dcedb8caa24084ae9b58a868c7175d1ad57e98da83da44b8715fb69e7"},{"path":"licensing/license-workflow/license-activation-diagram","title":"License Activation Diagram","description":"The following diagram shows the entire license activation workflow from when a customer enters their activation code through the periodic validation process that happens after successful activation.","section":"licensing","url":"https://docs.babelfor.net/licensing/license-workflow/license-activation-diagram","md":"/md/licensing/license-workflow/license-activation-diagram.md","headings":[],"sha256":"cf85dad9d46dacb856c0d328aa9b1d12194820508af35bb1666b8ad83de199e0"},{"path":"licensing/license-workflow/license-file-diagram","title":"License File Diagram","description":"The license file model represents the traditional approach to software licensing, where a digitally signed license file is distributed to customers and validated locally by the application without…","section":"licensing","url":"https://docs.babelfor.net/licensing/license-workflow/license-file-diagram","md":"/md/licensing/license-workflow/license-file-diagram.md","headings":[],"sha256":"8cd491ce1171760cb25ce315232ec00d7504320d45b7a946389b4bce25e7c804"},{"path":"licensing/license-templates","title":"License Templates","description":"License templates are a fundamental component of the Babel Licensing system, serving as blueprints for generating licenses with consistent configurations. These templates streamline the licensing…","section":"licensing","url":"https://docs.babelfor.net/licensing/license-templates","md":"/md/licensing/license-templates.md","headings":["Advantages of Using Templates","Template Structure and Components","License Models and Template Configuration","Managing Templates in Babel Desktop"],"sha256":"a283c4cc50d20b082a46708f8b25e3e0cb53588a3e7e964121bb15214a623bb3"},{"path":"licensing/license-templates/license-properties","title":"License Properties","description":"The License Properties section in a Babel Licensing template defines the specific attributes and constraints of licenses generated from the template. This section is divided into four key categories…","section":"licensing","url":"https://docs.babelfor.net/licensing/license-templates/license-properties","md":"/md/licensing/license-templates/license-properties.md","headings":["Assemblies","Components","Fields"],"sha256":"9f6c435754dd15020588f16432f9a7dd0ec54de2846ceaefc04dc32ac4470172"},{"path":"licensing/license-templates/license-restrictions","title":"License Restrictions","description":"The Restrictions section in a Babel Licensing template allows you to define specific constraints on how licenses can be used. These restrictions provide granular control over license behavior…","section":"licensing","url":"https://docs.babelfor.net/licensing/license-templates/license-restrictions","md":"/md/licensing/license-templates/license-restrictions.md","headings":["Overview of License Restrictions","Beta Restriction","Hardware Restriction","Trial Restriction","Domain Restriction","Usage Restriction","Custom Restrictions","Combining Restrictions"],"sha256":"f70b3a4a709d20ac7f63672881c4da67b90e23021764aeaa88718115030bb158"},{"path":"licensing/license-templates/user-key-format","title":"User Key Format","description":"The User Key format in Babel Licensing can be customized using a special syntax that allows you to define the structure, length, and character types of generated keys. This flexibility enables you to…","section":"licensing","url":"https://docs.babelfor.net/licensing/license-templates/user-key-format","md":"/md/licensing/license-templates/user-key-format.md","headings":[],"sha256":"5c9be44902bcb5494d63023ded460fde87ea7f2f5c1c1c0150f76a291b5bbcc2"},{"path":"licensing/licensing-modes","title":"Licensing Modes","description":"In Babel Licensing, licensing modes define how software licenses are distributed, activated, and managed. The licensing mode you choose determines how your customers will interact with your software…","section":"licensing","url":"https://docs.babelfor.net/licensing/licensing-modes","md":"/md/licensing/licensing-modes.md","headings":["Primary Licensing Modes","Token-Based Extensions","Documentation Structure"],"sha256":"722cd177d54cfa26920ea162e1bc73873bd5fc6170bd976ac0406caf227a4648"},{"path":"licensing/licensing-modes/floating-license","title":"Floating License","description":"A floating license is a pool of licenses shared among the users or machines on a network. With Babel Licensing, you create floating licenses on the Babel Licensing Service using Babel Desktop. This…","section":"licensing","url":"https://docs.babelfor.net/licensing/licensing-modes/floating-license","md":"/md/licensing/licensing-modes/floating-license.md","headings":["Prerequisites","Creating a Floating License","Configuring a Client"],"sha256":"eff9759dcb95a55f6f97a2c7d0398d40fce92f94bc85ff46e404c8f8fc3b0cc5"},{"path":"licensing/licensing-modes/license-activation","title":"License Activation","description":"License activation is a commonly used method to control the distribution and usage of software licenses. Babel Licensing uses license activation to distribute and activate licenses for your .NET…","section":"licensing","url":"https://docs.babelfor.net/licensing/licensing-modes/license-activation","md":"/md/licensing/licensing-modes/license-activation.md","headings":["Prerequisites","Creating an Activation License","Configuring a Client"],"sha256":"b5729240fafa006bb5af080b6f016b514e6d06b4a46715470a5e55b9157681b3"},{"path":"licensing/licensing-modes/license-file","title":"License File","description":"License files control software licenses in disconnected or protected environments, where the application may not be able to reach the Babel Licensing Service. You can create a license file in two…","section":"licensing","url":"https://docs.babelfor.net/licensing/licensing-modes/license-file","md":"/md/licensing/licensing-modes/license-file.md","headings":["Prerequisites","Creating a License File","With Babel Desktop","With the lic Command Line","Configuring a Client","License Validation With License Manager"],"sha256":"deebe3a310e8180b47f6819960bba80d93c71022eea23d0247b649f1f0a87a6c"},{"path":"licensing/licensing-modes/license-tokens","title":"License Tokens","description":"In the context of the Babel Licensing Service, license tokens are used to manage licenses and track their usage. There are two types of license tokens: floating license tokens and license activation…","section":"licensing","url":"https://docs.babelfor.net/licensing/licensing-modes/license-tokens","md":"/md/licensing/licensing-modes/license-tokens.md","headings":["Floating License Tokens","License Activation Tokens","How tokens are counted","Freeing tokens","Limits and warnings","Reclaiming inactive activations","Upgrading from Server to Data Center"],"sha256":"5755e697ad53c408c19d1d2fc6b77f5425f9310fc256bd89fc486e0cbadf9115"},{"path":"licensing/reporting","title":"Reporting","description":"Babel Licensing provides a comprehensive reporting framework that enables you to collect, analyze, and monitor critical information about your licensed applications. Through automated reporting…","section":"licensing","url":"https://docs.babelfor.net/licensing/reporting","md":"/md/licensing/reporting.md","headings":["Why Reporting Matters","Report Types","How Reporting Works","Reporting Architecture","Configuration and Customization","Getting Started with Reporting","Best Practices","Report Analysis and Monitoring","Integration with Licensing Modes","Performance Considerations","Documentation Structure"],"sha256":"247b999ff6d50727e8a655339d08f0245473b5abb34c8ecc53289f9a9f23de85"},{"path":"licensing/reporting/exception-report","title":"Exception Reports","description":"Exception reporting is crucial in identifying and addressing application crashes and errors. Babel Licensing Services offers a powerful feature for collecting and analyzing application fault reports.","section":"licensing","url":"https://docs.babelfor.net/licensing/reporting/exception-report","md":"/md/licensing/reporting/exception-report.md","headings":["Application Exception Report Example"],"sha256":"965edce0bd935a182570687dc3253271ac647dcdaf10ec01c791fbd4de4556e5"},{"path":"licensing/reporting/licensing-report","title":"License Reports","description":"License reporting provides detailed insights into how your application uses licensed features, fields, and restrictions. By enabling license usage tracking, you can monitor feature adoption, validate…","section":"licensing","url":"https://docs.babelfor.net/licensing/reporting/licensing-report","md":"/md/licensing/reporting/licensing-report.md","headings":["Overview","Console Application Example","Enabling License Tracking","Sending License Reports","What Gets Tracked","Report Content","Configuration Options","Managing Tracked Data","Customizing Reports","Report Merging","Error Handling","Best Practices","Example: Complete License Tracking","Server-Side Analysis","Related Topics"],"sha256":"f8dcead9bd6cf630c7dfe6680f63649114670c7442cc904314173af28fde8e6b"},{"path":"licensing/reporting/custom-report","title":"Custom Reports","description":"In addition to built-in exception and license reports, Babel Licensing allows you to create custom reports tailored to your application's specific needs. Custom reports enable you to send any…","section":"licensing","url":"https://docs.babelfor.net/licensing/reporting/custom-report","md":"/md/licensing/reporting/custom-report.md","headings":["Overview","Console Application Example","Creating a Custom Report","Report Base Class","Sending Custom Reports","Real-World Examples","Adding Environment and System Information","Adding Charts to Reports","Report Encryption","Customizing Before Send","Report Structure","Server-Side Processing","Best Practices","Complete Example","Related Topics"],"sha256":"a60a5f252bf56471851966c845d62e9f80cad937a101b491c6939de6cf5f4b55"},{"path":"licensing/fips-compliance","title":"FIPS Compliance","description":"Babel Licensing runs on FIPS-enabled Linux hosts, and its license validation does not rely on any algorithm that FIPS disallows. This page explains how the library behaves on such hosts, a startup…","section":"licensing","url":"https://docs.babelfor.net/licensing/fips-compliance","md":"/md/licensing/fips-compliance.md","headings":["Background","How it can surface during license validation","Resolving it in containers","Babel Licensing Service on FIPS hosts","Verifying the environment"],"sha256":"68434ec1efc291eaeebeced5147f5bddbe10bd13516fd5b926e9ee85727866e7"},{"path":"licensing/command-line","title":"Command Line Tools (Server)","description":"The lic command line tool generates, signs, updates and verifies Babel licenses from a terminal, a script or a build, on Windows, Linux and macOS.","section":"licensing","url":"https://docs.babelfor.net/licensing/command-line","md":"/md/licensing/command-line.md","headings":["Quick Start","What You Can Do","Licensing the Tool","In This Section"],"sha256":"480b730da485dbcd15fc994ad365574f82bdfd294a3601cd071e84013deb1daf"},{"path":"licensing/command-line/babel-licensing-tool","title":"Babel Licensing Tool (Server)","description":"Babel.Licensing.Tool packages the lic command line as a dotnet tool, so you can generate and manage licenses from a terminal or a script on Windows, Linux and macOS with nothing but the .NET SDK…","section":"licensing","url":"https://docs.babelfor.net/licensing/command-line/babel-licensing-tool","md":"/md/licensing/command-line/babel-licensing-tool.md","headings":["What the Package Contains","When to Use the Tool","Installing the Tool","Licensing the Tool","Using the Tool","Troubleshooting"],"sha256":"a4a93889e71b4d8a56bf6ca8ea6d0054b8e837533f2d17eab017aefb6c0d21ba"},{"path":"licensing/command-line/reference","title":"Command Line Reference (Server)","description":"Every option of the lic command line, grouped as in the output of lic --help.","section":"licensing","url":"https://docs.babelfor.net/licensing/command-line/reference","md":"/md/licensing/command-line/reference.md","headings":["Miscellaneous","License","License Restrictions","Output Files","Input Files","Long and Short Options","Exit Codes"],"sha256":"9e6c4d5186b8441b815cd0bfb7759a80c685f645a7cf2a4645a70480b562a574"},{"path":"licensing/command-line/ai-friendly-mode","title":"AI-Friendly CLI Mode (Server)","description":"Starting with Babel Licensing 11.8, the lic command line can emit a structured, machine-readable output stream suited to CI pipelines, order systems and AI agents, matching the mode the obfuscator…","section":"licensing","url":"https://docs.babelfor.net/licensing/command-line/ai-friendly-mode","md":"/md/licensing/command-line/ai-friendly-mode.md","headings":["Flags","Schema: lic.cli.v1","Machine-readable --help","Machine-readable --version","Driving lic From an Agent","Backward compatibility"],"sha256":"c26648e6389919f1310d0841c8a2355f920b671f74fee1e268c30473c78dfd2d"},{"path":"licensing/command-line/msbuild-task","title":"Lic MSBuild Task (Server)","description":"The Lic task runs the lic command line from an MSBuild project, so a build can generate and sign licenses with the same properties as the command line.","section":"licensing","url":"https://docs.babelfor.net/licensing/command-line/msbuild-task","md":"/md/licensing/command-line/msbuild-task.md","headings":["Registering the Task","A Complete Example","Task Properties","Project Files"],"sha256":"7beb9938e1b2cbe1c93b2acc9ce66dfee2d223ecd060513f4ed0cb1bdb3b0645"},{"path":"licensing/wordpress-plugin","title":"WordPress Plugin (Server)","description":"The Babel Licensing Service WordPress Plugin enables seamless integration of the Babel Licensing Service with WordPress, facilitating robust license management directly within the WordPress admin…","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin","md":"/md/licensing/wordpress-plugin.md","headings":[],"sha256":"46e6e21215f544f2e7021cf20b39a676e8c581ea3bf05b04e9bc7b42b695dcc8"},{"path":"licensing/wordpress-plugin/configuration","title":"Configuration","description":"Once the Babel Licensing plugin is activated, you configure it from the WordPress dashboard.","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/configuration","md":"/md/licensing/wordpress-plugin/configuration.md","headings":["General","Enable Debugging","Licenses","Emails"],"sha256":"2567b287b34c40faf52ee10d993a81f6caa3d0736f21c549d8ed343152011006"},{"path":"licensing/wordpress-plugin/customers","title":"Customers","description":"The Customers page within the Babel Licensing WordPress Plugin is a central hub for managing customer data that is critical for the licensing process. This page provides administrators with a…","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/customers","md":"/md/licensing/wordpress-plugin/customers.md","headings":["Customer Edit"],"sha256":"fae379295dd2451facb1a5c0dd591c50fb9bc9473328ef09845232c231659677"},{"path":"licensing/wordpress-plugin/dashboard","title":"Dashboard","description":"The Babel Licensing Plugin Dashboard provides a comprehensive view of licensing activities and metrics within your WordPress environment. This dashboard is designed to give administrators quick…","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/dashboard","md":"/md/licensing/wordpress-plugin/dashboard.md","headings":["Sales and License Distribution Chart","License Tokens","License Summary Stats","Guide to Usage and Interpretation"],"sha256":"7ed157a61415b089de94a49cb03f5c60ce26976daa12e230f5464711d68d7eb0"},{"path":"licensing/wordpress-plugin/emails","title":"Emails","description":"The Emails page of the Babel Licensing WordPress Plugin is designed to manage email templates used for communicating with customers during various events within the WordPress system. This page allows…","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/emails","md":"/md/licensing/wordpress-plugin/emails.md","headings":["Email Edit"],"sha256":"2c45fe96376f17692b50dfe5a658c4375787f3e4ac41c343e0d9658c412386e0"},{"path":"licensing/wordpress-plugin/getting-started","title":"Getting Started","description":"Before you can take advantage of the WordPress integration, you'll need to install and configure the Babel Licensing WordPress Plugin.","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/getting-started","md":"/md/licensing/wordpress-plugin/getting-started.md","headings":["Installing Babel Licensing in WordPress","Updating Babel Licensing Plugin","Uninstall Babel Licensing Plugin","Deactivate Babel Licensing Plugin","Delete Babel Licensing Plugin"],"sha256":"3c0291873de1fdc6fec5733261d35fd1b154f4f77fc70fc8c539cc12fcf3486c"},{"path":"licensing/wordpress-plugin/licenses","title":"Licenses","description":"The Licenses page of the Babel Licensing WordPress Plugin provides a detailed interface for managing all software licenses stored in the Babel Licensing Database. This page displays a grid of…","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/licenses","md":"/md/licensing/wordpress-plugin/licenses.md","headings":["License Edit"],"sha256":"6d67fa399434cbc07d6c198b1c99f9d015acebd00307540cbbfa5f630d0936ab"},{"path":"licensing/wordpress-plugin/log","title":"Log","description":"The Log page within the Babel Licensing WordPress Plugin serves as a crucial tool for monitoring and diagnosing interactions with the Babel Licensing Service. This page provides a detailed log of all…","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/log","md":"/md/licensing/wordpress-plugin/log.md","headings":[],"sha256":"c5aa2ceb83794e150fa6f9020c1aa6a4402be337ff1516e961c9628c73ff1417"},{"path":"licensing/wordpress-plugin/my-account","title":"My Account","description":"When a customer navigates to My Account > Licenses, they will see a list of all purchased licensed products along with relevant details.","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/my-account","md":"/md/licensing/wordpress-plugin/my-account.md","headings":[],"sha256":"653416398a5ca354cd620be1980e02e0cbb4e6127daff281d1feeb2e00023792"},{"path":"licensing/wordpress-plugin/products","title":"Products","description":"Installing the Babel Licensing WordPress plugin introduces a new custom post type: Licensed Product. It is what connects WordPress to Babel Licensing.","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/products","md":"/md/licensing/wordpress-plugin/products.md","headings":["Licensing Product","Product Edit","Bind Email To Actions","Product Attributes"],"sha256":"27d5a0d80aa0968935b66cd6f290a779ac45e6c3bc3387a58a185e2080e0aca5"},{"path":"licensing/wordpress-plugin/templates","title":"Templates","description":"The Templates page serves as a centralized hub for managing License Templates. These templates define the structure and terms for the licenses that can be issued, ensuring consistency and compliance…","section":"licensing","url":"https://docs.babelfor.net/licensing/wordpress-plugin/templates","md":"/md/licensing/wordpress-plugin/templates.md","headings":["Template Edit"],"sha256":"2eee5567bc5f80a9b696f1fd1106d022b61fb2b2e7283bd8da48bdc3283815a2"},{"path":"licensing/web-application","title":"Web Application (Data Center)","description":"The Babel Licensing Data Center edition unlocks an administrative web interface for managing the Babel Licensing Service.","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application","md":"/md/licensing/web-application.md","headings":["Software Application Overview"],"sha256":"1ffb78416b5be8c878d315532c9b67f283a6bbbf343be88a9dbb3105b3f1e242"},{"path":"licensing/web-application/api-keys","title":"API Keys (Data Center)","description":"The Babel Licensing Service provides an API key management system that allows users to securely generate, manage, and control API keys for accessing the Babel Licensing Service Web API Interface. API…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/api-keys","md":"/md/licensing/web-application/api-keys.md","headings":["Listing API Keys","Creating and Editing API Keys"],"sha256":"d18ef5cd0a76b32afcae1695df986066e8237837557b7522858f6eeab1784a3d"},{"path":"licensing/web-application/dashboard","title":"Dashboard (Data Center)","description":"The Babel Licensing Dashboard provides a comprehensive and customizable interface for managing licensing operations efficiently. Designed with flexibility in mind, the dashboard allows users to add…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/dashboard","md":"/md/licensing/web-application/dashboard.md","headings":["Widgets","If the map is empty"],"sha256":"09594b9cce8aa7d9e5b21616fb4b711e179d3c557ef59f2a72f835cf0b68ee1e"},{"path":"licensing/web-application/licenses","title":"Licenses (Data Center)","description":"The Licenses page in the Babel Licensing Web Application is where you manage and monitor all software licenses in your system. This page displays licensing information in a tabular format, with each…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/licenses","md":"/md/licensing/web-application/licenses.md","headings":["Main Features","Action Buttons","License Details and Activity","Viewing Licenses","Create a License","Managing Licenses","Monitoring License Activity","Search and Filter Capabilities","Editing a License","Tips for Efficient License Management","Template defaults"],"sha256":"d7f739fdd1b46e65014148bd91d204b89954802c90f94ab22c4b7d42c9392d35"},{"path":"licensing/web-application/log","title":"Log (Data Center)","description":"The Log section of the Babel Licensing Web Application provides a comprehensive monitoring and troubleshooting tool that records all system activities and events. This page displays detailed…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/log","md":"/md/licensing/web-application/log.md","headings":["Overview","Activity Graph","Date Selection","Log Management Controls","Log Entry Table","Detailed Entry View"],"sha256":"59bf51f10e9829693d519902ff3d641fa556177c942a6da0bb45f23e38c58b57"},{"path":"licensing/web-application/orders","title":"Orders (Data Center)","description":"The Orders page in Babel Licensing Service provides a comprehensive view of all purchase orders in the system. This interface allows administrators to track, manage, and process orders efficiently.","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/orders","md":"/md/licensing/web-application/orders.md","headings":["Key Features","Search and Filter","Column Information","Order Management Actions","Tips for Effective Order Management","Customer and products"],"sha256":"f17fd87b0154afd85f9f03dfe2f3e8bb9fe3bce28537a96e900e9161614ae0e2"},{"path":"licensing/web-application/products","title":"Products (Data Center)","description":"The Products view lists every software product that can be licensed through Babel Licensing. Administrators use it to create, edit and manage product entries, which templates and licenses are built…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/products","md":"/md/licensing/web-application/products.md","headings":["Overview","Action Buttons","Product List Columns","Row Actions","Creating a New Product","Managing Existing Products","Product-Template Relationship"],"sha256":"62cafe3fffb05579ecb6bed47def8b8ef3365ffe2769468be78ad359749ed38e"},{"path":"licensing/web-application/reports","title":"Reports (Data Center)","description":"The Reports page in Babel Licensing Web Application lists all the reports submitted by licensed applications and lets you manage them. Use it to track application health, license usage patterns…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/reports","md":"/md/licensing/web-application/reports.md","headings":["Overview","Report Types","Interface Components","Search and Filtering","Actions","Using the Reports Page","Filtering by Report Type","Analyzing Report Details","What Gets Reported","Exception Report Details View","Report Information Section","Properties Grid","Detailed Exception Information","Additional Tabs","Navigation and Actions","Using the Report Details View","Exception Report Benefits","What Gets Tracked","License Report Details View","Report Merging","License Report Benefits","Common Custom Report Types","Custom Report Details View","Custom Report Benefits","Searching and Filtering","Deleting Reports","Exporting Report Data","Overall Benefits","Related Documentation","Custom report charts","Deobfuscating exception reports"],"sha256":"c94703ac80d8d93e24f351f589339c7a3f80464ed344d0999f6d3b29ce512b99"},{"path":"licensing/web-application/resources","title":"Resources (Data Center)","description":"The Resources page in the Babel Licensing Web Application provides a central repository for managing various digital assets used throughout the licensing service. This page allows you to organize…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/resources","md":"/md/licensing/web-application/resources.md","headings":["Overview","Page Actions","Resource Information","Resource Types","Resource Management","Adding a New Resource","Editing Resources","Using Resources in the System","Best Practices"],"sha256":"168e834c28156cfc0ed4de355f9382a86376958a22158183e478d2d3793adb60"},{"path":"licensing/web-application/running-locally","title":"Running Locally (Data Center)","description":"The Babel Licensing Service decrypts the web application scripts in memory at run time, and only when its license includes the web application feature. Copying the files from the service wwwroot…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/running-locally","md":"/md/licensing/web-application/running-locally.md","headings":["Managing a Remote Service","Running the Service as API Only","API Key Generation","Troubleshooting","Security Considerations"],"sha256":"c3f31caa2bdf3c65bd661561390d74f14b56b13c3fda66f25c82124f4a053d7b"},{"path":"licensing/web-application/sign-in","title":"Sign In (Data Center)","description":"The Sign In page is the entry point to the Babel Licensing Web Application, serving as the security gateway that authenticates users before granting access to the system. This clean, minimalist…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/sign-in","md":"/md/licensing/web-application/sign-in.md","headings":["Accessing the Sign In Page","Session duration"],"sha256":"fe171998cc5429e06b5b0a5869ee3a76843be1a1f83209262b5ca393f9b73a53"},{"path":"licensing/web-application/templates","title":"Templates (Data Center)","description":"The License Templates view in Babel Licensing is where you manage the license templates used to create and issue licenses to your customers. These templates define the standard parameters and…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/templates","md":"/md/licensing/web-application/templates.md","headings":["Overview","Action Buttons","Template List Columns","Row Actions","License Modes","Format Options","Creating a New Template","Managing Existing Templates","Editing License Templates in Babel Licensing","Creating Custom Restrictions","Best Practices"],"sha256":"2a7aebbd593d0ce5e34b5f77ff4ee39616bca79e4db78700fc003133bbaf20b9"},{"path":"licensing/web-application/webhooks","title":"Webhooks (Data Center)","description":"Webhooks allow external applications to receive real-time notifications when specific events occur in the Babel Licensing Service. Use them to connect your existing systems, automate workflows and…","section":"licensing","url":"https://docs.babelfor.net/licensing/web-application/webhooks","md":"/md/licensing/web-application/webhooks.md","headings":["Managing Webhooks","Adding a New Webhook","Editing a Webhook","Deleting a Webhook","Testing a Webhook","Webhook Event Details","Supported Events","Webhook Payload Reference","Webhook Delivery and Retry Logic","Securing Webhooks","Implementing a Webhook Receiver","Best Practices for Receiving Webhooks","Processing Webhook Events","Troubleshooting"],"sha256":"39aa789726606fe4ad088b617b84246a2061cf5dbfb3b42edac44e004fc59615"},{"path":"licensing/ai-integration","title":"AI Integration","description":"Integrate AI assistants with Babel Licensing using the Model Context Protocol","section":"licensing","url":"https://docs.babelfor.net/licensing/ai-integration","md":"/md/licensing/ai-integration.md","headings":["Two ways to integrate","What is AI Integration?","How It Works","Benefits of AI Integration","Use Cases","Getting Started","Example Conversations","Advanced Capabilities","Security Considerations","Supported AI Clients","Learn More","Support"],"sha256":"e0bce570a44ec90a4ee4668926fc33a65005bb76e0fd4702a5f4019db15e3683"},{"path":"licensing/ai-integration/mcp-server","title":"MCP Server","description":"Use AI assistants to interact with Babel Licensing API through the Model Context Protocol","section":"licensing","url":"https://docs.babelfor.net/licensing/ai-integration/mcp-server","md":"/md/licensing/ai-integration/mcp-server.md","headings":["What is MCP?","Features","Requirements","Installation","Manual Installation","Configuration","Usage","Logging","Available Tools","Working with the API","Examples","Troubleshooting","API Documentation","Support","Resources","Version History"],"sha256":"5069b9045c304b7590ab3ade380c1281d30cbde297ea186c7f5f9f9982e4d86e"},{"path":"licensing/examples/summary","title":"Examples","description":"A collection of practical use cases and examples that will guide you in straightforwardly integrating Babel Licensing functionalities into your applications.","section":"licensing","url":"https://docs.babelfor.net/licensing/examples/summary","md":"/md/licensing/examples/summary.md","headings":["License Files And Serials","Licensing with Code Encryption"],"sha256":"0b222f03e0ebfb9a2c96029dec034f191b9ebe6319a538adc1aeb7d5a0a4517b"},{"path":"licensing/examples/trial-serial-license","title":"Trial Serial License","description":"Trial licenses allow software vendors to offer time-limited trial versions of their applications to potential customers.","section":"licensing","url":"https://docs.babelfor.net/licensing/examples/trial-serial-license","md":"/md/licensing/examples/trial-serial-license.md","headings":["Code Example","Trial License Generation","Trial License Validation","Execution of Encrypted Code"],"sha256":"2ff8e34da53e3172e94b46e5f0afdd149562a00e7b2c71fd325d4981cc9062ca"},{"path":"licensing/examples/feature-based-licenses","title":"Feature Based Licenses","description":"Babel Obfuscator includes a licensing feature that allows you to generate feature-based licenses for your obfuscated code. This means that you can create licenses that unlock specific features or…","section":"licensing","url":"https://docs.babelfor.net/licensing/examples/feature-based-licenses","md":"/md/licensing/examples/feature-based-licenses.md","headings":[],"sha256":"fc233e2b5b71aed49117a6ed7412aca2c6ff2910dcaa805da49cffe00821cacc"},{"path":"licensing/examples/license-bound-code-encryption","title":"License-Bound Code Encryption","description":"Make a protected feature cryptographically dependent on a valid license by storing the code-encryption password inside the license itself.","section":"licensing","url":"https://docs.babelfor.net/licensing/examples/license-bound-code-encryption","md":"/md/licensing/examples/license-bound-code-encryption.md","headings":["Code Example","The Protected Method","Where the Password Lives","Minting the License","Running It","Why This Is Stronger"],"sha256":"4b9366c5c94538ffdfd689eaa04d3b38483695a441b8fe7a3a61cf6bf92dd279"},{"path":"licensing/examples/external-encrypted-code","title":"Feature as an External Encrypted File","description":"Ship a premium feature as encrypted code that lives outside the application and is unlocked only when the customer also holds a license that grants it.","section":"licensing","url":"https://docs.babelfor.net/licensing/examples/external-encrypted-code","md":"/md/licensing/examples/external-encrypted-code.md","headings":["Code Example","External Encryption","Two License-Gated Hooks","Running It"],"sha256":"911a6fb3bba37c54d56b9a0266f6a3a1147377fa825da35cbb44edb907bb5b22"},{"path":"licensing/examples/subscription-license","title":"Subscription License with Encrypted Pro Code","description":"A time-limited subscription license with a grace period, where the subscription-only code is protected with Babel Obfuscator Code Encryption.","section":"licensing","url":"https://docs.babelfor.net/licensing/examples/subscription-license","md":"/md/licensing/examples/subscription-license.md","headings":["Code Example","Two Dates: Renewal and Hard Cutoff","The Encrypted Pro Feature","Running It"],"sha256":"13b219eec431554c8cf0021a80d1f72d77a1f0d73241c147438a23df03b5488e"},{"path":"licensing/examples/license-activation-in-maui","title":"License Activation in MAUI","description":"In this guide, we'll explore how to implement license activation in a .NET MAUI application using Babel Licensing. This approach allows you to securely bind licenses to specific devices, ensuring…","section":"licensing","url":"https://docs.babelfor.net/licensing/examples/license-activation-in-maui","md":"/md/licensing/examples/license-activation-in-maui.md","headings":["Platform Specific System Information","Registering Platform-Specific Implementations","Configuring Babel Licensing in MAUI","Creating the LicensingService","Implementing License Activation in the UI","Adding Exception Reporting","Best Practices for MAUI License Activation"],"sha256":"f2ef6ed3548984f857abca47e31609a0d6de46c5ee8f88e481ab737281601545"},{"path":"desktop","title":"Babel Desktop","description":"Babel Desktop, the cross-platform application for Babel Obfuscator projects and Babel Licensing management","section":"desktop","url":"https://docs.babelfor.net/desktop","md":"/md/desktop.md","headings":["License requirements","Getting Started","The Application Window","Work Recovery"],"sha256":"b60cb4619d65fb5b66429dd562cf4dbd11e34a114e2ce9a3cc69500e84ec5c1b"},{"path":"desktop/getting-started/install","title":"Install","description":"Install Babel Desktop on Windows, macOS and Linux","section":"desktop","url":"https://docs.babelfor.net/desktop/getting-started/install","md":"/md/desktop/getting-started/install.md","headings":["License requirements","Application Integrity","Proxy and Certificates"],"sha256":"0f31dbbc6c13b24752332502122d12d077f3400891f5fa7e53e853afae152645"},{"path":"desktop/getting-started/product-activation","title":"Product Activation","description":"Load a Babel license in Babel Desktop from a license file, an activation key or a floating license","section":"desktop","url":"https://docs.babelfor.net/desktop/getting-started/product-activation","md":"/md/desktop/getting-started/product-activation.md","headings":["License requirements","Troubleshooting"],"sha256":"a6ab7ffe7b315ce8bffce70457ab27e382a905c945afac09cc29d327d259638f"},{"path":"desktop/obfuscation-projects","title":"Obfuscation Projects","description":"Create and run Babel Obfuscator projects in Babel Desktop and review the protection statistics","section":"desktop","url":"https://docs.babelfor.net/desktop/obfuscation-projects","md":"/md/desktop/obfuscation-projects.md","headings":["Creating a Project","The Project Canvas","Setup Commands","Target Settings","Running the Project","Run Results","Decoding Stack Traces"],"sha256":"eb3453ed53c5d361e296551342e7a5317f7f7407272e6ccb11e7e2b42579b95b"},{"path":"desktop/stack-decoder","title":"Stack Decoder","description":"Decode obfuscated stack traces in Babel Desktop with the XML map files produced by the obfuscation","section":"desktop","url":"https://docs.babelfor.net/desktop/stack-decoder","md":"/md/desktop/stack-decoder.md","headings":[],"sha256":"81f37f8af136ed2b292306da4b8a43e694c7bdf7bbd5260b0243eb6e79f264bd"},{"path":"desktop/licensing","title":"Licensing","description":"Manage a Babel Licensing Service from Babel Desktop","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing","md":"/md/desktop/licensing.md","headings":["Availability","Pages in This Section"],"sha256":"bc8d11ec1aca2039893196db6abdcaad1fcfd3d5bd5a273106dd6c7bb8bed56b"},{"path":"desktop/licensing/connecting","title":"Connecting to a Service","description":"Connect Babel Desktop to a Babel Licensing Service with an API key and connection profiles","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/connecting","md":"/md/desktop/licensing/connecting.md","headings":["Creating an API Key","Connection Profiles","Self-Signed Certificates"],"sha256":"4c21ad9d1f046841aceba9de2e7ac812d9f4741f0bbc4792e829732a5da6a052"},{"path":"desktop/licensing/roles-and-permissions","title":"Roles and Permissions","description":"How service roles and API key permissions control the Licensing views and actions of Babel Desktop","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/roles-and-permissions","md":"/md/desktop/licensing/roles-and-permissions.md","headings":[],"sha256":"9df1c61268e396b5f7924b9b523be6a9bc7e3d5d7e719659b8d5d8660fbff0f1"},{"path":"desktop/licensing/dashboard","title":"Dashboard","description":"The Licensing Overview dashboard, activity globe and IP geolocation in Babel Desktop","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/dashboard","md":"/md/desktop/licensing/dashboard.md","headings":["Geographic Activity","IP Geolocation"],"sha256":"7ef97361b508279d87c324c9384753058410d32917bbaf72b600acb07512e603"},{"path":"desktop/licensing/working-with-records","title":"Working with Records","description":"Lists, detail pages and forms shared by every Licensing view of Babel Desktop","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/working-with-records","md":"/md/desktop/licensing/working-with-records.md","headings":[],"sha256":"96d0b2d0c263df2ed65f5a7ec90d4d48b93d5de8c8e8c46380a4fa1ce2512196"},{"path":"desktop/licensing/sales","title":"Sales","description":"Customers, products, releases and orders in Babel Desktop","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/sales","md":"/md/desktop/licensing/sales.md","headings":[],"sha256":"394fac76ce8758d4937828e4d3b884b8cb547ab3b9fa29eb9e4012244704443d"},{"path":"desktop/licensing/licenses","title":"Licenses","description":"Licenses, license templates, license tokens and sign keys in Babel Desktop","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/licenses","md":"/md/desktop/licensing/licenses.md","headings":[],"sha256":"460625860afed1031af2a01226a398008263a625c089d89ced0fbe3947f0b0b1"},{"path":"desktop/licensing/reports","title":"Reports","description":"Diagnostic reports and stack trace decoding in Babel Desktop","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/reports","md":"/md/desktop/licensing/reports.md","headings":[],"sha256":"efd4eda6115102faa57468982f77a08aeaba331fb271d6a5b450c737c0552b83"},{"path":"desktop/licensing/operations","title":"Operations","description":"Service log, license traces and webhooks in Babel Desktop","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/operations","md":"/md/desktop/licensing/operations.md","headings":[],"sha256":"836916b5364f49d57d0d3e125816c192a1239d2e2a2c320ce43b0a67c0ecd780"},{"path":"desktop/licensing/administration","title":"Administration","description":"Users, API keys, server settings and server info in Babel Desktop","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/administration","md":"/md/desktop/licensing/administration.md","headings":[],"sha256":"7eeca9b917406a34bcc93728ff7ecece77a3e4f278386e1444b2b290d9e95c4b"},{"path":"desktop/licensing/settings-and-automation","title":"Settings and Automation","description":"Settings of a Licensing connection and automation through the Babel Desktop MCP server","section":"desktop","url":"https://docs.babelfor.net/desktop/licensing/settings-and-automation","md":"/md/desktop/licensing/settings-and-automation.md","headings":["Connection Settings","Automation"],"sha256":"9a92d8c363ef339dfc9cafbb7e0c7f5528b9399633ffdc1e5041eff89044bd8d"},{"path":"desktop/extensions","title":"Extensions","description":"Browse, install, update and manage Babel Desktop extensions","section":"desktop","url":"https://docs.babelfor.net/desktop/extensions","md":"/md/desktop/extensions.md","headings":["The Extensions View","Development Versions","Installing from a File"],"sha256":"195a153934ed91d13dd3e16c384c5fad3077e48a22050ec93b2db92d6b214c73"},{"path":"desktop/themes","title":"Themes","description":"Switch the Babel Desktop theme and create your own theme extension","section":"desktop","url":"https://docs.babelfor.net/desktop/themes","md":"/md/desktop/themes.md","headings":["Choosing a Theme","Sample Themes","Creating a Theme"],"sha256":"0be6e2cb9cf907f1fc35f087206675927933318907ef0e40f7666c5b08080e3c"},{"path":"desktop/languages","title":"Languages","description":"Change the Babel Desktop interface language and install language packages","section":"desktop","url":"https://docs.babelfor.net/desktop/languages","md":"/md/desktop/languages.md","headings":["Changing the Language","Language Packages","Extension Translations"],"sha256":"2c019a512ddd5df5204ce5085323cf21e28c31b3b3382006bfbcbab6bd2280f6"},{"path":"desktop/mcp-server","title":"MCP Server","description":"Let an AI assistant operate Babel Desktop through its local Model Context Protocol server","section":"desktop","url":"https://docs.babelfor.net/desktop/mcp-server","md":"/md/desktop/mcp-server.md","headings":["Enabling the Server","Connecting a Client","What the Assistant Can Do","Babel Documentation Tools","Security","Troubleshooting"],"sha256":"2fc8e4e4f2d09c3c1e7e0bc65c47c0094432ce74fb8429da52db86e7c02af43d"},{"path":"desktop/updates","title":"Updates","description":"How Babel Desktop checks for, downloads and installs new versions","section":"desktop","url":"https://docs.babelfor.net/desktop/updates","md":"/md/desktop/updates.md","headings":["How Updates Work","Update Settings","Development Versions","What Babel Desktop Reports","License and Maintenance","Troubleshooting"],"sha256":"794d69eb740422eccf4666d1dbedca621121ad81c7861ddf8f505fa2f919ed53"},{"path":"api","title":"API Reference","description":"The Babel Licensing Service exposes a REST API to manage licenses, products, customers, orders, releases and the rest of the licensing data, to run the licensing operations of protected applications…","section":"api","url":"https://docs.babelfor.net/api","md":"/md/api.md","headings":["Base URL and Versioning","Content Types","Authentication","Roles and Access","Anonymous Endpoints","Querying Lists","Updating Resources","Errors","Rate Limiting","Webhooks","API Sections"],"sha256":"b3e5f47e3fa8c4f70afb8b67650c090fee100bda339f2cddaeb57d740c14c78f"},{"path":"api/authentication","title":"Authentication","description":"POST /v1/auth/login","section":"api","url":"https://docs.babelfor.net/api/authentication","md":"/md/api/authentication.md","headings":["POST /v1/auth/login","GET /v1/auth/user","POST /v1/auth/user","GET /v1/auth/session","POST /v1/auth/logout"],"sha256":"adeb48b6d5406171639cf4d5da35ee9a64669cb730a45f77fb765bc5c54eff03"},{"path":"api/licensing-operations","title":"Licensing Operations","description":"The operations a protected application calls at run time: activation, floating seats, validation and license information.","section":"api","url":"https://docs.babelfor.net/api/licensing-operations","md":"/md/api/licensing-operations.md","headings":["Pages","Endpoints"],"sha256":"80416660c48f95498ebb34203876ea842471f39ae5642790d5cf578eeeb14f16"},{"path":"api/licensing-operations/activation","title":"Activation","description":"POST /v1/license/activate","section":"api","url":"https://docs.babelfor.net/api/licensing-operations/activation","md":"/md/api/licensing-operations/activation.md","headings":["POST /v1/license/activate","POST /v1/license/deactivate"],"sha256":"0bd06b3b9b653e2696988ecbacbe0a498101dc607ec59f869813a542a6faae0c"},{"path":"api/licensing-operations/floating","title":"Floating Licenses","description":"POST /v1/license/request","section":"api","url":"https://docs.babelfor.net/api/licensing-operations/floating","md":"/md/api/licensing-operations/floating.md","headings":["POST /v1/license/request","POST /v1/license/release","POST /v1/license/heartbeat"],"sha256":"cd61d60b908d817c728230ae8cf70fa477bac3069c97ddf3f47a768e4703bddc"},{"path":"api/licensing-operations/validation","title":"Validation and Info","description":"POST /v1/license/validate","section":"api","url":"https://docs.babelfor.net/api/licensing-operations/validation","md":"/md/api/licensing-operations/validation.md","headings":["POST /v1/license/validate","POST /v1/license/info"],"sha256":"9186d06b50c0bb954747d4d175591836666b2bc313a162339d83a069f22834c3"},{"path":"api/management-api","title":"Management API","description":"The Management API administers the licensing data: customers, contacts, products, orders, licenses, license tokens and templates, assemblies, resources, received reports, users, roles, API keys, the…","section":"api","url":"https://docs.babelfor.net/api/management-api","md":"/md/api/management-api.md","headings":["Pages","Endpoints"],"sha256":"7cc563710c90430ab6c99dac8f1919d09d4a064d7e1028db4d6b4aa905b172c1"},{"path":"api/management-api/customers","title":"Customers","description":"GET /v1/customers","section":"api","url":"https://docs.babelfor.net/api/management-api/customers","md":"/md/api/management-api/customers.md","headings":["GET /v1/customers","POST /v1/customers","PUT /v1/customers","GET /v1/customers/{customerId}/contacts","GET /v1/customers/{customerId}/orders","GET /v1/customers/{customerId}/licenses","DELETE /v1/customers/{customerId}"],"sha256":"f14f72a13857640b61bdc1aebc7de7d1faf4afdf825f1bfbd930c7ff0703bb20"},{"path":"api/management-api/contacts","title":"Contacts","description":"GET /v1/contacts","section":"api","url":"https://docs.babelfor.net/api/management-api/contacts","md":"/md/api/management-api/contacts.md","headings":["GET /v1/contacts","POST /v1/contacts","PUT /v1/contacts","DELETE /v1/contacts/{contactId}"],"sha256":"36a524b8600a90b007f31aed411d9a0fe670c8a4d1f332314ce69717b129fb89"},{"path":"api/management-api/products","title":"Products","description":"GET /v1/products","section":"api","url":"https://docs.babelfor.net/api/management-api/products","md":"/md/api/management-api/products.md","headings":["GET /v1/products","POST /v1/products","PUT /v1/products","DELETE /v1/products/{productId}","GET /v1/products/{productId}/orders"],"sha256":"50be47812df96c3b0a4583d52983166a56c50e664159356edfe44922f8a7ada9"},{"path":"api/management-api/orders","title":"Orders","description":"GET /v1/orders","section":"api","url":"https://docs.babelfor.net/api/management-api/orders","md":"/md/api/management-api/orders.md","headings":["GET /v1/orders","POST /v1/orders","PUT /v1/orders","DELETE /v1/orders/{orderId}"],"sha256":"754bee939ebdf7b1d46de39143cafdfc9cfa69e4378bbd43ccd1cc83b56f11ac"},{"path":"api/management-api/order-products","title":"Order Products and Licenses","description":"GET /v1/orders/\\{orderId\\}/products","section":"api","url":"https://docs.babelfor.net/api/management-api/order-products","md":"/md/api/management-api/order-products.md","headings":["GET /v1/orders/{orderId}/products","POST /v1/orders/{orderId}/products/{productId}","PUT /v1/orders/{orderId}/products/{productId}","DELETE /v1/orders/{orderId}/products/{productId}","GET /v1/orders/{orderId}/licenses"],"sha256":"be556a47df7011a5c79e8f2945bd0d038353c20be1ae23682987ce3c2443c98b"},{"path":"api/management-api/licenses","title":"Licenses","description":"GET /v1/licenses","section":"api","url":"https://docs.babelfor.net/api/management-api/licenses","md":"/md/api/management-api/licenses.md","headings":["GET /v1/licenses","POST /v1/licenses","PUT /v1/licenses","DELETE /v1/licenses/{licenseId}"],"sha256":"34ea9676afdf7d6cf374c3eb1b062faca9933c2dd4a4e1316f667cae98705481"},{"path":"api/management-api/license-tokens","title":"License Tokens","description":"GET /v1/license-tokens","section":"api","url":"https://docs.babelfor.net/api/management-api/license-tokens","md":"/md/api/management-api/license-tokens.md","headings":["GET /v1/license-tokens","GET /v1/licenses/{licenseId}/tokens","POST /v1/licenses/{licenseId}/tokens","DELETE /v1/licenses/{licenseId}/tokens/{tokenId}"],"sha256":"59360bc294b788d2da6a9c5b5ca49a4f198d1601f03832b9739e87093b7eac84"},{"path":"api/management-api/license-traces","title":"License Traces","description":"GET /v1/license-traces","section":"api","url":"https://docs.babelfor.net/api/management-api/license-traces","md":"/md/api/management-api/license-traces.md","headings":["GET /v1/license-traces","DELETE /v1/license-traces","POST /v1/license-traces/geolocation"],"sha256":"41cd2326afd4201eed5407c5c647a0f6461ec6fe2504054880d5e0e5d368515d"},{"path":"api/management-api/license-templates","title":"License Templates","description":"GET /v1/license-templates","section":"api","url":"https://docs.babelfor.net/api/management-api/license-templates","md":"/md/api/management-api/license-templates.md","headings":["GET /v1/license-templates","POST /v1/license-templates","PUT /v1/license-templates","GET /v1/license-templates/{templateId}/licenses","DELETE /v1/license-templates/{templateId}"],"sha256":"3786eb026836a5a492fe9a3a15aa854d495083ee99746eccd38ebd04e4d2cb43"},{"path":"api/management-api/assemblies","title":"Assemblies","description":"GET /v1/assemblies","section":"api","url":"https://docs.babelfor.net/api/management-api/assemblies","md":"/md/api/management-api/assemblies.md","headings":["GET /v1/assemblies","POST /v1/assemblies","PUT /v1/assemblies","DELETE /v1/assemblies/{assemblyId}"],"sha256":"953002b4cd4ba63c9fd23e872a8458753e5b9c23b5f7f419ed68b336f5ae9d15"},{"path":"api/management-api/resources","title":"Resources","description":"GET /v1/resources","section":"api","url":"https://docs.babelfor.net/api/management-api/resources","md":"/md/api/management-api/resources.md","headings":["GET /v1/resources","POST /v1/resources","PUT /v1/resources","DELETE /v1/resources/{resourceId}"],"sha256":"272c2e0a014478ccc0166c2007efaef1ca5782fa95ae1b142e9cf36c59c28204"},{"path":"api/management-api/reports","title":"Received Reports","description":"GET /v1/reports","section":"api","url":"https://docs.babelfor.net/api/management-api/reports","md":"/md/api/management-api/reports.md","headings":["GET /v1/reports","POST /v1/reports/geolocation","DELETE /v1/reports/{reportId}"],"sha256":"369cc75739c6600f9501998fb0b6abfdbd452f39f727bd26b7e0a1f4206ec56e"},{"path":"api/management-api/users","title":"Users","description":"GET /v1/users","section":"api","url":"https://docs.babelfor.net/api/management-api/users","md":"/md/api/management-api/users.md","headings":["GET /v1/users","POST /v1/users","PUT /v1/users","DELETE /v1/users/{userId}","GET /v1/users/{userId}/settings","POST /v1/users/{userId}/settings","PUT /v1/users/{userId}/settings","DELETE /v1/users/{userId}/settings/{settingId}"],"sha256":"9e060db0e16a0f9db154378a9e974c98df83c01213c5f4c2bf63147ba52094cb"},{"path":"api/management-api/roles","title":"Roles","description":"GET /v1/roles","section":"api","url":"https://docs.babelfor.net/api/management-api/roles","md":"/md/api/management-api/roles.md","headings":["GET /v1/roles","GET /v1/users/{userId}/roles","POST /v1/users/{userId}/roles","DELETE /v1/users/{userId}/roles"],"sha256":"a597e2a93acfbbe102a76dbc6c7834ca23038b29e5525e090e18f99b5ec6e8cd"},{"path":"api/management-api/api-keys","title":"API Keys","description":"GET /v1/api-keys","section":"api","url":"https://docs.babelfor.net/api/management-api/api-keys","md":"/md/api/management-api/api-keys.md","headings":["GET /v1/api-keys","POST /v1/api-keys","PUT /v1/api-keys","DELETE /v1/api-keys/{apiKeyId}"],"sha256":"be77ef1f525cc916e922e8e051cb8435995ea77d67e933fb7415c9de250f2d92"},{"path":"api/management-api/log","title":"Log","description":"GET /v1/log/levels","section":"api","url":"https://docs.babelfor.net/api/management-api/log","md":"/md/api/management-api/log.md","headings":["GET /v1/log/levels","GET /v1/log","DELETE /v1/log"],"sha256":"378dbeee4f33f638cf450d0c7ee7f96913faf043d464e65566851b16d5e288a6"},{"path":"api/management-api/settings","title":"Settings and Server Info","description":"GET /v1/settings","section":"api","url":"https://docs.babelfor.net/api/management-api/settings","md":"/md/api/management-api/settings.md","headings":["GET /v1/settings","PUT /v1/settings","GET /v1/info"],"sha256":"05dc462a47c1a862da81ab10b4097988a59fe1beb8db70bf6b637f996f9b0ca1"},{"path":"api/management-api/email","title":"Email","description":"POST /v1/email/send","section":"api","url":"https://docs.babelfor.net/api/management-api/email","md":"/md/api/management-api/email.md","headings":["POST /v1/email/send","POST /v1/email/license"],"sha256":"268593ece916137adb259ef6b00605c06ec9a775e92f99a85e2c4ede669aecb0"},{"path":"api/product-releases","title":"Product Releases","description":"A product release describes one version of a product: version, releaseDate, channel (stable or insider), public and requiresMaintenance. A release has assemblies that ship with it, license templates…","section":"api","url":"https://docs.babelfor.net/api/product-releases","md":"/md/api/product-releases.md","headings":["Pages","Endpoints"],"sha256":"2b55c8c97b4df613d8c9bf9ef7f01291743a8941d0e5a129f0bd0ab7b0d86b76"},{"path":"api/product-releases/releases","title":"Releases","description":"GET /v1/products/\\{productId\\}/releases","section":"api","url":"https://docs.babelfor.net/api/product-releases/releases","md":"/md/api/product-releases/releases.md","headings":["GET /v1/products/{productId}/releases","POST /v1/products/{productId}/releases","PUT /v1/products/{productId}/releases","DELETE /v1/products/{productId}/releases/{releaseId}"],"sha256":"478b09c11fbed187e4c4fd04cb233dee5521f89c665135d3924bf4e4b3552a7a"},{"path":"api/product-releases/release-assemblies","title":"Release Assemblies","description":"GET /v1/products/\\{productId\\}/releases/\\{releaseId\\}/assemblies","section":"api","url":"https://docs.babelfor.net/api/product-releases/release-assemblies","md":"/md/api/product-releases/release-assemblies.md","headings":["GET /v1/products/{productId}/releases/{releaseId}/assemblies","POST /v1/products/{productId}/releases/{releaseId}/assemblies","PUT /v1/products/{productId}/releases/{releaseId}/assemblies","DELETE /v1/products/{productId}/releases/{releaseId}/assemblies/{assemblyId}"],"sha256":"149f30516e08246bbda0970590cf7855f5b9d5a25ac87cefeac4a60230f08bfd"},{"path":"api/product-releases/release-license-templates","title":"Release License Templates","description":"GET /v1/products/\\{productId\\}/releases/\\{releaseId\\}/license-templates","section":"api","url":"https://docs.babelfor.net/api/product-releases/release-license-templates","md":"/md/api/product-releases/release-license-templates.md","headings":["GET /v1/products/{productId}/releases/{releaseId}/license-templates"],"sha256":"16a592fd029b408e486dbd8d07ccb0ef73aeafe55672b4cef2ff9029e81a87ac"},{"path":"api/product-releases/downloads","title":"Downloads","description":"GET /v1/products/\\{productId\\}/releases/\\{releaseId\\}/downloads","section":"api","url":"https://docs.babelfor.net/api/product-releases/downloads","md":"/md/api/product-releases/downloads.md","headings":["GET /v1/products/{productId}/releases/{releaseId}/downloads","POST /v1/products/{productId}/releases/{releaseId}/downloads","PUT /v1/products/{productId}/releases/{releaseId}/downloads","DELETE /v1/products/{productId}/releases/{releaseId}/downloads/{downloadId}","POST /v1/products/{productId}/releases/{releaseId}/downloads/verify"],"sha256":"65e654fd90fb4e15e75eaad066d59478490837a429b0eeaa6896a6478bd18a2a"},{"path":"api/reports","title":"Reports","description":"POST /v1/report","section":"api","url":"https://docs.babelfor.net/api/reports","md":"/md/api/reports.md","headings":["POST /v1/report"],"sha256":"dbe782d46de40b20ce9a5ffb2119058838e8393749be3954b1b2ca7e27008b40"},{"path":"api/updates","title":"Updates","description":"These routes serve the updates of application products to the applications themselves. They are anonymous. An application that has a license identifies it with its user key, preferably in the…","section":"api","url":"https://docs.babelfor.net/api/updates","md":"/md/api/updates.md","headings":["Pages","Endpoints"],"sha256":"0a815ca8913e45e2a8ba9d12affd15fd99b877844b8ff880cc514404c139b990"},{"path":"api/updates/update-check","title":"Update Check","description":"GET /v1/updates/\\{productCode\\}","section":"api","url":"https://docs.babelfor.net/api/updates/update-check","md":"/md/api/updates/update-check.md","headings":["GET /v1/updates/{productCode}"],"sha256":"34fb92b26fc17cac88cf2d2fde77aa3d689779f4c9d51a6e207df4b12bbb7d3c"},{"path":"api/updates/feeds-and-downloads","title":"Feeds and Downloads","description":"GET /v1/updates/\\{productCode\\}/feed/\\{channel\\}/\\{platform\\}/\\{file\\}","section":"api","url":"https://docs.babelfor.net/api/updates/feeds-and-downloads","md":"/md/api/updates/feeds-and-downloads.md","headings":["GET /v1/updates/{productCode}/feed/{channel}/{platform}/{file}","GET /v1/updates/{productCode}/latest.yml","GET /v1/updates/{productCode}/latest-mac.yml","GET /v1/updates/{productCode}/latest-linux.yml","GET /v1/updates/{productCode}/download/{platform}/{version}/{fileName}","HEAD /v1/updates/{productCode}/download/{platform}/{version}/{fileName}"],"sha256":"5d807931310d94ca9843b92bb6a4012edfba0c825421d43010947e6078bf8f06"},{"path":"api/updates/extension-keys","title":"Extension Keys","description":"GET /v1/extensions/keys","section":"api","url":"https://docs.babelfor.net/api/updates/extension-keys","md":"/md/api/updates/extension-keys.md","headings":["GET /v1/extensions/keys"],"sha256":"d35015732cf7338c706cef8746f2e0c690a91c2cf49e0cf1c07ef4dadf47aa04"},{"path":"api/webhooks","title":"Webhooks","description":"Webhook subscriptions, their delivery events, the available event types and the dispatcher status.","section":"api","url":"https://docs.babelfor.net/api/webhooks","md":"/md/api/webhooks.md","headings":["Pages","Endpoints"],"sha256":"195fb93e8ad4d278f43b6c8a37105809d9f8ef5eb99f58157b2b634cb976388c"},{"path":"api/webhooks/subscriptions","title":"Subscriptions","description":"GET /v1/webhooks/subscriptions","section":"api","url":"https://docs.babelfor.net/api/webhooks/subscriptions","md":"/md/api/webhooks/subscriptions.md","headings":["GET /v1/webhooks/subscriptions","POST /v1/webhooks/subscriptions","GET /v1/webhooks/subscriptions/{id}","PUT /v1/webhooks/subscriptions/{id}","DELETE /v1/webhooks/subscriptions/{id}","POST /v1/webhooks/subscriptions/{id}/test"],"sha256":"cbc9e18dbd46ae45b2324dcee4683dfcfed242f8671e1c8fde80ba7bb1e9c346"},{"path":"api/webhooks/events","title":"Events","description":"GET /v1/webhooks/subscriptions/\\{id\\}/events","section":"api","url":"https://docs.babelfor.net/api/webhooks/events","md":"/md/api/webhooks/events.md","headings":["GET /v1/webhooks/subscriptions/{id}/events","DELETE /v1/webhooks/subscriptions/{id}/events/{eventId}"],"sha256":"fd97eea3c57c1f1a7fc0232d8a8e8b4fbff5fcfe39b01b5ef34a0dfcd7c26668"},{"path":"api/webhooks/status-and-event-types","title":"Status and Event Types","description":"GET /v1/webhooks/status","section":"api","url":"https://docs.babelfor.net/api/webhooks/status-and-event-types","md":"/md/api/webhooks/status-and-event-types.md","headings":["GET /v1/webhooks/status","GET /v1/webhooks/event-types"],"sha256":"74d6461fab344b08fad76cb5ce27ca7ec42f8bcca6dd0f20906c00162dec87d7"},{"path":"api/schemas","title":"Schemas","description":"The request and response models of the API, grouped by area. Endpoint pages link to the model they use.","section":"api","url":"https://docs.babelfor.net/api/schemas","md":"/md/api/schemas.md","headings":["Pages","All Schemas"],"sha256":"e660d013d2d4c797574beb6062352fb083e909922fcea4f6ece7df86856c8f71"},{"path":"api/schemas/product-releases","title":"Product Releases Schemas","description":"Response for DeleteReleaseDownload.","section":"api","url":"https://docs.babelfor.net/api/schemas/product-releases","md":"/md/api/schemas/product-releases.md","headings":["Licensing.DeleteReleaseDownloadResponse","Licensing.GetReleaseDownloadsResponse","Licensing.InsertReleaseDownloadRequest","Licensing.InsertReleaseDownloadResponse","Licensing.ReleaseDownloadDto","Licensing.UpdateReleaseDownloadRequest","Licensing.UpdateReleaseDownloadResponse","Licensing.VerifyReleaseDownloadsResponse","Management.DeleteProductReleaseAssemblyResponse","Management.DeleteProductReleaseResponse","Management.GetProductReleaseAssembliesResponse","Management.GetProductReleaseLicenseTemplatesResponse","Management.GetProductReleasesResponse","Management.InsertProductReleaseAssemblyRequest","Management.InsertProductReleaseAssemblyResponse","Management.InsertProductReleaseRequest","Management.InsertProductReleaseResponse","Management.Release","Management.UpdateProductReleaseAssemblyRequest","Management.UpdateProductReleaseAssemblyResponse","Management.UpdateProductReleaseRequest","Management.UpdateProductReleaseResponse"],"sha256":"891063dc21def0087121019d13a932fca6197c3ed57be5c5e8a951d8e88f0af6"},{"path":"api/schemas/licensing","title":"Licensing Schemas","description":"","section":"api","url":"https://docs.babelfor.net/api/schemas/licensing","md":"/md/api/schemas/licensing.md","headings":["Licensing.ActivateLicenseRequest","Licensing.ActivateLicenseResponse","Licensing.DeactivateLicenseRequest","Licensing.DeactivateLicenseResponse","Licensing.Duration","Licensing.HeartbeatRequest","Licensing.HeartbeatResponse","Licensing.License","Licensing.LicenseFormat","Licensing.LicenseInfoRequest","Licensing.LicenseInfoResponse","Licensing.LicenseToken","Licensing.LicensingMode","Licensing.ReleaseLicenseRequest","Licensing.ReleaseLicenseResponse","Licensing.Report","Licensing.RequestLicenseRequest","Licensing.RequestLicenseResponse","Licensing.SendReportRequest","Licensing.SendReportResponse","Licensing.Timestamp","Licensing.ValidateLicenseRequest","Licensing.ValidateLicenseResponse"],"sha256":"d355af256c41b201c2b27113d37e4a7f79d6fe2a15fceba31fdca703024e3e2f"},{"path":"api/schemas/webhooks","title":"Webhooks Schemas","description":"","section":"api","url":"https://docs.babelfor.net/api/schemas/webhooks","md":"/md/api/schemas/webhooks.md","headings":["Management.CreateWebhookSubscriptionDto","Management.CreateWebhookSubscriptionRequest","Management.CreateWebhookSubscriptionResponse","Management.DeleteWebhookEventResponse","Management.DeleteWebhookSubscriptionResponse","Management.GetWebhookEventTypesResponse","Management.GetWebhookEventsResponse","Management.GetWebhookStatusResponse","Management.GetWebhookSubscriptionResponse","Management.GetWebhookSubscriptionsResponse","Management.SendWebhookTestEventRequest","Management.SendWebhookTestEventResponse","Management.UpdateWebhookSubscriptionDto","Management.UpdateWebhookSubscriptionRequest","Management.UpdateWebhookSubscriptionResponse","Management.WebhookEvent","Management.WebhookEventType","Management.WebhookSubscription"],"sha256":"5f8985b478ac231a67cb5b8394a38f1db263f34fab2da49ebac96b76fbb5ab01"},{"path":"api/schemas/authentication","title":"Authentication Schemas","description":"None","section":"api","url":"https://docs.babelfor.net/api/schemas/authentication","md":"/md/api/schemas/authentication.md","headings":["Management.GetLoggedInUserRequest","Management.GetLoggedInUserResponse","Management.GetSessionResponse","Management.LoginRequest","Management.LoginResponse","Management.LogoutRequest","Management.LogoutResponse","Management.UpdateUserSettingsRequest","Management.UpdateUserSettingsResponse"],"sha256":"6986ee6c6d483f215c99ee7dbd995adbc413a7377e98ced696e72cf29653d019"},{"path":"api/schemas/server","title":"Reports, Log and Server Schemas","description":"None","section":"api","url":"https://docs.babelfor.net/api/schemas/server","md":"/md/api/schemas/server.md","headings":["Management.ApplicationSetting","Management.DeleteReportResponse","Management.EmailAttachment","Management.EmailRecipient","Management.GetLogLevelsResponse","Management.GetLogResponse","Management.GetReportResponse","Management.GetServerInfoResponse","Management.GetSettingsRequest","Management.GetSettingsResponse","Management.LogEntry","Management.LogLevelInfo","Management.Report","Management.ReportProperty","Management.ResolveReportLocationsRequest","Management.ResolveReportLocationsResponse","Management.SendEmailRequest","Management.SendEmailResponse","Management.SendLicenseEmailRequest","Management.SendLicenseEmailResponse","Management.UpdateSettingsRequest","Management.UpdateSettingsResponse"],"sha256":"6cf156bfd918cd601abc55e87200a5b12e72f3d907f811e85144236400a8a11a"},{"path":"api/schemas/users-and-api-keys","title":"Users, Roles and API Keys Schemas","description":"","section":"api","url":"https://docs.babelfor.net/api/schemas/users-and-api-keys","md":"/md/api/schemas/users-and-api-keys.md","headings":["Management.AddUserToRoleRequest","Management.AddUserToRoleResponse","Management.ApiKey","Management.DeleteApiKeyResponse","Management.DeleteUserResponse","Management.DeleteUserSettingResponse","Management.GetApiKeysResponse","Management.GetRolesResponse","Management.GetUserRolesResponse","Management.GetUserSettingsResponse","Management.GetUsersResponse","Management.InsertApiKeyRequest","Management.InsertApiKeyResponse","Management.InsertUserRequest","Management.InsertUserResponse","Management.InsertUserSettingRequest","Management.InsertUserSettingResponse","Management.RemoveUserFromRoleRequest","Management.RemoveUserFromRoleResponse","Management.Role","Management.UpdateApiKeyRequest","Management.UpdateApiKeyResponse","Management.UpdateUserRequest","Management.UpdateUserResponse","Management.UpdateUserSettingRequest","Management.UpdateUserSettingResponse","Management.User","Management.UserSetting"],"sha256":"715675b3d88b19d1481f55df361a282a4b28d30a75df387e7ac675c522fc2ec3"},{"path":"api/schemas/license-tokens","title":"License Tokens Schemas","description":"","section":"api","url":"https://docs.babelfor.net/api/schemas/license-tokens","md":"/md/api/schemas/license-tokens.md","headings":["Management.DeleteLicenseTokenResponse","Management.GetLicenseTokensResponse","Management.InsertLicenseTokenRequest","Management.InsertLicenseTokenResponse","Management.LicenseToken"],"sha256":"f6ab92e9add767f015b21e59383334e25db42b9a6b4a046522536a7deaeb8b0a"},{"path":"api/schemas/licenses","title":"Licenses Schemas","description":"","section":"api","url":"https://docs.babelfor.net/api/schemas/licenses","md":"/md/api/schemas/licenses.md","headings":["Management.DeleteLicenseResponse","Management.DeleteLicenseTemplateResponse","Management.DeleteLicenseTraceRequest","Management.DeleteLicenseTraceResponse","Management.GetCustomerLicensesResponse","Management.GetLicenseTemplateLicensesResponse","Management.GetLicenseTemplatesResponse","Management.GetLicenseTracesResponse","Management.GetLicensesResponse","Management.GetOrderLicensesResponse","Management.InsertLicenseRequest","Management.InsertLicenseResponse","Management.InsertLicenseTemplateRequest","Management.InsertLicenseTemplateResponse","Management.License","Management.LicenseFeature","Management.LicenseField","Management.LicenseProduct","Management.LicenseRestriction","Management.LicenseTemplate","Management.LicenseTrace","Management.Licensee","Management.LicensingMode","Management.ResolveLicenseTraceLocationsRequest","Management.ResolveLicenseTraceLocationsResponse","Management.UpdateLicenseRequest","Management.UpdateLicenseResponse","Management.UpdateLicenseTemplateRequest","Management.UpdateLicenseTemplateResponse"],"sha256":"14a60b0e832546b3570ad6a1845a2bd8e4de9fc350c82d84d7b2a21ac041f570"},{"path":"api/schemas/sales","title":"Customers, Orders and Products Schemas","description":"","section":"api","url":"https://docs.babelfor.net/api/schemas/sales","md":"/md/api/schemas/sales.md","headings":["Management.Assembly","Management.Contact","Management.Customer","Management.DeleteAssemblyResponse","Management.DeleteContactResponse","Management.DeleteCustomerResponse","Management.DeleteOrderResponse","Management.DeleteProductOrderResponse","Management.DeleteProductResponse","Management.DeleteResourceResponse","Management.GetAssembliesResponse","Management.GetContactsResponse","Management.GetCustomerContactsResponse","Management.GetCustomerOrdersResponse","Management.GetCustomersResponse","Management.GetOrderProductsResponse","Management.GetOrdersResponse","Management.GetProductOrdersResponse","Management.GetProductsResponse","Management.GetResourcesResponse","Management.InsertAssemblyRequest","Management.InsertAssemblyResponse","Management.InsertContactRequest","Management.InsertContactResponse","Management.InsertCustomerRequest","Management.InsertCustomerResponse","Management.InsertOrderRequest","Management.InsertOrderResponse","Management.InsertProductOrderRequest","Management.InsertProductOrderResponse","Management.InsertProductRequest","Management.InsertProductResponse","Management.InsertResourceRequest","Management.InsertResourceResponse","Management.Order","Management.Product","Management.ProductOrder","Management.Resource","Management.UpdateAssemblyRequest","Management.UpdateAssemblyResponse","Management.UpdateContactRequest","Management.UpdateContactResponse","Management.UpdateCustomerRequest","Management.UpdateCustomerResponse","Management.UpdateOrderRequest","Management.UpdateOrderResponse","Management.UpdateProductOrderRequest","Management.UpdateProductOrderResponse","Management.UpdateProductRequest","Management.UpdateProductResponse","Management.UpdateResourceRequest","Management.UpdateResourceResponse"],"sha256":"8c847acbb36d0c069d93032e2c47add3bcc19caf82e3008e6e29083973decfed"}],"chunks":[{"page":0,"heading":"","anchor":"","text":"Welcome to the official documentation for Babel software protection and licensing solutions.\nHere you will find guides, API references and examples for protecting\nyour .NET applications and adding software licensing to them."},{"page":0,"heading":"Products","anchor":"products","text":"Explore the documentation for our products and API designed to protect and monetize your .NET software:\nBabel Obfuscator: Protect your .NET applications with industry-leading obfuscation technology. Babel Obfuscator\nprovides symbol renaming, control flow obfuscation, string encryption, code encryption, and\ntamper detection to safeguard your intellectual property from reverse engineering.\nBabel Licensing: Implement flexible software licensing for your applications. Babel Licensing supports multiple\nlicensing modes including license files, floating licenses, license activation, and consumption\ntokens. Includes a complete licensing service, managed from Babel Desktop or, with the Data Center\nedition, from the browser.\nBabel Desktop: Use Babel Desktop on Windows, macOS and Linux to configure obfuscation projects, decode stack traces and manage licensing through Babel Licensing Service. Connect AI assistants to the Desktop MCP server.macOS and Linux require an Ultimate license."},{"page":0,"heading":"Getting Started","anchor":"getting-started","text":"Babel Obfuscator\nBabel Desktop - Install and use the cross-platform desktop application for Windows, macOS and Linux\nCommand Line Interface - Automate obfuscation in build processes\nNuGet Package Integration - Integrate obfuscation into your MSBuild workflow\nExamples - Practical examples and use cases\nBabel Licensing\nInstallation Guide - Install the Babel Licensing Service\nBabel Desktop Licensing - Manage customers, products and licenses from the desktop\nClient Components - Integrate licensing into your applications\nLicensing Modes - Choose the right licensing model\nExamples - Sample implementations and tutorials\nAPI Reference - REST API for programmatic license management\nBabel Desktop\nInstallation\nObfuscation projects\nLicense management\nDesktop MCP server"},{"page":0,"heading":"Licensing API","anchor":"licensing-api","text":"Complete REST API reference for the Babel Licensing Service. Programmatically manage licenses, products, customers, and more. Includes authentication, licensing operations, webhooks, and detailed schema documentation.\nAPI reference."},{"page":0,"heading":"Key Features","anchor":"key-features","text":"Code Protection\nSymbol Renaming - Rename classes, methods, fields, and properties to meaningless identifiers\nControl Flow Obfuscation - Transform code logic to make decompilation ineffective\nString Encryption - Protect string literals from static analysis\nCode Encryption - Encrypt method bodies with optional feature-based licensing\nAnti-Debugging - Detect and respond to debugging attempts\nTamper Detection - Verify assembly integrity at runtime\nSoftware Licensing\nLicense Files - Offline XML-based license validation\nFloating Licenses - Concurrent user licensing with automatic release\nLicense Activation - Online activation with hardware binding\nTrial Licenses - Time-limited evaluation licenses with expiration dates\nHardware Licenses - Lock licenses to specific hardware configurations\nConsumption Tokens - Usage-based licensing for services\nReporting - Exception reports, license usage tracking, and custom reports\nWeb Management - Browser-based license administration (Data Center)\nMCP Server - AI-powered license management through Model Context Protocol integration"},{"page":0,"heading":"Additional Resources","anchor":"additional-resources","text":"The documentation is also published as plain Markdown for AI assistants. See Using the Documentation with AI to give it to Claude, ChatGPT or another assistant, or to let Babel Desktop search it for you.\nVisit our main website at babelfor.net for:\nProduct downloads and pricing\nKnowledge base articles\nSupport and contact information\nBlog posts and announcements\nFor technical support, please contact us at support@babelfor.net."},{"page":1,"heading":"","anchor":"","text":"Every page of this site is also published as plain Markdown, so an AI\nassistant can read the documentation without parsing the website. You can\nhand the assistant a URL or a file, or connect it to Babel Desktop, which\nsearches the documentation for it."},{"page":1,"heading":"Files for AI Assistants","anchor":"files-for-ai-assistants","text":"The site build publishes these files next to the pages:\nURL | Content\nhttps://docs.babelfor.net/llms.txt | Index of every page, grouped by section (Obfuscator, Licensing, Desktop, API Reference), with a one-line description and a link to the Markdown copy of each page\nhttps://docs.babelfor.net/llms-full.txt | All pages in one file, in navigation order. Each page starts with its title and a Source: line with the page URL. The file is a few megabytes\nhttps://docs.babelfor.net/md/<path>.md | Markdown copy of a single page. The path is the page address, for example /md/desktop/stack-decoder.md for Stack Decoder, or /md/desktop.md for the Desktop section page\nhttps://docs.babelfor.net/docs-index.json | Search index of all sections, used by the Babel Desktop documentation tools\nThe Markdown copies have the same content as the pages. Procedures become numbered lists, notes become quoted paragraphs, tabs become subheadings, and links and images point to https://docs.babelfor.net, so they still work when the text is copied somewhere else.\nThe files are rebuilt every time the site is published and always describe the current release."},{"page":1,"heading":"Using the Files with Claude, ChatGPT and Other Assistants","anchor":"using-the-files-with-claude-chatgpt-and-other-assistants","text":"Pick the file that matches the question. For a question about one feature, a single page is enough and leaves the assistant more room for your own code and logs. For broad questions, give it the index or the full file.\nFind the page\nOpen llms.txt and look for the pages that cover your question, or browse this site and add /md in front of the path and .md at the end: https://docs.babelfor.net/licensing/licensing-modes becomes https://docs.babelfor.net/md/licensing/licensing-modes.md.\nGive it to the assistant\nIf the assistant can open web pages, paste the URL into the conversation. Otherwise download the file and attach it, or copy its text into the message. Large files such as llms-full.txt may not fit in a single conversation; in that case, give the assistant llms.txt and let it ask for the pages it needs.\nAsk the question\nAsk the assistant to answer from the documentation you provided and to quote the Source: URL or the page link it used, so you can check the answer on the site.\nSome example requests:\nRead https://docs.babelfor.net/llms.txt and tell me which pages explain how to run Babel Obfuscator in a CI build on Linux. Then read those pages and list the steps.\nUsing https://docs.babelfor.net/md/obfuscator/nuget-package/configuration.md, add string encryption and control flow obfuscation to this project file.\nHere is llms-full.txt. What is the difference between a floating license and license activation, and which one fits a desktop app sold per seat?"},{"page":1,"heading":"Using the Files with Claude, ChatGPT and Other Assistants","anchor":"using-the-files-with-claude-chatgpt-and-other-assistants","text":"Info: These files are public, static pages. Opening or attaching them only downloads them from https://docs.babelfor.net; nothing about your code or projects is sent to babelfor.NET. What you paste into an assistant, such as source code, project files or stack traces, is governed by that assistant's own terms."},{"page":1,"heading":"Using the Documentation from Babel Desktop","anchor":"using-the-documentation-from-babel-desktop","text":"If Babel Desktop is installed, connect your assistant to its MCP server. This is the recommended option. The server includes three documentation tools, docs_search, docs_read and docs_list, so the same connection answers how-to questions and then applies the change in the app: the assistant looks up how a feature works, cites the page, and changes the project settings or runs the obfuscation.\nEnable the MCP server\nIn Babel Desktop, open Settings, choose MCP and tick Enable the automation server. Requiring an access token is recommended. See Enabling the Server.\nConnect the assistant\nClick Copy configuration and add it to the MCP configuration of your client, or, for Claude Code, click Copy Claude Code command and run the command. The configuration contains the server address, http://127.0.0.1:8765/mcp with the default port, and the X-Babel-Token header when a token is required. See Connecting a Client.\nAsk a question\nAsk how to do something in Babel. The assistant searches the documentation, reads the matching section and answers with links to the pages.\nThe documentation tools need no other setting. They are available whenever the server is running. The Desktop downloads the pages from https://docs.babelfor.net and searches them on your machine, and it keeps a copy in your user profile so they still answer when you are offline. See Babel Documentation Tools for the details."},{"page":2,"heading":"","anchor":"","text":"Babel Obfuscator protects .NET assemblies against reverse engineering, from\n.NET Framework 2.0 to .NET 10, on desktop, mobile, web and server targets.\nIt renames, encrypts and restructures compiled code so that what a decompiler\nrecovers is no longer worth reading."},{"page":2,"heading":"Why Obfuscate .NET Code","anchor":"why-obfuscate-net-code","text":"Software written in .NET languages such as C#, VB.NET and F# compiles to MSIL (Microsoft Intermediate Language), a CPU-independent instruction set stored in the assembly alongside rich metadata: type names, member signatures, string literals and attributes. Together they let freely available decompilers rebuild source code that is close to the original, in seconds and without any special skill.\nObfuscation transforms the compiled assembly so that this reconstruction stops being useful. Babel Obfuscator renames symbols, encrypts strings, constants and resources, rewrites the control flow of methods, and can encrypt whole method bodies for execution inside a managed virtual machine. The application behaves exactly as before; the code an attacker recovers no longer does."},{"page":2,"heading":"What's New in 12.0","anchor":"whats-new-in-120","text":"Version 12.0 hardens Babel against automated deobfuscation, extends tampering detection to mobile, and opens the product to AI assistants.\nBabel Desktop: New cross-platform app for Windows, macOS and Linux that edits and runs\nobfuscation projects, decodes stack traces, manages Babel Licensing and\nhosts an MCP server.\nChained State: A control flow flattening algorithm engineered to resist automated\ndeobfuscators. Verifiable IL, NativeAOT and MAUI compatible, within a few\npercent of ordinary flattening at run time.\nSTREAM String Encryption: Authenticated, lazy per-string encryption with a fully managed decryptor:\nsafe under trimming, NativeAOT and FIPS, verified on Android and iOS.\nAndroid Package Integrity: Tampering detection for .NET MAUI on Android: the app checks the APK\nsigning certificate against signer fingerprints pinned at obfuscation time,\nso a repackaged app is rejected, even when trimmed or AOT-compiled.\niOS Package Identity: Tampering detection for .NET MAUI on iOS: the app verifies its bundle\nidentifier and Apple Team identifier against pinned values, under full AOT.\nStack Decoder Proxy Frames: Decoded stack traces now name the method behind every Dynamic Proxy bridge,\nand can hide the Babel-generated frames entirely."},{"page":2,"heading":"What's New in 12.0","anchor":"whats-new-in-120","text":"The releases leading up to 12.0 brought more: version 11.8 added a managed AES decryptor so protected assemblies start on FIPS-mode hosts, much faster obfuscation of very large assemblies, and the Hardware Dongle Binding sample; version 11.7 introduced the AI-friendly command line."},{"page":2,"heading":"The Ultimate Badge","anchor":"the-ultimate-badge","text":"Some headings in this manual carry this marker: (Ultimate). It means the feature is available from the Babel Obfuscator Ultimate edition or higher; hovering over the badge shows the same information.\nBabel Obfuscator comes in two editions. Enterprise is a single-user license for Windows with the command line tool and the MSBuild task of the .NET Framework (babel_net472) zip package. Ultimate is a site license that runs on Windows, Linux and macOS on any number of machines and adds Babel Desktop, the NuGet packages, build server integration, the Babel Encrypt plugin, and the protections introduced in 12.0 for the Ultimate tier: Chained State, STREAM string encryption and Android and iOS package-integrity tampering detection. The Babel Licensing editions, Server and Data Center, include Babel Obfuscator Ultimate, so every badged feature is available on them too; a few licensing-related capabilities, such as the licensing tools of the MCP server, are specific to those two editions and say so on their page.\nA heading without a badge describes a feature of both editions. The complete matrix, with pricing, is on the Compare Editions page."},{"page":2,"heading":"Protection Features","anchor":"protection-features","text":"Each feature can be enabled on its own and tuned per symbol with obfuscation rules, so you can apply the strongest transforms only where the intellectual property is."},{"page":2,"heading":"Protection Features","anchor":"protection-features","text":"Symbol Renaming: Rename namespaces, types, members and parameters to meaningless names, in\nASCII or Unicode, with XAML/BAML awareness and cross-assembly map files.\nString Encryption: Encrypt string literals with the XOR, HASH or STREAM algorithms, or plug in\nan algorithm of your own.\nControl Flow Obfuscation: Insert opaque branches, rewrite conditionals and flatten methods around\ndispatchers, up to the Ultimate Chained State algorithm.\nCode Encryption: Encrypt method bodies and run them in the managed Babel Virtual Machine.\nKeep them in external files or behind passwords for feature-based licensing.\nDynamic Proxy: Route calls to external and internal methods through generated proxies, so\nthe real call targets disappear from the IL.\nResource Encryption: Compress and encrypt embedded resources, decrypted on demand at run time.\nValue and Array Encryption: Hide inline numeric constants and array initializers, such as keys and\nlookup tables.\nAnti-Debugging: Detect an attached debugger and terminate the process, or run a handler of\nyour own.\nTampering Detection: Verify the image hash on desktop and the package signature or identity on\nAndroid and iOS, then terminate or react with custom code.\nMerge and Embed: Fold dependencies into one assembly, or embed them as encrypted resources,\nfor a single-file deployment with a smaller exposed surface.\nOptimizations: Remove dead code, seal classes, strip attributes and inline small members to\nshrink metadata and speed up loading."},{"page":2,"heading":"Protection Features","anchor":"protection-features","text":"Obfuscation Rules: Fine-tune every feature with XML rules and custom attributes, backed by the\nanalysis Agent that keeps reflection and serialization working."},{"page":2,"heading":"Built for AI-Assisted Workflows","anchor":"built-for-ai-assisted-workflows","text":"Babel treats AI assistants as first-class operators of the product, at two levels.\nBabel MCP Server. Babel Desktop can expose an MCP endpoint on the local machine. Claude Code, or any client that speaks the Model Context Protocol, then operates the application the way you would: it creates projects, adds assemblies, writes rules, chooses what to merge or embed, starts the obfuscation, reads warnings and statistics, decodes stack traces, authors themes and takes screenshots to check its own work. On the Server and Data Center editions the same server manages the licensing database. The server is off by default. Turn it on with Enable the automation server in Settings > MCP. It listens on loopback only and can require an access token. Copy Claude Code command, on the same page, gives you the registration command. See Babel MCP Server.\nclaude mcp add --transport http babel-obfuscator http://127.0.0.1:8765/mcp \\\n  --header \"X-Babel-Token: paste-the-token-from-settings-mcp\"\nAI-friendly command line. Since version 11.7 the command line tool can emit a structured, versioned output stream for CI pipelines and agents: --format=json or --format=ndjson switch stdout to the babel.cli.v1 schema, --quiet makes unattended runs fail fast instead of prompting, and --strict-exit turns on semantic exit codes. The same flag makes --help and --version machine-readable, so an agent can discover every option on its own. See AI-Friendly Mode."},{"page":2,"heading":"Built for AI-Assisted Workflows","anchor":"built-for-ai-assisted-workflows","text":"Info: Babel Licensing has its own MCP server for the hosted Licensing Service, so an assistant can manage customers, licenses and activations over the REST API. See AI Integration in the Babel Licensing manual."},{"page":2,"heading":"Platforms and Frameworks","anchor":"platforms-and-frameworks","text":"Area | Support\nBuild host | Windows, with the command line tool and MSBuild task from the zip packages; Linux, macOS and CI build servers through the Babel NuGet packages and dotnet tool (Ultimate edition); Babel Desktop on Windows, macOS and Linux (Ultimate edition)\nTarget runtimes | .NET 10 and every .NET and .NET Core release before it, .NET Framework 2.0 to 4.8, .NET Standard, Mono\nApplication models | Desktop (WPF, Windows Forms, Avalonia), .NET MAUI on Android and iOS, Xamarin, Blazor, ASP.NET Core, UWP, nanoFramework\nLanguages | C#, including C# 14, VB.NET and F#\nPublish modes | Framework-dependent, self-contained, single-file, trimmed and NativeAOT\nObfuscation works on IL, so a build host on one operating system can protect assemblies published for any runtime identifier. Symbol renaming, STREAM string encryption and control flow obfuscation, including Chained State, survive trimming and NativeAOT unchanged. Features that need a memory-mapped image or dynamic IL, such as Code Encryption, Dynamic Proxy and the desktop tampering check, have documented limits on MAUI, Blazor and AOT targets; each feature page states them."},{"page":2,"heading":"How You Run It","anchor":"how-you-run-it","text":"Babel Desktop: Application for Windows, macOS and Linux to build and run obfuscation\nprojects, decode stack traces, manage Babel Licensing and host the MCP server.\nCommand Line: Every feature from a shell or script, with an AI-friendly output mode. On\nLinux and macOS it runs as the Ultimate dotnet tool.\nMSBuild Task: Obfuscate as part of the build from Visual Studio and build servers, with\nIntelliSense for every task property.\nNuGet Package: Add a package reference and dotnet build or dotnet publish obfuscates at\nthe right point of the SDK pipeline, before trimming and AOT. The way to run\nBabel on Linux, macOS and CI build servers.\nThe Ultimate edition and the Babel Licensing editions include the NuGet packages, so Babel runs as a dotnet tool on Windows, Linux and macOS and inside SDK-style builds. Babel Desktop runs the engine on .NET 10, so obfuscating in Babel Desktop also requires one of these editions. The Enterprise edition provides the Windows command line tool and the MSBuild task of the .NET Framework zip package."},{"page":2,"heading":"Next Steps","anchor":"next-steps","text":"Getting Started to install Babel and activate your license\nGeneral Features for a feature-by-feature tour\nEnhancing Code Security for the settings that give the best protection with the least effort\nExamples for MAUI, Blazor, ClickOnce, build servers and feature-based licensing"},{"page":3,"heading":"","anchor":"","text":"Babel Obfuscator\nBabel Obfuscator protects .NET assemblies against reverse engineering, from\n.NET Framework 2.0 to .NET 10, on desktop, mobile, web and server targets.\nIt renames, encrypts and restructures compiled code so that what a decompiler\nrecovers is no longer worth reading."},{"page":3,"heading":"Why Obfuscate .NET Code","anchor":"why-obfuscate-net-code","text":"Software written in .NET languages such as C#, VB.NET and F# compiles to MSIL (Microsoft Intermediate Language), a CPU-independent instruction set stored in the assembly alongside rich metadata: type names, member signatures, string literals and attributes. Together they let freely available decompilers rebuild source code that is close to the original, in seconds and without any special skill.\nObfuscation transforms the compiled assembly so that this reconstruction stops being useful. Babel Obfuscator renames symbols, encrypts strings, constants and resources, rewrites the control flow of methods, and can encrypt whole method bodies for execution inside a managed virtual machine. The application behaves exactly as before; the code an attacker recovers no longer does."},{"page":3,"heading":"What's New in 12.0","anchor":"whats-new-in-120","text":"Version 12.0 hardens Babel against automated deobfuscation, extends tampering detection to mobile, and opens the product to AI assistants.\nBabel Desktop: New cross-platform app for Windows, macOS and Linux that edits and runs\nobfuscation projects, decodes stack traces, manages Babel Licensing and\nhosts an MCP server.\nChained State: A control flow flattening algorithm engineered to resist automated\ndeobfuscators. Verifiable IL, NativeAOT and MAUI compatible, within a few\npercent of ordinary flattening at run time.\nSTREAM String Encryption: Authenticated, lazy per-string encryption with a fully managed decryptor:\nsafe under trimming, NativeAOT and FIPS, verified on Android and iOS.\nAndroid Package Integrity: Tampering detection for .NET MAUI on Android: the app checks the APK\nsigning certificate against signer fingerprints pinned at obfuscation time,\nso a repackaged app is rejected, even when trimmed or AOT-compiled.\niOS Package Identity: Tampering detection for .NET MAUI on iOS: the app verifies its bundle\nidentifier and Apple Team identifier against pinned values, under full AOT.\nStack Decoder Proxy Frames: Decoded stack traces now name the method behind every Dynamic Proxy bridge,\nand can hide the Babel-generated frames entirely."},{"page":3,"heading":"What's New in 12.0","anchor":"whats-new-in-120","text":"The releases leading up to 12.0 brought more: version 11.8 added a managed AES decryptor so protected assemblies start on FIPS-mode hosts, much faster obfuscation of very large assemblies, and the Hardware Dongle Binding sample; version 11.7 introduced the AI-friendly command line."},{"page":3,"heading":"The Ultimate Badge","anchor":"the-ultimate-badge","text":"Some headings in this manual carry this marker: (Ultimate). It means the feature is available from the Babel Obfuscator Ultimate edition or higher; hovering over the badge shows the same information.\nBabel Obfuscator comes in two editions. Enterprise is a single-user license for Windows with the command line tool and the MSBuild task of the .NET Framework (babel_net472) zip package. Ultimate is a site license that runs on Windows, Linux and macOS on any number of machines and adds Babel Desktop, the NuGet packages, build server integration, the Babel Encrypt plugin, and the protections introduced in 12.0 for the Ultimate tier: Chained State, STREAM string encryption and Android and iOS package-integrity tampering detection. The Babel Licensing editions, Server and Data Center, include Babel Obfuscator Ultimate, so every badged feature is available on them too; a few licensing-related capabilities, such as the licensing tools of the MCP server, are specific to those two editions and say so on their page.\nA heading without a badge describes a feature of both editions. The complete matrix, with pricing, is on the Compare Editions page."},{"page":3,"heading":"Protection Features","anchor":"protection-features","text":"Each feature can be enabled on its own and tuned per symbol with obfuscation rules, so you can apply the strongest transforms only where the intellectual property is."},{"page":3,"heading":"Protection Features","anchor":"protection-features","text":"Symbol Renaming: Rename namespaces, types, members and parameters to meaningless names, in\nASCII or Unicode, with XAML/BAML awareness and cross-assembly map files.\nString Encryption: Encrypt string literals with the XOR, HASH or STREAM algorithms, or plug in\nan algorithm of your own.\nControl Flow Obfuscation: Insert opaque branches, rewrite conditionals and flatten methods around\ndispatchers, up to the Ultimate Chained State algorithm.\nCode Encryption: Encrypt method bodies and run them in the managed Babel Virtual Machine.\nKeep them in external files or behind passwords for feature-based licensing.\nDynamic Proxy: Route calls to external and internal methods through generated proxies, so\nthe real call targets disappear from the IL.\nResource Encryption: Compress and encrypt embedded resources, decrypted on demand at run time.\nValue and Array Encryption: Hide inline numeric constants and array initializers, such as keys and\nlookup tables.\nAnti-Debugging: Detect an attached debugger and terminate the process, or run a handler of\nyour own.\nTampering Detection: Verify the image hash on desktop and the package signature or identity on\nAndroid and iOS, then terminate or react with custom code.\nMerge and Embed: Fold dependencies into one assembly, or embed them as encrypted resources,\nfor a single-file deployment with a smaller exposed surface.\nOptimizations: Remove dead code, seal classes, strip attributes and inline small members to\nshrink metadata and speed up loading."},{"page":3,"heading":"Protection Features","anchor":"protection-features","text":"Obfuscation Rules: Fine-tune every feature with XML rules and custom attributes, backed by the\nanalysis Agent that keeps reflection and serialization working."},{"page":3,"heading":"Built for AI-Assisted Workflows","anchor":"built-for-ai-assisted-workflows","text":"Babel treats AI assistants as first-class operators of the product, at two levels.\nBabel MCP Server. Babel Desktop can expose an MCP endpoint on the local machine. Claude Code, or any client that speaks the Model Context Protocol, then operates the application the way you would: it creates projects, adds assemblies, writes rules, chooses what to merge or embed, starts the obfuscation, reads warnings and statistics, decodes stack traces, authors themes and takes screenshots to check its own work. On the Server and Data Center editions the same server manages the licensing database. The server is off by default. Turn it on with Enable the automation server in Settings > MCP. It listens on loopback only and can require an access token. Copy Claude Code command, on the same page, gives you the registration command. See Babel MCP Server.\nclaude mcp add --transport http babel-obfuscator http://127.0.0.1:8765/mcp \\\n  --header \"X-Babel-Token: paste-the-token-from-settings-mcp\"\nAI-friendly command line. Since version 11.7 the command line tool can emit a structured, versioned output stream for CI pipelines and agents: --format=json or --format=ndjson switch stdout to the babel.cli.v1 schema, --quiet makes unattended runs fail fast instead of prompting, and --strict-exit turns on semantic exit codes. The same flag makes --help and --version machine-readable, so an agent can discover every option on its own. See AI-Friendly Mode."},{"page":3,"heading":"Built for AI-Assisted Workflows","anchor":"built-for-ai-assisted-workflows","text":"Info: Babel Licensing has its own MCP server for the hosted Licensing Service, so an assistant can manage customers, licenses and activations over the REST API. See AI Integration in the Babel Licensing manual."},{"page":3,"heading":"Platforms and Frameworks","anchor":"platforms-and-frameworks","text":"Area | Support\nBuild host | Windows, with the command line tool and MSBuild task from the zip packages; Linux, macOS and CI build servers through the Babel NuGet packages and dotnet tool (Ultimate edition); Babel Desktop on Windows, macOS and Linux (Ultimate edition)\nTarget runtimes | .NET 10 and every .NET and .NET Core release before it, .NET Framework 2.0 to 4.8, .NET Standard, Mono\nApplication models | Desktop (WPF, Windows Forms, Avalonia), .NET MAUI on Android and iOS, Xamarin, Blazor, ASP.NET Core, UWP, nanoFramework\nLanguages | C#, including C# 14, VB.NET and F#\nPublish modes | Framework-dependent, self-contained, single-file, trimmed and NativeAOT\nObfuscation works on IL, so a build host on one operating system can protect assemblies published for any runtime identifier. Symbol renaming, STREAM string encryption and control flow obfuscation, including Chained State, survive trimming and NativeAOT unchanged. Features that need a memory-mapped image or dynamic IL, such as Code Encryption, Dynamic Proxy and the desktop tampering check, have documented limits on MAUI, Blazor and AOT targets; each feature page states them."},{"page":3,"heading":"How You Run It","anchor":"how-you-run-it","text":"Babel Desktop: Application for Windows, macOS and Linux to build and run obfuscation\nprojects, decode stack traces, manage Babel Licensing and host the MCP server.\nCommand Line: Every feature from a shell or script, with an AI-friendly output mode. On\nLinux and macOS it runs as the Ultimate dotnet tool.\nMSBuild Task: Obfuscate as part of the build from Visual Studio and build servers, with\nIntelliSense for every task property.\nNuGet Package: Add a package reference and dotnet build or dotnet publish obfuscates at\nthe right point of the SDK pipeline, before trimming and AOT. The way to run\nBabel on Linux, macOS and CI build servers.\nThe Ultimate edition and the Babel Licensing editions include the NuGet packages, so Babel runs as a dotnet tool on Windows, Linux and macOS and inside SDK-style builds. Babel Desktop runs the engine on .NET 10, so obfuscating in Babel Desktop also requires one of these editions. The Enterprise edition provides the Windows command line tool and the MSBuild task of the .NET Framework zip package."},{"page":3,"heading":"Next Steps","anchor":"next-steps","text":"Getting Started to install Babel and activate your license\nGeneral Features for a feature-by-feature tour\nEnhancing Code Security for the settings that give the best protection with the least effort\nExamples for MAUI, Blazor, ClickOnce, build servers and feature-based licensing"},{"page":4,"heading":"","anchor":"","text":"What Babel Obfuscator does, where it runs, and what it protects. Each section\nlinks to the page that shows how to configure the feature."},{"page":4,"heading":"Protects Your Code and Intellectual Property Against Reverse Engineering","anchor":"protects-your-code-and-intellectual-property-against-reverse-engineering","text":"Babel Obfuscator applies several independent layers of protection to a compiled assembly: it renames symbols to meaningless identifiers, encrypts strings, constants and arrays and resources, rewrites the control flow of methods, hides call targets behind dynamic proxies, and can encrypt whole method bodies for execution in a managed virtual machine. The application keeps its behaviour and its public interface; what a decompiler recovers is no longer the source you wrote.\nThe layers combine. Renaming removes the vocabulary a reader relies on, string and value encryption remove the clues that survive renaming, control flow obfuscation removes the structure, and code encryption removes the code itself. Applied together, and selectively where the intellectual property is, they raise the cost of understanding and modifying the assembly far above the value an attacker can extract from it."},{"page":4,"heading":"Compatible With the Whole .NET Ecosystem","anchor":"compatible-with-the-whole-net-ecosystem","text":"Babel Obfuscator works at the IL and metadata level, so it supports every runtime and application model that produces standard .NET assemblies:\n.NET 10 and every .NET and .NET Core release before it\n.NET Framework 2.0 to 4.8\nDesktop applications built with WPF, Windows Forms or Avalonia\n.NET MAUI on Android and iOS, and Xamarin\nBlazor and ASP.NET Core\n.NET Standard, UWP, Mono and nanoFramework\nIt handles code written in C#, up to C# 14, VB.NET and F#, and it follows the publish modes of the modern SDK: framework-dependent, self-contained, single-file, trimmed and NativeAOT. Symbol renaming, STREAM string encryption and control flow obfuscation, including Chained State, survive trimming and ahead-of-time compilation unchanged. Features that rely on a memory-mapped image or on dynamic IL, such as Code Encryption, Dynamic Proxy and the desktop tampering check, have documented limits on MAUI, Blazor and AOT targets; each feature page states them, and the Obfuscate .NET MAUI and Blazor WebApp examples show working configurations."},{"page":4,"heading":"Runs on Windows, macOS and Linux (Ultimate)","anchor":"runs-on-windows-macos-and-linux-","text":"Every edition includes the command line tool and MSBuild task for Windows (zip packages). Running Babel Desktop, running Babel on macOS and Linux, and inside Azure DevOps, GitHub Actions and similar CI build pipelines, requires the Ultimate edition, or the Server and Data Center licensing editions that include it: only these ship the Babel Obfuscator NuGet packages, which run Babel as a dotnet tool on any operating system and integrate it into dotnet build and dotnet publish. The Enterprise edition is limited to the Windows command line tool and MSBuild task of the .NET Framework zip package.\nBecause obfuscation works on IL, the operating system of the build host does not constrain the target: a Windows build agent can protect assemblies published for linux-x64, linux-arm64 or osx-arm64, and a Linux container can protect a Windows desktop application. Teams can therefore keep the build environment they already have."},{"page":4,"heading":"Fully Managed Code Encryption and Virtualization","anchor":"fully-managed-code-encryption-and-virtualization","text":"Code Encryption rewrites the IL of a method into a custom instruction set, encrypts it, and leaves in its place a stub that hands control to the Babel Virtual Machine (BVM), a lightweight managed runtime embedded in the obfuscated assembly. The BVM decrypts and executes the method when it is called. The method body no longer exists in the assembly in a form a decompiler can read, and the instructions cannot be patched.\nThe solution is entirely managed: encrypted methods are not replaced by native code for a specific platform, so the cross-platform nature of .NET is preserved and the JIT compiler still optimizes for the target CPU. Encrypted code can be kept in external code files deployed alongside a license, or protected with a password supplied at run time, which is the basis for feature-based licensing. The Hardware Dongle Binding article shows how to tie encrypted code to a physical device. Because it costs performance, Code Encryption is meant for the sensitive parts of the code base, with the other protections covering the rest."},{"page":4,"heading":"Hardened Against Automated Deobfuscation (Ultimate)","anchor":"hardened-against-automated-deobfuscation-","text":"Classic obfuscation defeats a human reader; a class of automated tools can undo some of it in a single pass, by statically recovering the order of a flattened method or reading the key that sits next to an encrypted string. Version 12.0 adds two transforms designed for that adversary:\nChained State flattens a method around a dispatcher whose original order cannot be recovered by static analysis alone. In internal testing against a standard automated deobfuscator, methods flattened with the ordinary switch algorithm were rebuilt, while the same methods flattened with chain were left intact. It emits verifiable IL, adds no runtime dependencies, and runs within a few percent of ordinary flattening.\nSTREAM string encryption encrypts each string individually with an authenticated cipher, decrypts it lazily on first use, and never stores the key inline. Identical strings encrypt to different bytes, no point in time holds the whole string set in clear text, and the fully managed decryptor publishes unchanged under trimming, NativeAOT and FIPS mode."},{"page":4,"heading":"Detects Debugging and Tampering, on Desktop and Mobile","anchor":"detects-debugging-and-tampering-on-desktop-and-mobile","text":"Anti-debugging code injected into the assembly detects an attached debugger and terminates the process or invokes a method of yours. Tampering detection verifies at start-up that the assembly is the one Babel produced: on desktop targets it hashes the loaded image in memory and compares it with a hash stamped at obfuscation time.\nStarting with version 12.0, tampering detection covers .NET MAUI, where the desktop technique cannot apply. On Android the obfuscated app compares the certificate the running APK was signed with against trusted signer fingerprints you pin at obfuscation time, so a repackaged or re-signed app is rejected. On iOS it verifies its own bundle identifier and Apple Team identifier. Both checks inspect the operating-system package rather than the managed image, so they keep working with trimming and full AOT. In every case the reaction is yours to choose: terminate, or run a custom handler that can log, degrade features or phone home."},{"page":4,"heading":"Simplifies Deployment by Merging and Embedding Dependencies","anchor":"simplifies-deployment-by-merging-and-embedding-dependencies","text":"Merge and Embed turns an application and its dependencies into a single file. Merging folds the code of referenced assemblies into the target and renames it together with your own, so the merged types can be internalized and obfuscated as one unit, which both simplifies deployment and shrinks the surface of readable code. Embedding stores an assembly whole, as an encrypted resource that is loaded at run time, for third-party or strong-named assemblies that must not be altered. The two can be combined in the same project."},{"page":4,"heading":"Optimizes Code and Metadata","anchor":"optimizes-code-and-metadata","text":"Beyond protection, Babel optimizes the assembly it produces. Dead code removal strips methods, fields, properties and types that are never used. Metadata optimizations seal classes automatically, remove unneeded custom attributes, System.Enum types and property and event constructs. Code optimizations inline small methods and properties and remove const fields. The result is an assembly that is smaller on disk, faster to load, and harder to read, because the metadata a reverse engineer relies on has been reduced to what the runtime needs."},{"page":4,"heading":"Integrated With Visual Studio, MSBuild, NuGet and Build Servers","anchor":"integrated-with-visual-studio-msbuild-nuget-and-build-servers","text":"Babel runs inside the build rather than after it. The Babel MSBuild task obfuscates from Visual Studio and from any build server that runs MSBuild, and every task property is documented with IntelliSense in the project file. The Babel.Obfuscator NuGet package  (Ultimate) goes further for SDK-style projects: a single package reference places the task at the right point of the dotnet build and dotnet publish pipeline, before trimming and ahead-of-time compilation rewrite the assembly, which is the only order in which those publish modes can be protected. The build server examples cover Azure DevOps, GitHub Actions, AppVeyor and App Center, and show how to run unit tests against the obfuscated output; like the NuGet package, they require the Ultimate edition."},{"page":4,"heading":"Available as a Command Line Tool, With an AI-Friendly Mode","anchor":"available-as-a-command-line-tool-with-an-ai-friendly-mode","text":"Everything Babel can do is available from the command line, on Windows, Linux and macOS. Since version 11.7 the tool also offers an AI-friendly mode for pipelines and agents: --format=json or --format=ndjson emit a structured, versioned event stream on stdout while diagnostics go to stderr, --quiet suppresses the banner and fails fast instead of prompting, and --strict-exit enables semantic exit codes that distinguish invalid arguments, missing input, obfuscation, licensing and signing failures. The same flag turns --help into a machine-readable description of every option."},{"page":4,"heading":"Operated by AI Assistants Through MCP","anchor":"operated-by-ai-assistants-through-mcp","text":"Babel Desktop can host a Model Context Protocol server, so an assistant such as Claude Code connects to the running application and drives it: create a project, add assemblies, write rules, choose what to merge or embed, obfuscate, read warnings and statistics, decode a stack trace, author a theme, and take a screenshot to check the result. Tools cover the operations you perform most often, plus tools for settings, Babel Licensing and application updates. On the Server and Data Center editions the same server manages the licensing database: customers, products, orders, licenses, signing keys, and license generation and export.\nThe server is off by default, binds to the loopback address only, and can require an access token on every request. Babel Licensing offers a separate MCP server for the hosted Licensing Service."},{"page":4,"heading":"Decodes Obfuscated Stack Traces","anchor":"decodes-obfuscated-stack-traces","text":"Renaming changes the names that appear in exception stack traces, so Babel produces an XML map file for every obfuscated assembly and provides the tools to translate a trace back. The Stack Decoder in Babel Desktop, and the --stacktrace command line option, restore the original names, with optional PDB support for line numbers. When Dynamic Proxy is enabled, the decoder names the method behind every proxy bridge frame and can hide the Babel-generated frames altogether, leaving a trace identical to the one the unobfuscated application would produce. Map files also drive cross-assembly renaming, so an application and its libraries can be obfuscated in separate builds and still agree on the renamed symbols."},{"page":4,"heading":"FIPS-Ready","anchor":"fips-ready","text":"Assemblies protected with Babel run on hosts in FIPS mode. The features that decrypt content at run time, Code Encryption, String Encryption, Resource Encryption and Value and Array Encryption, can be configured to use a self-contained managed AES decryptor, so the injected runtime never depends on the platform cryptographic provider and the application starts even in a container whose OpenSSL FIPS provider is missing. The FIPS Compliance page explains the environment condition, the obfuscation-time fix and the environment-level fix."},{"page":4,"heading":"Extensible With Rules, Attributes and Plugins","anchor":"extensible-with-rules-attributes-and-plugins","text":"Every feature can be tuned per symbol. XML rules select types and members by pattern, attribute, visibility or inheritance and enable, disable or configure a feature for them; custom attributes do the same from the source code. The obfuscation Agent analyses the assembly before obfuscation and generates the rules that keep reflection, serialization, data binding and dynamic code working. For anything beyond that, plugins written in .NET can add string and value encryption algorithms, custom renaming schemes, generated rules and code transformations, with open-source samples on GitHub as a starting point."},{"page":5,"heading":"","anchor":"","text":"To get started with Babel Obfuscator, please follow the installation instructions.\nInstall\nProduct Activation\nBabel Obfuscator is available as a:\nCommand line tool\nMSBuild task\nNuGet package\nBabel Desktop (Windows, macOS and Linux)\nThe Ultimate edition and the Babel Licensing Server and Data Center editions include the NuGet packages and tools that allow using Babel Obfuscator on Windows, Linux and macOS as a dotnet tool. Babel Desktop runs the engine on .NET 10 and also requires one of these editions. The single-user Enterprise edition provides the command line tool and MSBuild task of the .NET Framework zip package on Windows.\nTo learn more about using Babel Obfuscator, please refer to the following examples and articles\nExamples\nArticles"},{"page":6,"heading":"","anchor":"","text":"Babel Obfuscator is available as the Babel Desktop application for Windows, macOS and\nLinux, as zip packages with the command line tool and the MSBuild task, and as NuGet\npackages and a dotnet CLI tool."},{"page":6,"heading":"Babel Desktop","anchor":"babel-desktop","text":"Babel Desktop is the cross-platform application for Windows, macOS and Linux that edits and runs .babel obfuscation projects and manages a Babel Licensing Service. See Install Babel Desktop for the installers and Product Activation for the license requirements.\n[!NOTE]\nBabel Desktop does not install the babel command line tool. To run Babel from a terminal, a build script or MSBuild, use the zip packages or the dotnet tool described below."},{"page":6,"heading":"Command Line and MSBuild Task (zip packages)","anchor":"command-line-and-msbuild-task-zip-packages","text":"The command line tool and the MSBuild task are distributed as zip packages, one for each target framework:\nPackage | Framework\nbabel_net472_<ver>.zip | .NET Framework 4.7.2\nbabel_net80_<ver>.zip | .NET 8\nbabel_net90_<ver>.zip | .NET 9\nbabel_net100_<ver>.zip | .NET 10\nEach package contains:\nbabel, the Babel Obfuscator command line tool\nlic, the Babel Licensing command line tool\nHardwareId, the tool that reads the hardware identifier of the machine\nthe MSBuild task in the MSBuild folder: Babel.Build.dll, Babel.Build.targets and Babel.Build.xsd\nTo install the command line tool:\nExtract the package\nExtract the zip package to a folder of your choice, for example C:\\Tools\\Babel on Windows or ~/Babel on Linux and macOS.\nAdd the folder to PATH\nAdd that folder to the PATH environment variable.\nCopy the license file\nCopy your license file babel.licenses into the same folder, next to babel. See Product Activation for the other ways to provide the license.\nVerify the installation\nOpen a new PowerShell or terminal window and enter:\n> babel\nThe .NET Framework package runs on Windows only. The .NET 8, .NET 9 and .NET 10 packages also run on Linux and macOS through the dotnet host, provided the matching .NET runtime is installed:\ndotnet ~/Babel/babel.dll\nOn Linux and macOS you can also install babel as a dotnet tool, as described in Installing Babel CLI dotnet Tool.\nThe Babel Encrypt plugin is distributed separately in the babel_encrypt_plugin_<ver>.zip package."},{"page":6,"heading":"Babel NuGet Packages","anchor":"babel-nuget-packages","text":"Upon purchasing the Babel Obfuscator Ultimate Edition or the Babel Licensing Server and Data Center editions, you acquire several NuGet packages. These contain the Babel Obfuscator NuGet packages:\nPackage | Description | Edition\nBabel.Obfuscator.x.y.z.nupkg | This package allows using Babel Obfuscator in any .NET project | Ultimate\nBabel.Obfuscator.Tool.x.y.z.nupkg | Babel Obfuscator dotnet CLI tool | Ultimate\nBabel.Licensing.Tool.x.y.z.nupkg | Babel Licensing dotnet CLI tool | Server, Data Center\nBabel.Licensing.x.y.z.nupkg | Babel Licensing client components | Server, Data Center\nBabel.Data.x.y.z.nupkg | Babel Licensing data components | Server, Data Center\nThese NuGet packages are not available on the public NuGet repository. To use them in your projects, you need to install them on your private NuGet feeds or your local machine.\nThere are several NuGet private feeds available:\nAzure Artifacts\nGitHub Package Registry\nGitLab Package Registry\nMyGet\nTeamCity\nGitea (Open Source)\nNuGet Server (Open Source)\nIf you don't have a private NuGet feed, you can create one on your local machine.\n[!NOTE]\nRegardless your packages are hosted on a server or your local machine, you can access them using the nuget CLI tool or Visual Studio."},{"page":6,"heading":"Create a Local NuGet Feed Using dotnet","anchor":"create-a-local-nuget-feed-using-dotnet-","text":"If you have installed Visual Studio or dotnet SDK, you can access NuGet directly from the dotnet CLI tool. Now you have to decide where to store your packages on your local machine. For this example, we will create the folder NuGet under the user Documents folder. If you are on Linux or Mac OS, you can create the folder under the user home directory ~/NuGet.\nYou can add the packages to your local feed using dotnet nuget add command.\nWindows PowerShell or DOS shell:\ndotnet nuget add source %UserProfile%\\Documents\\NuGet\nLinux or Mac OS:\ndotnet nuget add source ~/NuGet\nThe dotnet tool should report that the package was successfully added, and you can now access your packages through the dotnet command."},{"page":6,"heading":"Create a Local NuGet Feed Using Visual Studio","anchor":"create-a-local-nuget-feed-using-visual-studio","text":"Open the Package Sources options\nOpen Visual Studio and from the Tools menu select Options. In the Options panel, search for NuGet and select the Package Sources node under the NuGet Package Manager tree item.\n\nVisual Studio Options Package Sources\nAdd the Babel package source\nPress the button with the plus icon and enter the Name field Babel and the Source field the full path to the folder containing the Babel Obfuscator NuGet package files. Press the OK button.\nReference the Babel.Obfuscator package\nIn the Solution Explorer right click your project file. Select Manage NuGet Packages…\nSelect your newly added Babel package source in the Package source combo box, then Install the Babel.Obfuscator package.\n\nVisual Studio NuGet package manager\nAdd the license file\nCopy your license file babel.licenses in the solution folder and rebuild the solution."},{"page":6,"heading":"Installing Babel CLI dotnet Tool","anchor":"installing-babel-cli-dotnet-tool","text":"Once the Babel NuGet packages are in your local NuGet repository, you can install the CLI tools using dotnet tool install command.\nInstall Babel Obfuscator CLI tool babel:\ndotnet tool install Babel.Obfuscator.Tool -g\nInstall Babel Licensing CLI tool lic:\ndotnet tool install Babel.Licensing.Tool -g\nTo show the versions of the dotnet tool installed, use the following command:\ndotnet tool list -g\n\nPackage Id                 Version      Commands\n------------------------------------------------\nbabel.licensing.tool       12.0.0.1     lic     \nbabel.obfuscator.tool      12.0.0.1     babel"},{"page":6,"heading":"Update Babel CLI dotnet Tool","anchor":"update-babel-cli-dotnet-tool","text":"To update Babel Obfuscator CLI tool babel, run in your terminal:\ndotnet tool update Babel.Obfuscator.Tool -g\nTo update Babel Licensing CLI tool lic, run in your terminal:\ndotnet tool update Babel.Licensing.Tool -g"},{"page":6,"heading":"Uninstalling Babel CLI dotnet Tool","anchor":"uninstalling-babel-cli-dotnet-tool","text":"To remove Babel Obfuscator CLI tool babel, run in your terminal:\ndotnet tool uninstall Babel.Obfuscator.Tool -g\nTo remove Babel Licensing CLI tool lic, run in your terminal:\ndotnet tool uninstall Babel.Licensing.Tool -g"},{"page":7,"heading":"","anchor":"","text":"Babel Obfuscator can be used in demo mode without requiring a license. However, during the trial period, users can only utilize the obfuscation renaming feature. It's important to note that assemblies obfuscated in demo mode will cease to function after a specific date, as indicated in the obfuscation log by the warning code W00000.\nWarning [W00000]: This is an evaluation version; the obfuscated assembly will no longer work after 15/08/2024 17:16:27\nThe presence of warning W00000 in the build log indicates that the obfuscated assembly is running in demo mode and will cease to function after the specified expiration date. Consequently, such assemblies cannot be distributed for production or retail use, as they are designed to stop working post-expiration.\nTo ensure that only fully licensed and unrestricted assemblies are used in a retail or production build, it is recommended to configure Babel to treat Warning W00000 as an error.\nThis configuration will cause the build process to fail if the warning is encountered, preventing the release of demo-mode obfuscated assemblies. You can achieve this by adding the WarningsAsErrors property to the Babel task in your build script, as shown below:\n<Babel WarningsAsErrors=\"W00000\" ... />"},{"page":7,"heading":"","anchor":"","text":"By setting WarningsAsErrors to include W00000, any occurrence of this warning will be treated as an error, thereby halting the build process. This ensures that the build will only succeed if a valid license is properly installed ensuring that the resulting assemblies are not subject to expiration or functionality restrictions."},{"page":7,"heading":"License File","anchor":"license-file","text":"To fully unlock all features and ensure continued functionality, purchasing a Babel Obfuscator license is necessary.\nUpon purchasing Babel Obfuscator and obtaining the license, you will receive a file named \"babel.licenses.\" This file is in XML format and is digitally signed, containing the relevant license information for the specific product edition that you have purchased.\nDo not edit the license file: a modified file is no longer valid.\nTo install the license, copy the babel.licenses file into the folder where you extracted the zip package, next to babel.exe or babel.dll. Babel reads the license from there and unlocks the features of the edition you purchased, and the assemblies it obfuscates no longer expire after the trial period.\nTo keep the license file somewhere else, set the environment variable BABEL_LICENSE_PATH to its full path. This works on any operating system.\nWindows PowerShell, current session:\n$env:BABEL_LICENSE_PATH = \"C:\\Babel\\babel.licenses\"\nWindows, persistent for the current user:\nsetx BABEL_LICENSE_PATH \"C:\\Babel\\babel.licenses\"\nLinux and macOS:\nexport BABEL_LICENSE_PATH=~/Babel/babel.licenses\nIn Babel Desktop, open Settings, choose License, select License file as the license source and click Browse... to load the file.\nYou can access your license information by typing into a PowerShell or terminal window:\nbabel.exe --license\nIf a valid license is found, you will get your license information:"},{"page":7,"heading":"License File","anchor":"license-file","text":"License Id: licC2A87385\n   issued: 19 Dec 2022\n\nProduct: Babel Obfuscator Ultimate 10.0.0.0\n   Babel Obfuscator for .NET Framework\n\nLicensed to: babelfor.NET\n   contact info: sales@babelfor.net\n\nFields: ultimate\nIf the license file is not found you will get the following message:\nError: A valid license could not be found. Please contact http://www.babelfor.net for assistance.\nUsing Secrets License Key\nOn build servers that support secrets, it is possible to securely store and manage the Babel Obfuscator license key as a secret, which can then be accessed during the build process. By setting up the license key as a secret, you can ensure that the key is protected and only accessible by authorized users or processes. This helps to maintain the security and integrity of your application's code and assets.\nBabel Obfuscator provides the option to load the license directly from an environment variable that is used to store the license key. This can be done by entering the following command at the command line:\nbabel --license env:BABEL_LICENSE\nHere, BABEL_LICENSE is the environment variable that contains the Babel Obfuscator license key. Using this method, the license key can be securely stored in an environment variable using the build server secrets and accessed by Babel Obfuscator during the obfuscation process.\nThe following example shows how to pass the BABEL_LICENSE environment variable to the build step using the secrets.BABEL_LICENSE_SECRET, which stores the license key."},{"page":7,"heading":"License File","anchor":"license-file","text":"name: dotnet package\n\non: [push]\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        dotnet-version: [ '3.1.x', '7.0.x' ]\n\n    steps:\n      - uses: actions/checkout@v3\n      - name: Setup .NET Core SDK ${{ matrix.dotnet-version }}\n        uses: actions/setup-dotnet@v3\n        with:\n          dotnet-version: ${{ matrix.dotnet-version }}\n      - name: Install dependencies\n        run: dotnet restore\n      - name: Build\n        run: dotnet build --configuration Release --no-restore\n        env:\n          BABEL_LICENSE: ${{ secrets.BABEL_LICENSE_SECRET }}\nIf you are using the Babel Obfuscator NuGet package in your project, define the BabelLicense property as follow:\n<PropertyGroup>\n  <BabelLicense>$(BABEL_LICENSE)</BabelLicense>\n</PropertyGroup>\nBy setting the BabelLicense property to $(BABEL_LICENSE), Babel Obfuscator will load the license key from the defined environment variable BABEL_LICENSE, which is set to the secret BABEL_LICENSE_SECRET in the build step. This approach allows for secure storage and usage of the license key in the build process. To know more please review the sample project GitHub Actions."},{"page":7,"heading":"Activation Key","anchor":"activation-key","text":"If you have received an activation key for Babel Obfuscator, such as:\nDWTW3-SPGGH-04DJ4-4K809\nyou can activate your product in Babel Desktop:\nOpen the License settings\nOpen Settings and choose the License category.\nSelect Activation key\nSelect Activation key as the License source.\nEnter the activation key\nEnter the activation key you received, including the dashes.\nActivate\nClick Activate.\nThe activation is stored on this machine and restored every time Babel Desktop starts. Click Deactivate to release the activation from this machine.\nYou can also activate the license from the command line:\nbabel --license activate:DWTW3-SPGGH-04DJ4-4K809\nand release it with:\nbabel --license deactivate"},{"page":7,"heading":"Floating License Usage","anchor":"floating-license-usage","text":"Babel Obfuscator offers the flexibility of operating under a floating license mechanism. This is particularly useful for organizations or teams where multiple users might need to access the software, but not simultaneously. The unique identifier for requesting a floating license is embodied in a user key, which follows a format resembling:\nP1N1J-EH5VA-VGSFU-7EOK8\nWhen utilizing this floating license system, the secrets.BABEL_LICENSE_SECRET is configured to store this user key securely. In the context of your project's build configuration, the <BabelLicense> XML element should be structured as:\n<PropertyGroup>\n  <BabelLicense>floating:$(BABEL_LICENSE)</BabelLicense>\n</PropertyGroup>\nBy adopting this configuration, when Babel Obfuscator runs during the build process, it will recognize the floating:$(BABEL_LICENSE) instruction and attempt to retrieve a floating license using the user key stored in the BABEL_LICENSE environment variable.\nIn Babel Desktop, open Settings, choose License, select Floating license as the license source, enter the user key and click Request license. Check Request automatically at startup to request it every time the application starts. The floating license is released when Babel Desktop exits."},{"page":7,"heading":"Troubleshooting License File Issues","anchor":"troubleshooting-license-file-issues","text":"If you have license file issues, please check out the following points.\nEnsure the license file babel.licenses is next to babel.exe or babel.dll in the folder where you extracted the zip package, or that the BABEL_LICENSE_PATH environment variable points to it.\nEnsure you installed the retail version of Babel Obfuscator. The DEMO version of Babel Obfuscator available to download at babelfor.net is not suited to run with a retail license. If you are using the DEMO version, replace it with the retail package.\nThe babel.licenses license file should be the exact one you received with the Babel binary packages. Each version of Babel Obfuscator comes with its license file. A license file is made for one specific version of the product; it also unlocks newer versions released while its maintenance is active, but not versions released after the maintenance expired.\nThe babel tool version can be displayed with the following command:\nbabel --version\n\nAssembly version: 10.0.0.0\nProduct version: 10.0.0.0\nFile version: 10.0.0.0"},{"page":8,"heading":"","anchor":"","text":"Babel Obfuscator provides a command line tool on Windows, Mac and Linux. This\nparagraph will describe how to use Babel Obfuscator from the command line.\nBabel Obfuscator is available as a command line tool, which makes it easy to integrate into your build pipeline and automate the obfuscation process. The command line tool, named \"babel\", allows you to easily specify the input assemblies, output file, and various obfuscation options. To start babel from the command line, open the PowerShell on Windows or the Terminal on Mac OS and enter:\n> babel\nThe \"babel\" command launches the babel executable command line tool. This command accepts the following syntax:\nbabel <primary assembly source> [<other assemblies>...] [options]\nThe first parameter, <primary assembly source>, is the target assembly (or primary assembly) you want to obfuscate and is a mandatory parameter.\nThe [<other assemblies>...] is an optional list of assemblies that will be merged with the primary assembly.\nThe [options] are a list of command line switches to configure Babel Obfuscator. Each command line switch is prefixed by a double hyphen, for example:\n--embed\nInfo: Bundling Command Line Options\n\nCommand line options can be bundled using the short syntax. Use a single hyphen to enter multiple options in a bundled expression:\n\nbabel myapp.exe --types --methods --properties --fields --events\n\nIt is equivalent to:\n\nbabel myapp.exe -tmpfe\nTo show all available command line options enter the command line:"},{"page":8,"heading":"","anchor":"","text":"babel --help\nYou can show a detailed description of every command line switch by entering:\nbabel --help [command name]\nFor example\nbabel --help controlflow\nwill output detailed help for the controlflow command line switch:\n> babel --help controlflow\ncontrolflow (nocontrolflow, no-controlflow, control-flow, no-control-flow, i)\nusage: --[no]controlflow\n  Enable ([no]disable) MSIL control flow obfuscation (default: disabled)\n  Use this option to alter the method control flow. \n  Key-value pairs can optionally be entered to configure code scrambling:\n\nProduces verifiable MSIL code\n\n  goto=[on/off]    Whether to insert irrelevant branches\n  switch=[on/off]  Whether to enable switch scrambling\n  case=[on/off]    Whether to hide case constants\n  if=[on/off]      Whether to enable if scrambling\n  call=[on/off]    Whether to enable random calls\n  value=[on/off]   Whether to use value encryption\n  token=[on/off]   Whether to enable emission of method tokens\n\nProduces not verifiable MSIL code\n  underflow=[on/off]  Whether to enable stack underflow ()\n\nExamples:\n--controlflow switch=on --controlflow case=on\n\nThis option can be entered multiple times."},{"page":8,"heading":"","anchor":"","text":"Info: AI-friendly / machine-readable output (since 11.7.0)\n\nBabel Obfuscator can also emit a structured stream on stdout for CI pipelines\nand AI/agent integrations. Pass --format=json or --format=ndjson to switch\nto the babel.cli.v1 schema, optionally with --quiet (no logo, fails on\nprompts) and --strict-exit (semantic exit codes 10/20/30/40/50).\nThe same flag also makes --help and --version machine-readable.\nSee AI-Friendly Mode for the full reference."},{"page":9,"heading":"","anchor":"","text":"The Babel Obfuscator command line tool accepts different options. A double hyphen character prefixes each option. The following section will describe each option you can enter at the command line."},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"Those options are typically used to configure general obfuscation features or the way Babel Obfuscator deals with the target assembly.\n--help [option]\nTyping --help without any parameters will show the main help menu. When the parameter [option] is specified, Babel will display the extended help for the command specified. For example:\n--help strings\nPrints the following information:\nstringencryption (nostringencryption, no-stringencryption, string-encryption, no-string-encryption, strings, no-strings)\nusage: --[no]stringencryption [name]\n  Enable ([no]disable) string encryption (default: disabled)\n\n  When enabled, all the user strings in the target assembly will be encrypted. The   \n  optional parameter name sets the encryption type.\n\nhash - Compressed hash table. The strings are arranged into compressed encrypted hash table data. This algorithm ensures tamper protection.\nxor - Inline xor strings.\nstream - Authenticated per-string encryption, decrypted lazily. Fully managed (AOT/trim/FIPS safe).\nThis shows a list of aliases admitted for the command, followed by the command usage and a short description.\n--[no]logo\nThis option controls the display of the Babel Obfuscator copyright message at startup. The copyright message will not be shown if the optional prefix [no] is specified.\n--format <format>\nAvailable since 11.7.0."},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"Selects the output format of stdout. Allowed values are text (default), json and ndjson. With json or ndjson, the run produces a structured stream conforming to the babel.cli.v1 schema and human diagnostics are routed to stderr.\nbabel myapp.exe --format=json > result.json\nbabel myapp.exe --format=ndjson | jq -c 'select(.level==\"error\")'\nThe same flag also switches --help and --version to a machine-readable representation. See the AI-Friendly Mode page for the schema, examples and a full reference.\n--quiet (-q)\nAvailable since 11.7.0.\nSuppresses the logo banner and changes interactive password prompts to fail-fast with an explicit error instead of blocking on input. Safe for unattended/agent invocations.\nbabel myapp.exe --quiet --keyfile mykey.pfx --keypwd env:KEY_PWD\n--strict-exit\nAvailable since 11.7.0.\nEnables semantic exit codes: 0 success, 10 invalid arguments, 20 input not found, 30 obfuscation failure, 40 licensing failure, 50 key/signing failure. Without this flag, the legacy 0/1 contract is preserved. See AI-Friendly Mode — --strict-exit for the full table and exitReason semantics.\n--license [path|env]\nWhen the optional argument is not specified, it displays available license information. Optionally you can specify the license file path.\nbabel --license C:\\Babel\\babel.licenses\nAlternatively, you can specify a search directory where Babel should look for the license file.\nIf you have a license key, you can use the env option to pass it to Babel as follows:"},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"babel --license env:BABEL_LICENSE_KEY\nHere the BABEL_LICENSE_KEY is the Environment variable containing the license key.\n--verbose <n>\nSets the console output verbosity level. Where <n> is a mandatory non-negative integer number. If 0 is specified, no messages are displayed during obfuscation. A number greater than 10 will make Babel show debug information.\n--noconfig (@)\nSkip loading the default configuration for command line values. If specified, all default values that are in the babel.exe.config file, are ignored:\nbabel myapp.exe --noconfig\nbabel myapp.exe @\n--nowarn <warn list>\nSuppress the notification of one or more warning messages. The <warn list> parameter represents a list of warning IDs separated by a comma character. Babel will silently ignore warning numbers passed to the nowarn option.\n--[no]warnasinfo [warn list]\nSpecifies a list of warnings that should be downgraded to information messages. The [warn list] is an optional comma-delimited list of the warning IDs.\n--[no]warnaserror [warn list]\nSpecifies a list of warnings that should be treated as errors halting the obfuscation process. The [warn list] is an optional comma-delimited list of the warning IDs.\n--[no]statistics [file]\nWhether to generate obfuscation statistics, which can either be logged at the end of the program or saved to a file if specified.\nThe following additional options are available:\nfull=[on/off]    Whether to collect additional method statistics"},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"By enabling full obfuscation statistics, additional method information like CYC (Cyclomatic Complexity) is collected. This could cause resource consumption, especially when processing assemblies with many types.\nHere is an example of obfuscation statistics taken from the console output:\nBabel statistics:\n  Random seed: 6dfabc3f1a479d66\n  Experimental features: false\n  Multithread obfuscation: true\n  \n  Rules phase, elapsed time 00.000s\n  Processed rules: 0\n  \n  Agent phase, elapsed time 00.046s\n\n  Renaming phase, elapsed time 00.082s\n  Unicode normalization: off\n  Flatten namespaces: on\n  Overloaded renaming: off\n  Virtual functions: on\n  XAML renaming: on (res)\n  \n  Symbols statistics:\n      76/[  106]        types: 71.70 %\n       0/[    2]       events: 0.00 %\n      82/[  236]      methods: 34.75 %\n       7/[   22]   properties: 31.82 %\n     219/[  258]       fields: 84.88 %\n  \n     384/[  624]      overall: 61.54 %\n  \n  Encrypt Strings phase, elapsed time 00.016s\n  String algorithm: hash (.NET Core)\n  Number of encrypted strings: 266\n--[no]agent (a)\nThis option enables or disables the obfuscation Agent. When enabled, the agent performs a static analysis of the code to prevent renaming or obfuscation of target assembly symbols that could otherwise cause malfunctions in the obfuscated application.\n--assemblyname <option>\nThis option provides flexibility in determining the name of the target assembly.\nThe available options are:"},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"--assemblyname name=assemblyname\n  --assemblyname inputfilename\n  --assemblyname outputfilename\n  --assemblyname nochange (default)\nThe default behaviour is nochange. It means that the assembly name will not be changed from its original value. If you don't specify any --assemblyname option, this will be the behavior.\n--[no]satellite [assembly]\nEnables, [no] disable the processing of satellite assemblies. If the optional parameter [assembly] file is specified, treat the specified assembly file as a satellite assembly of the target assembly.\n--addsearch <path>\nAdds the specified directory <path>, to the list of folders where Babel searches for referenced assemblies.\nThe parameter <path> can be a wildcard expression to match a set of directories. The following special characters can be used to make a wildcard expression:\n| \n* | matches any number of any characters including none\n? | matches any single character\n** | matches any directory recursively\n[a-z] | matches one character from the range given in the bracket\n[!ab] | matches any characters that are not in the given bracket\nThe following special strings can be combined into the path expression for the currently searched assembly:\n| \n:assemblyname: | searched assembly name\n:assemblyversion: | searched assembly version\n:assemblypublickeytoken: | searched assembly public key token\nThis option can be entered multiple times.\n--addsearch .\\**\\lib\n --addsearch .\\:assemblyname:\\**\\netcoreapp2.0\nW00013 in the BAML-binding path"},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"The W00013 warning emitted by Babel's assembly resolver — Could not resolve assembly <assembly> — is generally informative. For most types of code in most assemblies, an unresolved reference does not change the obfuscated output: Babel has enough information from the metadata it has already loaded to perform renaming, control flow obfuscation, string encryption, and other transformations without consulting every referenced assembly.\nThere is, however, at least one specific case in which W00013 correlates with a real change in the obfuscated output: assemblies that contain embedded BAML referencing types defined in an unresolved assembly. When Babel reads BAML to discover XAML-bound members (see Aligning string literals with renamed XAML-bound members), it needs to resolve every BAML element's CLR type. If the assembly that declares such a type is not on the search path, the resolver emits W00013 for it; the BAML element is then not bound to its backing field, and the field is not flagged as XAML-bound. As a consequence, when the field is later renamed, the alignment step that rewrites string literals matching the original name is silently skipped: the field receives its new name, but every literal naming the original field is left untouched, leaving the obfuscated assembly internally inconsistent and any name-based runtime lookup based on those literals broken."},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"For projects that contain embedded BAML, before treating an obfuscation run as final for production, verify that every assembly defining types referenced from BAML elements is reachable through --addsearch and that the trace log shows no W00013 for those assemblies. The same setting is exposed by the SearchDirectories MSBuild Babel Task property and by the SearchDirectories setting in the Files & dependencies group of the Babel Desktop properties panel.\nThis warning behavior is scoped to projects with embedded BAML; in non-WPF projects, or in projects without embedded BAML, W00013 is typically informational and does not affect the obfuscated output.\n--quickrule <rule>\nEnter a quick rule definition. A quick rule can be used instead of an XML rule when the user wants to configure the obfuscation process without having to make an XML rule file.\nQuick rule syntax:\nfeature[=exclude];[regex];[access];[target]\nWhere:"},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"| \nfeature | Is the name of the targeted feature\n[=exclude] | Can be specified to disable the feature\n[regex] | Is an optional regular expression used to filter the symbols. By default, the obfuscator will take all symbols.\n[access] | Set the visibility of the symbols that should be processed and can be one of the following values: Public, Protected, Internal, Private, All (default All)\n[target] | Specifies the symbol kind. Admitted values are: Classes, Delegates, Structures, Interfaces, Enums, Events, Methods, Properties, Fields, StaticFields, Resource, All (default All)\nThe quickrule switch can be entered multiple times. Quick rules will be processed in the order they are encountered at the command line and before the processing of any XML rule.\nRename all public symbols inside the target assembly:\nbabel myapp.exe --quickrule renaming;.*;Public\nDisable string encryption within the ACME namespace:\nbabel myapp.exe --quickrule \"string encryption=exclude;ACME.*;All;Methods\"\nEnable code encryption for the ACME.Licensing class:\nbabel myapp.exe --quickrule \"msil encryption=on;ACME.Licensing.*\"\n--dbghelpdlldir <path>\nThis option runs on Windows OS only and configures the path to the dbghelp.dll, allowing Babel Obfuscator to load debug symbols from the Microsoft Symbol Server.\n--trace <regex>\nEnables obfuscation tracking for symbols whose full name signature matches the specified regular expression. This option can be used to debug regular expressions."},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"babel myapp.exe --trace MyNamespace.MyClass::MyMethod\nTrace the method named MyMethod and log debugging information about its obfuscation status.\n--randomseed <seed>\nSet the seed used to initialize the Babel Obfuscator random number generator. It can be set to have a deterministic obfuscation. The parameter <seed> can be any hexadecimal string.\n--use <key=value>\nSet additional Babel Obfuscator options as key-value pairs.\ndebugxaml=[on/off]          Whether to enable XAML debug mode\nencryption=<name>           Set encryption algorithm (Aes, AesManaged, DES, TripleDES, Rijndael, RC2, XOR)\nexperimental=[on/off]       Whether to enable experimental features\nloadtomemory=[on/off]       Whether to load assemblies to memory\nparallel=[on/off]           Whether to perform multithread obfuscation\ntagassembly=[on/off]        Whether to tag assembly with the BabelObfuscator attribute\nobfuscationattr=[skip/keep] Skip processing or force attribute retention\nlogtimestamp=[on/off/fmt]   Whether to add a timestamp to the log output (fmt date time format)\nExamples:\nOutput debugging information related to all XAML resources having a name starting with Panel\nbabel myapp.exe --use debugxaml=Panel.* --verbose 5\nTag the obfuscated assembly with the [BabelObfuscator] attribute.\nbabel myapp.exe --use tagassembly=on\nForce Babel Obfuscator to use TripleDES encryption algorithm\nbabel myapp.exe --use encryption=TripleDES"},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"Protect with the managed AES algorithm so the runtime injected into the obfuscated assembly decrypts without the platform cryptographic provider. Use this to make protected assemblies start on hosts where that provider is unavailable, such as containers with a broken OpenSSL FIPS state (see FIPS Compliance). The obfuscator still encrypts with the platform provider on the build host and produces the same ciphertext; only the injected decryptor changes.\nbabel myapp.exe --msilencryption --use encryption=aesmanaged\nThe experimental option can also accept a list of obfuscator features, including \"all\" which allows using new obfuscation algorithms not yet released for all .NET platforms.\nbabel myapp.exe --use experimental=all\nWhen experimental features are enabled in Babel, it is important to note that the obfuscation tool will not verify if the platform-specific requirements are met. This means that all the obfuscations configured will be executed regardless of whether they are appropriate for the target platform. It is essential to keep in mind that enabling experimental features can increase the risk of errors and may affect the application's performance. Therefore, it is recommended to use experimental features cautiously, preferably only in a testing environment, and with a thorough understanding of the potential risks involved.\n--[no]isobfuscated [action]\nWhether to detect if the target assembly is already obfuscated.\nAdmitted actions are:"},{"page":9,"heading":"Miscellaneous","anchor":"miscellaneous","text":"warn: raise a warning and continue processing the target assembly.\nexit: exit without processing the target assembly\nThis option can be useful in a build scenario where there is the possibility that the target assembly is processed a second time. Babel parses the symbol names to see if the assembly has already been obfuscated. However, there are some cases where the analysis could give an incorrect result. In this situation, it is better to tag the assembly with the BabelObfuscator attribute using the tagassembly option of the --use command line switch."},{"page":9,"heading":"Input Files","anchor":"input-files","text":"The Input Files section includes options that provide external files to Babel Obfuscator containing additional configurations or data necessary to perform some specific operation.\n--keyfile <file>\nSet the strong name file to re-sign the obfuscated assembly and localized resource DLLs. Babel Obfuscator supports Strong Name Key (.snk) and Personal Information Exchange (.pfx).\nInfo: If a Personal Information Exchange file is used, add the command line option --keypwd to specify the .pfx file password.\n--keyname <container>\nUse this option to re-sign the application if the key pair is stored in a key container. The mandatory <_container>_ parameter represents the key container name used to re-sign the obfuscated assembly and localized resources DLLs.\n--keypwd <password>\nSpecifies the password requested by a Personal Information Exchange (.pfx) file to re-sign the obfuscated assembly. When the password is not specified from the command line, Babel will require the user to enter the proper password during the obfuscation process.\n--rules <file>\nSet an XML rule file used by Babel to configure the obfuscation process. This option can be specified multiple times. Rule files will be processed in the order they are entered on the command line.\nbabel myapp.exe --rules ruleset1.xml --rules ruleset2.xml\n--mapin <file>\nSet the input XML obfuscation map file that will be used to obfuscate the names of referenced symbols. This option can be specified multiple times."},{"page":9,"heading":"Input Files","anchor":"input-files","text":"babel myapp.exe --mapin library.map.xml --mapin utils.map.xml\n--project <file>\nSpecify an obfuscation project file.\n--stacktrace <file|key=value>\nDeobfuscate stack trace file. This option requires passing a text <file> containing the obfuscated stack trace and a set of XML mapping files to deobfuscate the stack trace content.\nbabel --stacktrace obfuscatedstacktrace.txt --mapin myapp.map.xml --mapin library.map.xml\nThe option can be repeated to pass, besides the stack trace file, the following key=value settings:\nSetting | Values | Description\nmode | full (default), compact | Selects the verbosity of the decoded frames.\nframes | all (default), user | all keeps every frame; user drops the frames Babel generated — Dynamic Proxy bridges and the anonymous run-time frames they call through — leaving only your source call chain.\nFor example, to decode a trace keeping only the user call chain:\nbabel --stacktrace obfuscatedstacktrace.txt --stacktrace frames=user --mapin myapp.map.xml"},{"page":9,"heading":"Output Files","anchor":"output-files","text":"Babel Obfuscator options to set output filenames.\n--output <file>\nSet the output file path for the obfuscated target. If this option is not provided, the obfuscated target will be saved into the BabelOut subdirectory of the original assembly folder.\n--pdb <file>\nSet the output PDB file path. This option can be used when the --debug option is enabled.\n--pdbpwd <password>\nSet debug information file password. The password will encrypt the source code file names stored inside the PDB.\n--logfile <file>\nSend the Babel Obfuscator output messages to a log file.\n--mapout [file]\nSet the output file name for the XML obfuscation map. If the optional parameter [file] is not provided, Babel Obfuscator will name the XML map file as the original assembly name, adding the extension .map.xml.\n--makeproject [file]\nCreates an MSBuild project file from the entered command line. If the optional parameter [file] is not provided, Babel Obfuscator will save the project file into the BabelOut subdirectory."},{"page":9,"heading":"Plugins","anchor":"plugins","text":"Plugins are additional components that extend the functionality of Babel Obfuscator. They allow for adding or modifying obfuscation features, enabling greater customization and control over the obfuscation process. (see Encrypt Plugin)\n--plugin <file>\nSet Babel Obfuscator plugin file path. This option may be specified multiple times.\n--argument <key=value>\nSet plugin argument as key-value pair. This option may be specified multiple times."},{"page":9,"heading":"Merge and Embed Assemblies","anchor":"merge-and-embed-assemblies","text":"Assembly merging involves combining multiple assemblies into a single primary assembly. Babel Obfuscator performs this operation by merging and obfuscating all the assemblies specified after the primary assembly in the command line.\n--[no]copyattrs [regex]\nWhen this option is enabled, all the assembly-level attributes of each input assembly are copied into the target assembly. An optional regular expression can be specified to merge duplicate attributes that match the given regular expression.\n--embed <assembly>\nBabel Obfuscator can embed multiple dependency assemblies into the target assembly. The embedded assemblies are compressed and encrypted. Embedding can simplify the deployment and reduce the size of the software. It can be used instead of merging when there is no need to fully obfuscate the dependency assembly.\nThis option can be specified multiple times.\nbabel myapp.exe --embed Library1.dll --embed Library2.dll\n--[no]internalize\nWhen enabled, all public types in merged assemblies will have their visibility restricted to internal (Friend VB).\n--[no]jsonmanifest\nEnable ([no]disable) handling of dependencies manifest (default: enabled). Babel Obfuscator can update .deps.json manifest file of the target assembly when merging dependencies."},{"page":9,"heading":"Renaming","anchor":"renaming","text":"These commands can be used to configure symbol renaming.\n--[no]types (t)\nWhether to enable types renaming.\n--[no]events (e)\nWhether to enable events renaming.\n--[no]methods (m)\nWhether to enable methods renaming.\n--[no]parameters (r)\nWhether to enable the method's parameters renaming.\n--[no]properties (p)\nWhether to enable properties renaming.\n--[no]fields (f)\nWhether to enable field symbols renaming.\n--[no]xaml [key=value]\nIf enabled, symbols used in XAML or BAML resources are renamed. This option can accept optional key-value pairs specified as <key>=<value>.\nAccepted key values are:\nkeys=[on/off]      Whether to enable renaming of dictionary keys\nres=[on/off]       Whether to enable renaming of BAML/XAML resources\nstrip=[on/off]     Whether to strip line information or white spaces\nmanual=[on/off]    Whether to use manual symbol renaming\n--[no]virtual [key=value]\nWhether to rename virtual members such as methods, properties, and events. This option can accept optional key-value pairs specified as <key>=<value>.\nAccepted key values are:\nexternal=[on/off]    Whether to obfuscate external virtual calls\n--[no]overloaded [key=value]\nWhen enabled, Babel Obfuscator uses the same name for two or more methods of the same type whenever CLR rules permit. Key-value pairs can optionally be entered to select which overloading to apply.\nAccepted key values are:"},{"page":9,"heading":"Renaming","anchor":"renaming","text":"methods=[on/off]     Whether to overload methods\nproperties=[on/off]  Whether to overload methods\nparameters=[on/off]  Whether to overload parameters\n--[no]flatns (n)\nWhen enabled, all renamed types are moved into the global namespace. This flattens the namespace hierarchy and no namespace information is embedded into the obfuscated assembly.\n--[no]unicode [char set]\nIf enabled, the names are replaced with unreadable Unicode strings. With Unicode normalization disabled, all the obfuscated names are made by strings of lowercase characters taken from the Latin alphabet. Optionally the user can specify the character set used to generate obfuscated names.\nbabel myapp.exe --unicode 0xf000-0xfe00 \nbabel myapp.exe --unicode 10,13,a-z\n--namelength <n>\nSet the minimum name length of renamed symbols. Optionally key-value pairs can be entered to fix the minimum length of types, methods, properties, fields and events separately.\nbabel myapp.exe --namelength types=12 --namelength methods=3\n--nameprefix [prefix]\nSet the name prefix of renamed symbols. Optionally key-value pairs can be entered to set the prefix of types, methods, properties, fields, events and parameters separately.\nbabel myapp.exe --nameprefix types=$Name_ --nameprefix methods=M_\nInfo: The special value $Name is replaced with the original symbol name. Typically the $Name prefix can be used to debug renaming issues.\n--[no]xmldoc [file|regex]"},{"page":9,"heading":"Renaming","anchor":"renaming","text":"Whether to update the target assembly XML documentation by filtering out all renamed symbols. Optionally the XML document file path or a regular expression can be specified. If the file name or the regular expression matches the XML documentation file name of a merged assembly. In that case, the XML document of the merged assembly will be merged into the XML document of the target assembly."},{"page":9,"heading":"Control Flow Obfuscation","anchor":"control-flow-obfuscation","text":"Control flow obfuscation involves transforming the code of a method, thereby obscuring its execution path and making the resulting flow much more complex and difficult to comprehend.\n--[no]controlflow\nUsed to alter the method control flow. Key-value pair <key>=<value> can optionally be entered to configure code scrambling.\nAccepted key values to produce verifiable IL code:\ngoto=[on/off]    Whether to insert irrelevant branches\nswitch=[on/off]  Whether to enable switch scrambling\ncase=[on/off]    Whether to hide case constants\nif=[on/off]      Whether to enable if scrambling\ncall=[on/off]    Whether to enable random calls\nvalue=[on/off]   Whether to use value encryption\ntoken=[on/off]   Whether to enable emission of method tokens\nchain=[on/off]   Whether to enable chained-state flattening (Ultimate)\nTo produce unverifiable IL code:\nunderflow=[on/off]  Whether to enable stack underflow\nThis option can be specified multiple times, for example:\nbabel myapp.exe --controlflow if=on --controlflow switch=on --controlflow case=on\n--controlflow call=on\n--iterations <n>\nSet the number of iterations used in the control flow obfuscation algorithm. Setting the number of iterations to 0 will disable control flow obfuscation. As n increases, an increasing number of irrelevant branch instructions are inserted in each method.\n--[no]invalidopcodes [mode]\nUse this option to emit invalid MSIL op-codes. This will stop some reflection tools from inspecting the IL method body."},{"page":9,"heading":"Control Flow Obfuscation","anchor":"control-flow-obfuscation","text":"Warning: Activating this option will result in the obfuscated assembly being non-verifiable by Intermediate Language (IL) verifiers. It is important to note that code that is not IL verifiable cannot run on x64 operating systems and, therefore, this option should not be enabled if the obfuscated assembly targets x64 platforms.\nThe optional parameter [mode] enables different invalid opcodes configurations:\nenhanced: Insert additional invalid op-codes"},{"page":9,"heading":"Encryption and Protection","anchor":"encryption-and-protection","text":"Options targeting advanced obfuscation features like string and code encryption.\n--[no]msilencryption [regex]\nWhether to enable Code Encryption for methods matching the optional regular expression or obfuscation rules defined in XML rules files. This option can be specified multiple times.\n--[no]stringencryption [name]\nWhether to enable encryption of user strings. An optional parameter name can be specified to select the encryption algorithm used.\nAccepted algorithm names are:\nhash     The strings are arranged into a hash table\nxor      Inline XOR encoded strings\nstream   Authenticated per-string encryption, decrypted lazily; fully managed (AOT/trim/FIPS safe)\n--[no]valueencryption [key=value]\nThis option enables the encryption of inline constant values and arrays. Key-value pair <key>=<value> can optionally be entered to enable or disable the encryption of some defined types.\nAccepted key values are:\nint32=[on/off]\t   Whether to encrypt Int32 values\nint64=[on/off]\t   Whether to encrypt Int64 values\nsingle=[on/off]\t   Whether to encrypt Single values\ndouble=[on/off]\t   Whether to encrypt Double values\narray=[on/off]\t   Whether to encrypt Arrays\n--[no]ildasm\nWhen enabled, the System.Runtime.CompilerServices.SuppressIldasmAttribute is added to the target assembly to prevent the Microsoft MSIL Disassembler: ILDASM (Ildasm.exe) from disassembling the obfuscated target.\n--[no]reflection\nWhether to enable the emission of invalid metadata to stop reflection-based tools."},{"page":9,"heading":"Encryption and Protection","anchor":"encryption-and-protection","text":"--[no]resourceencryption [key=value]\nWhether to enable managed resource encryption. When enabled, all the embedded resources are compressed and encrypted. Key value pairs can be optionally entered to specify additional settings.\nAccepted key values are:\nencrypt=[on/off]   Whether to encrypt resources\ncompress=[on/off]  Whether to compress resources\nprotect=[on/off]   Whether to protect embedded resources\n--[no]proxy [type][;regex]\nWhether to enable the generation of proxy calls to external/internal methods. The optional parameter [type] can have one of the following values:\nexternal     hide calls to external assembly methods\ninternal     hide calls to internally defined assembly methods\nall\t     hide both internal and external method calls\nOptionally the user can enter a regular expression to match the method signature that should be proxied, for example:\nbabel.exe myapp.exe --proxy external --proxy ;System.Array::.* --proxy ;::GetEnumerator\n--[no]tamperingdetection\nWhether to enable anti-tampering protection.\n--[no]antidebugging\nWhether to enable anti-debugging protection."},{"page":9,"heading":"Code Generation","anchor":"code-generation","text":"These options concern some code optimizations that Babel Obfuscator can add to the target assembly.\n--addreference <assembly>\nAdd or retarget an assembly reference to the target assembly. Example:\nbabel myapp.exe --addreference \"[System*, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]\"\nRetargets all System references to portable assemblies. This option can be specified multiple times.\n--[no]cleanattrs <regex>\nWhether to enable the removal of unwanted attributes. The <regex> parameter is a regular expression that matches the unwanted attribute type's full name. This option can be specified multiple times.\n--[no]constremoval\nWhether to enable the removal of constant fields. Any reference to a constant field will be replaced by its constant value whenever possible.\n--[no]deadcode [regex]\nWhether to enable Dead Code Removal. When enabled, removes all methods, properties, fields and events that are not reached by any coding pattern. An optional entry point can be specified through [regex] to define where to start the search.\n--[no]debug [source]\nWhether to enable the emit of the debugging information and generate a PDB debug symbol file for the obfuscated target. A debug symbol store can optionally be specified.\n--debug srv*c:\\Symbols*http://msdl.microsoft.com/download/symbols\n--[no]disgregateremoval\nWhether to enable the removal of property and event metadata information, leaving only properties and events accessor methods.\n--[no]enumremoval"},{"page":9,"heading":"Code Generation","anchor":"code-generation","text":"Whether to enable the removal System.Enum types. Any reference to an enum field will be replaced with its constant value whenever possible.\n--[no]inlineexpansion\nInline code expansion will allow a method call to be replaced by its own code at the point where the call is made.\n--[no]instrument [regex]\nWhether to enable, code instrumentation. An optional regular expression can be specified to target the fully qualified members that should be instrumented.\nFully qualified members have the following syntax\n[NamespaceName].[TypeName]::[MethodName]\nExample:\nbabel myapp.exe --instrument mynamespace\\.mytype::.*\nThis option can be entered multiple times.\n--[no]emptymethods\nWhether to add instrumentation code to methods with an empty body.\n--moduleinitializer [method]\nAdd module initializer code. Optionally a static method signature with no parameters can be specified, which will be called after the module loads.\n[Obfuscation(Feature = \"module initializer:priority=120\")]\npublic static void DoInitialize120()\n{\n   Console.WriteLine(\"DoInitialize120\");\n}\nWhere priority can get an integer value which defines the order that babel will call initializer methods. Babel adds its initializer methods with a default priority set to 100. Initializers with a priority of less than 100 will be called first.\n--[no]seal"},{"page":9,"heading":"Code Generation","anchor":"code-generation","text":"When enabled seal all non-public classes that are not used as base classes in an inheritance hierarchy. Declaring a class as sealed can improve method call performance by preventing the Just-In-Time (JIT) compiler from walking the method's virtual table, where possible."},{"page":10,"heading":"","anchor":"","text":"Starting with Babel Obfuscator 11.7.0, the command line tool can emit a\nstructured, machine-readable output stream that is well suited to CI pipelines,\nbuild orchestrators and AI/agent integrations.\nThe default text output of babel.exe is unchanged and remains fully backward\ncompatible: existing CI scripts and customer integrations require no changes.\nThe AI-friendly mode is enabled by three new global flags:\n--format=text|json|ndjson — selects the output channel format\n--quiet (alias -q) — suppresses the logo banner and fails fast on interactive prompts\n--strict-exit — opts into semantic exit codes\nWhen --format=json or --format=ndjson is selected, stdout carries the\nstructured stream and human-readable diagnostics are routed to stderr so the\ntwo channels never interleave."},{"page":10,"heading":"Flags","anchor":"flags","text":"--format <format>\nSelects the output format used on stdout. Allowed values:\nValue | Description\ntext | Default. Legacy human-readable console output. No structural changes from previous releases.\njson | Buffered single JSON envelope written when the run completes (or on --help / --version). Best when stdout is captured to a file or piped into a JSON consumer.\nndjson | Newline-delimited JSON. One event per line, flushed as it is produced. Best for streaming consumers, log shippers and live agents that need to react before the run terminates.\nExamples:\nbabel myapp.exe --format=json > result.json\nbabel myapp.exe --format=ndjson | jq -c 'select(.level==\"error\")'\nInfo: With --format=json or --format=ndjson the logo banner\nis automatically suppressed regardless of --logo, so that the very\nfirst byte on stdout is valid JSON.\n--quiet (-q)\nSuppresses the copyright/logo banner and changes the behavior of interactive\npassword prompts: instead of blocking on Console.In, Babel fails fast with\nan explicit error. This makes --quiet safe for unattended invocations from\nCI runners, container build steps and AI agents.\nbabel myapp.exe --quiet --keyfile mykey.pfx --keypwd env:KEY_PWD\n--quiet is independent from --format: it can be combined with the legacy\ntext output to keep human-readable logs without the banner.\n--strict-exit\nOpts the process into semantic exit codes. Without this flag, Babel preserves\nthe legacy contract where 0 means success and 1 means any failure."},{"page":10,"heading":"Flags","anchor":"flags","text":"Exit code | Constant | Meaning\n0 | success | Run completed without errors.\n10 | invalidArguments | Command line could not be parsed or contained an invalid value (e.g. unknown --format).\n20 | inputNotFound | The primary assembly or another required input file was not found.\n30 | obfuscationFailure | Obfuscation failed at runtime (any unclassified obfuscator exception).\n40 | licensingFailure | Licensing check failed (missing, expired or unauthorized license).\n50 | keyOrSigningFailure | Strong-name signing or cryptographic key operation failed.\nThe classification is also surfaced as exitReason in the JSON/NDJSON result\nrecord (see Result envelope), even when --strict-exit is\nnot active, so consumers can distinguish failure categories independently from\nthe numeric exit code.\nbabel myapp.exe --strict-exit --format=json\necho \"exit=$?\""},{"page":10,"heading":"Schema: babel.cli.v1","anchor":"schema-babelcliv1","text":"All structured payloads conform to the versioned babel.cli.v1 schema.\nWithin a major schema version, additive changes (new fields, new event codes,\nnew exit reasons) are allowed; breaking changes will bump the schema name.\nEvent record\nEvery diagnostic emitted while a run is in progress is mapped to an event:\n{\n  \"ts\":      \"2026-05-08T14:32:11.482Z\",\n  \"level\":   \"info\",\n  \"code\":    \"BAB1234\",\n  \"message\": \"Renaming phase, elapsed time 00.082s\",\n  \"data\":    { \"phase\": \"renaming\", \"elapsedMs\": 82 }\n}\nField | Type | Notes\nts | string (ISO-8601, UTC) | Timestamp at which the event was produced.\nlevel | debug | info | warning | error | Severity.\ncode | string | null | Babel diagnostic code (e.g. BAB1234, W00013) when applicable.\nmessage | string | Human-readable message.\ndata | object | null | Optional structured payload attached to the event.\nResult envelope\n--format=json\nA single JSON object is written to stdout when the run terminates. It contains\nthe run-level summary and all events buffered during the run:"},{"page":10,"heading":"Schema: babel.cli.v1","anchor":"schema-babelcliv1","text":"{\n  \"exitCode\":   0,\n  \"exitReason\": \"success\",\n  \"elapsedMs\":  4218,\n  \"warnings\":   1,\n  \"errors\":     0,\n  \"events\": [\n    { \"ts\": \"2026-05-08T14:32:09.500Z\", \"level\": \"info\",    \"code\": null,      \"message\": \"Babel Obfuscator 11.7.0.0\", \"data\": null },\n    { \"ts\": \"2026-05-08T14:32:11.482Z\", \"level\": \"info\",    \"code\": \"BAB1234\", \"message\": \"Renaming phase ...\",       \"data\": { \"phase\": \"renaming\" } },\n    { \"ts\": \"2026-05-08T14:32:13.012Z\", \"level\": \"warning\", \"code\": \"W00013\",  \"message\": \"Could not resolve ...\",     \"data\": null }\n  ]\n}\n--format=ndjson\nEach event is flushed as soon as it is produced, on its own line. After the\nlast event, a final result line is appended (without an events array, since\nevents have already been streamed):\n{\"ts\":\"2026-05-08T14:32:09.500Z\",\"level\":\"info\",\"code\":null,\"message\":\"Babel Obfuscator 11.7.0.0\",\"data\":null}\n{\"ts\":\"2026-05-08T14:32:11.482Z\",\"level\":\"info\",\"code\":\"BAB1234\",\"message\":\"Renaming phase ...\",\"data\":{\"phase\":\"renaming\"}}\n{\"ts\":\"2026-05-08T14:32:13.012Z\",\"level\":\"warning\",\"code\":\"W00013\",\"message\":\"Could not resolve ...\",\"data\":null}\n{\"exitCode\":0,\"exitReason\":\"success\",\"elapsedMs\":4218,\"warnings\":1,\"errors\":0}"},{"page":10,"heading":"Schema: babel.cli.v1","anchor":"schema-babelcliv1","text":"Field | Type | Notes\nexitCode | integer | Numeric exit code actually returned by the process (legacy or strict, depending on --strict-exit).\nexitReason | string | Stable classification token. Always reflects the semantic class even without --strict-exit.\nelapsedMs | integer | Total wall-clock duration in milliseconds.\nwarnings | integer | Count of warning-level events.\nerrors | integer | Count of error-level events.\nevents | array | null | Present in json mode; omitted in ndjson (events are streamed as separate lines)."},{"page":10,"heading":"Machine-readable --help","anchor":"machine-readable---help","text":"babel --help --format=json emits a complete description of every public\noption, suitable for tooling that needs to introspect the CLI surface (shell\ncompletions, AI agents, doc generators):\n{\n  \"version\": \"11.7.0.0\",\n  \"usage\":   \"babel.exe <primary assembly source> [<other assemblies>...] [options]\",\n  \"options\": [\n    {\n      \"name\":        \"controlflow\",\n      \"aliases\":     [\"nocontrolflow\", \"no-controlflow\", \"control-flow\", \"no-control-flow\", \"i\"],\n      \"description\": \"Enable ([no]disable) MSIL control flow obfuscation\",\n      \"args\":        null,\n      \"argRequired\": false,\n      \"argOptional\": false,\n      \"negatable\":   true,\n      \"incremental\": false,\n      \"container\":   \"scalar\",\n      \"type\":        \"boolean\",\n      \"group\":       \"- Code Obfuscation -\",\n      \"details\":     \"Use this option to alter the method control flow ...\"\n    }\n  ]\n}\nA scoped form is also supported. babel --help controlflow --format=json emits\nthe same envelope but containing only the controlflow option (and its\ndetails resolved from the option resource bundle).\nHidden/internal options are never returned."},{"page":10,"heading":"Machine-readable --version","anchor":"machine-readable---version","text":"babel --version --format=json emits runtime and platform information:\n{\n  \"product\":     \"Babel Obfuscator\",\n  \"version\":     \"11.7.0.0\",\n  \"fileVersion\": \"11.7.0.0\",\n  \"runtime\":     \".NET 8.0.11\",\n  \"platform\":    \"win-x64\"\n}\nThe platform field uses the .NET RuntimeIdentifier (RID) when running on\n.NET 5+, and a synthetic <os>-<arch> string on legacy targets (net472-x64,\nunix-x64, ...)."},{"page":10,"heading":"Backward compatibility","anchor":"backward-compatibility","text":"The default value of --format is text; the legacy textual output, exit\ncodes and behavior are unchanged when no new flag is specified.\nWithout --strict-exit, the process keeps returning 0 on success and 1\non any failure — existing CI gates that branch on $? keep working.\n--quiet is independent and can be opted into without enabling structured\noutput.\nInfo: The structured output is also available through the MSBuild Task\nand the Babel.Obfuscator NuGet Package by passing the same\nflags via the standard property/argument plumbing."},{"page":11,"heading":"","anchor":"","text":"Babel Obfuscator can be easily integrated with MSBuild to deploy obfuscation in your build process.\nThe Babel MSBuild task is available with any Babel Obfuscator license edition, and can be added to any MSBuild project by inserting the appropriate UsingTask element into the MSBuild project XML file:\n<UsingTask TaskName=\"Babel\" AssemblyName=\"Babel.Build, Version=10.0.0.0, Culture=neutral, PublicKeyToken=138d17b5bd621ab7\" />\nThe AssemblyName attribute refers to the fully qualified name of the .NET component Babel.Build.dll installed into the Global Assembly Cache.\nThe AssemblyName Version property should be set to the currently installed product version. For example, if you > have installed version x.y.z.w:\nVersion=x.y.z.0\nThe revision number w should always be set to 0.\nIn case you do not want to use the fully qualified assembly name, it is possible to reference the Babel.Build.dll component using the full path as follows:\n<UsingTask TaskName=\"Babel\" AssemblyFile=\"<Full path to Babel.Build.dll>\" />\nOnce the assembly Babel.Build has been referenced, it is now possible to use the Babel task to start Babel Obfuscator on a given target assembly:\n<Target Name=\"AfterBuild\">\n  <Babel InputFile=\"$(TargetPath)\" OutputFile=\"$(TargetPath)\" />\n</Target>\nThe Babel task defined above will be executed after the build to obfuscate the target assembly, replacing it with the obfuscated one processed by Babel."},{"page":11,"heading":"","anchor":"","text":"The \"AfterBuild\" target is a well known MSBuild target defined in the build pipeline and it is typically used to add tasks that will be performed once the build has completed and all the binaries are stored in the build output folder defined by $(TargetPath) MSBuild variable.\nFor instance, the Babel task mentioned earlier will run after the build to obfuscate the target assembly stored in the $(TargetPath) variable, replacing it with the obfuscated version processed by Babel."},{"page":11,"heading":"AfterBuild and Compile Targets","anchor":"afterbuild-and-compile-targets","text":"In more recent .NET SDKs, some additional optimization tasks have been introduced that occur before the “AfterBuild” task and after the compilation step, which is carried out during the “Compile” task. The “Compile” task is distinct from “AfterBuild,” which serves merely as a placeholder in the build pipeline, meant to be overridden by external build processes. The “Compile” task is the actual step where compilation occurs, and it cannot be replaced by user-defined tasks.\nBecause obfuscation needs to be performed after the “Compile” task and before any subsequent optimizations made by the build system, you should integrate the Babel obfuscation task immediately following the “Compile” step. This can be done using the MSBuild target attribute AfterTargets as shown below:\n<Target Name=\"Obfuscate\" AfterTargets=\"Compile\">\n  <Babel InputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" \n         OutputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" />\n</Target>\nThis setup ensures that the obfuscation process is applied to the compiled output before any further build optimizations are executed.\nIt’s important to note that the InputFile and OutputFile properties are not set to TargetPath because, at this stage of the build process, the compiled assembly has not yet been copied to the TargetPath location. Instead, it is stored in an intermediate build folder $(IntermediateOutputPath), which serves as the source for all subsequent build steps."},{"page":11,"heading":"AfterBuild and Compile Targets","anchor":"afterbuild-and-compile-targets","text":"This intermediate folder contains the assembly and other artifacts produced during the compilation phase, allowing various tasks, including obfuscation, to be performed on the compiled output before the final build is completed. By specifying the intermediate path, we ensure that the obfuscation process is applied to the correct version of the assembly, as it exists before any copying or additional processing steps that might alter the build output.\nThis approach not only streamlines the build process but also ensures that the obfuscated output is correctly generated and prepared for any further optimization tasks or deployment steps."},{"page":11,"heading":"Configuring Babel Task","anchor":"configuring-babel-task","text":"The Babel task provides a variety of properties that can be configured to customize the obfuscation process according to your specific needs. A comprehensive list of these properties is available in the Babel Task Reference section of the documentation. By default, the Babel task only enables symbol renaming, which alters the names of classes, methods, and other symbols in the code to make it more difficult to reverse engineer.\nTo access more advanced obfuscation features, such as control flow obfuscation, string encryption, and other sophisticated techniques, a valid license is required. Without a valid license, the Babel task operates in demo mode, which is limited to symbol renaming. Additionally, assemblies obfuscated in demo mode are designed to stop functioning after a specific date, as indicated in the build log by the warning code W00000. For example:\nWarning [W00000]: This is an evaluation version, the obfuscated assembly will no longer work after 15/08/2024 17:16:27\nObtaining and applying a valid license unlocks the full range of Babel’s obfuscation capabilities and removes any limitations, allowing the obfuscated assemblies to run without expiration."},{"page":11,"heading":"Configuring Babel Task","anchor":"configuring-babel-task","text":"<Target Name=\"Obfuscate\" AfterTargets=\"Compile\">\n  <Babel InputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" \n         OutputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" \n         ControlFlowObfuscation=\"goto=on;if=on;switch=on;case=on;call=on;true\"\n         ControlFlowIterations=\"3\" StringEncryption=\"hash\" \n         ResourceEncryption=\"true\" />\n</Target>\nThis ensures that your application benefits from comprehensive protection features, safeguarding your intellectual property and source code from unauthorized access or tampering."},{"page":11,"heading":"Build Performance in Visual Studio with Code Analyzers","anchor":"build-performance-in-visual-studio-with-code-analyzers","text":"In Visual Studio, code analyzers are tightly integrated into the development workflow. These analyzers continuously run in the background to provide real-time feedback in the Visual Studio editor, which enhances your coding experience by highlighting potential issues as you type. However, this feature comes with a trade-off: it triggers the build process at every iteration, which can cause performance bottlenecks, especially if tasks like Babel obfuscation are part of the build.\nTo prevent unnecessary performance overhead, you can modify your MSBuild configuration to ensure the Babel obfuscation task runs only during the full build process (i.e., when you’re actually building the solution) and not during the background design-time builds used by the analyzers. Here’s how you can do it:\n<Target Name=\"Obfuscate\" AfterTargets=\"Compile\" \n        Condition=\"'$(DesignTimeBuild)' != 'true'\">\n    <Babel … />\n</Target>\nBy adding the Condition=\"'$(DesignTimeBuild)' != 'true'\", you ensure that the Obfuscate target is skipped during the design-time builds (the background processes that code analyzers use). This change will significantly reduce the amount of CPU time consumed during regular coding sessions without affecting your final build process. The obfuscation will still run when needed—during the actual project build."},{"page":11,"heading":"Babel Task And Babel Obfuscator NuGet Package","anchor":"babel-task-and-babel-obfuscator-nuget-package","text":"The Babel Obfuscator NuGet package available with the Ultimate edition simplifies the integration of the Babel task within the build pipeline. Once the package is referenced in a .NET project, it automatically integrates the Babel task at the appropriate point in the build process without requiring manual configuration. This means that developers do not need to explicitly add the Using directive for the Babel task or manually insert the Babel task into the build script.\nThe package intelligently determines the correct placement of the Babel task based on the project type and the .NET SDK version being used. This automation ensures that the obfuscation process occurs at the optimal stage in the build pipeline, accommodating various build configurations and requirements specific to different project types. This streamlined integration minimizes the potential for errors and makes it easier for developers to apply obfuscation without in-depth knowledge of the build pipeline’s intricacies.\nKey benefits of using Babel Obfuscator NuGet package\n1. Automatic Handling: The Babel Obfuscator NuGet package is designed to intelligently manage obfuscation during the build process, ensuring that it runs only during full builds and is skipped during design-time builds used by analyzers."},{"page":11,"heading":"Babel Task And Babel Obfuscator NuGet Package","anchor":"babel-task-and-babel-obfuscator-nuget-package","text":"2. Reduced CPU Load: By automatically skipping the obfuscation step during background builds, the package helps maintain system performance, reducing unnecessary CPU load and allowing Visual Studio to run more smoothly during development.\n3. Simplified Configuration: You don’t need to manually modify your MSBuild scripts. The package integrates seamlessly with your project and handles everything in the background, saving time and reducing complexity.\n4. Consistent Results: The obfuscation process is consistently applied only during the final build stages, ensuring that your code is protected without interfering with the day-to-day development process.\nAdditionally, the Babel Obfuscator NuGet package maintain consistency across projects, ensuring that all necessary steps for obfuscation are correctly implemented regardless of the project’s complexity or the team’s familiarity with the process. This feature is particularly beneficial in larger projects or teams where maintaining uniform build processes can be challenging."},{"page":12,"heading":"","anchor":"","text":"Every attribute of the Babel MSBuild task, grouped by feature, with the\ncommand line option each attribute maps to.\nThe Babel task exposes one attribute for each option of the command line tool and forwards the attribute values to it unchanged. A Boolean attribute accepts true or false. Where the command line option takes an argument, the same argument can be passed as the attribute value, so an attribute marked Boolean / String accepts either form. List attributes take several values separated by ;. Attributes that are not set keep the defaults listed in the tables.\nWhen the Babel Obfuscator NuGet package is used, each attribute is set through an MSBuild property or item; see the Property Mapping table of the package reference.\nInfo: Version 12.0 adds the SingleFile, TrustedSigner, TrustedBundle and TrustedTeam attributes, which drive the mobile package-integrity checks of Tampering Detection, and the stream value of StringEncryption. They are marked 12.0 in the tables below."},{"page":12,"heading":"Miscellaneous","anchor":"miscellaneous","text":"Attribute | Type | Default | Command line | Description\nBabelDirectory | String |  |  | Legacy override of the folder that contains babel.exe. The task fails when the executable is not found there. Prefer ToolPath.\nDbgHelpDllDir | String |  | --dbghelpdlldir | Path of the folder that contains dbghelp.dll.\nDetectIfObfuscated | Boolean / String | false | --isobfuscated | Whether to detect if the target assembly is already obfuscated. The value warn raises a warning and continues, exit stops without processing the assembly.\nEnableObfuscationAgent | Boolean | true | --agent | Whether to run the obfuscation agent, which analyzes the assembly and excludes from obfuscation the symbols that would break it.\nLicense | String |  | --license | Full path of the license file, or a list of directories to search for license files.\nNoConfiguration | Boolean | false | --noconfig | Whether to ignore the default values stored in the Babel configuration file.\nNoWarnings | String |  | --nowarn | List of warning codes to ignore.\nProvideCommandLineArgs | Boolean | false |  | Whether to log the command line passed to Babel and return it in the CommandLineArgs output item.\nQuickRules | String |  | --quickrule | Quick rule definitions.\nRandomSeed | String |  | --randomseed | Seed of the random number generator used during obfuscation.\nRemoveKey | Boolean | false | --removekey | Whether to remove the strong name from the obfuscated assembly."},{"page":12,"heading":"Miscellaneous","anchor":"miscellaneous","text":"SatelliteAssemblies | String |  | --satellite | List of satellite assembly files to process.\nSearchDirectories | String |  | --addsearch | List of directories where the referenced assemblies are searched. References is accepted as an alias.\nSearchSatelliteAssemblies | Boolean | true | --satellite | Whether to search and process the satellite assemblies of the target.\nShowLogo | Boolean | true | --logo | Whether to output the Babel version and copyright information.\nShowStatistics | Boolean | true | --statistics | Whether to display the obfuscation statistics at the end of the process. Boolean only: use StatisticsFile to save the statistics to a file.\nStatisticsFile | String |  | --statistics | Path of the file where the obfuscation statistics are saved. Ignored when ShowStatistics is false.\nTargetAssemblyName | String | nochange | --assemblyname | Origin of the target assembly name: nochange, inputfilename, outputfilename or name=<assembly name>.\nToolExe | String |  |  | Name of the Babel executable, babel.exe or babel.dll.\nToolPath | String |  |  | Directory of the Babel executable.\nTrace | String |  | --trace | List of regular expressions that select the symbols to trace. The trace shows why a symbol is or is not obfuscated and helps debugging the obfuscation rules.\nUse | Key=Value |  | --use | Usage options as key-value pairs.\nVerboseLevel | Int | 1 | --verbose | Verbosity of the console output. 0 disables the messages, values above 10 show debug information."},{"page":12,"heading":"Miscellaneous","anchor":"miscellaneous","text":"WarningsAsErrors | String |  | --warnaserror | List of warning codes reported as errors. An error stops the obfuscation process.\nWarningsAsInfos | String |  | --warnasinfo | List of warning codes reported as informational messages.\nXmlRules | String |  |  | Inline XML rule elements, see XML Rules."},{"page":12,"heading":"Input Files","anchor":"input-files","text":"Attribute | Type | Default | Command line | Description\nInputFile | String |  |  | Path of the assembly to obfuscate.\nKeyContainer | String |  | --keyname | Name of the strong name key container (Windows only).\nKeyFile | String |  | --keyfile | Path of the strong name key file used to sign the obfuscated assembly.\nKeyPwd | String |  | --keypwd | Password of the strong name key file or certificate.\nMapInFiles | String |  | --mapin | List of XML map files of already obfuscated assemblies, used to rename the references to their symbols.\nProject | String |  | --project | Path of a Babel obfuscation project file.\nRulesFiles | String |  | --rules | List of XML rules files to process."},{"page":12,"heading":"Output Files","anchor":"output-files","text":"Attribute | Type | Default | Command line | Description\nGenerateLogFile | Boolean | false | --logfile | Whether to generate an obfuscation log. The default log file name is <target assembly>.log.\nGenerateMapOutFile | Boolean | false | --mapout | Whether to generate an obfuscation map file. The default map file name is <target assembly>.xml.map.\nLogFile | String |  | --logfile | Path of the obfuscation log file.\nMakeProject | String |  | --makeproject | Path of the MSBuild project file created from the task settings.\nMapOutFile | String |  | --mapout | Path of the obfuscation map file.\nOutputFile | String |  | --output | Path of the obfuscated assembly.\nPdbFile | String |  | --pdb | Path of the debug symbols file.\nPdbPwd | String |  | --pdbpwd | Password of the debug symbols file."},{"page":12,"heading":"Plugins","anchor":"plugins","text":"Attribute | Type | Default | Command line | Description\nPlugins | String |  | --plugin | List of plugin assembly files.\nPluginsArguments | Key=Value |  | --argument | Plugin arguments as key-value pairs."},{"page":12,"heading":"Merge and Embed","anchor":"merge-and-embed","text":"Attribute | Type | Default | Command line | Description\nCopyAttributes | Boolean / String | false | --copyattrs | Whether the assembly level attributes of the merged assemblies are copied into the target assembly. A regular expression selects the duplicate attributes that can be merged.\nDependenciesManifest | Boolean | true | --jsonmanifest | Whether to update the .deps.json dependencies manifest of the target assembly when assemblies are merged or embedded.\nEmbedAssemblies | String |  | --embed | List of assembly files to embed into the target assembly.\nInternalize | Boolean | false | --internalize | Whether the merged types have their visibility restricted to the target assembly.\nMergeAssemblies | String |  |  | List of assembly files to merge into the target assembly."},{"page":12,"heading":"Renaming","anchor":"renaming","text":"Attribute | Type | Default | Command line | Description\nFlattenNamespaces | Boolean / String | true | --flatns | Whether to move the renamed types into the global namespace. A string sets a common namespace name for the renamed types instead.\nNameLength | Int / Key=Value |  | --namelength | Minimum length of the obfuscated names. Key-value pairs assign the length to a given symbol kind.\nNamePrefix | String / Key=Value |  | --nameprefix | Prefix of the obfuscated names, $name or any string. Key-value pairs assign the prefix to a given symbol kind.\nObfuscateEvents | Boolean | true | --events | Whether to rename events.\nObfuscateFields | Boolean | true | --fields | Whether to rename fields.\nObfuscateMethods | Boolean | true | --methods | Whether to rename methods.\nObfuscateParameters | Boolean | true | --parameters | Whether to rename method parameters.\nObfuscateProperties | Boolean | true | --properties | Whether to rename properties.\nObfuscateTypes | Boolean | true | --types | Whether to rename types.\nObfuscateXaml | Boolean / Key=Value | false | --xaml | Whether to rename the symbols referenced by XAML and BAML resources. Key-value pairs configure the renaming.\nOverloadedRenaming | Boolean / Key=Value | false | --overloaded | Whether to reuse the same name for members with different signatures. Key-value pairs select which members are overloaded."},{"page":12,"heading":"Renaming","anchor":"renaming","text":"UnicodeNormalization | Boolean / String | false | --unicode | Whether to generate names using Unicode characters. When disabled, ASCII characters are used. A comma-separated list of characters or ranges restricts the character set.\nVirtualFunctions | Boolean / Key=Value | true | --virtual | Whether to rename virtual members. Key-value pairs configure the renaming of external overrides.\nXmlDocFiles | String |  | --xmldoc | List of XML documentation files to process together with the assembly. XmlDoc is accepted as a legacy alias."},{"page":12,"heading":"Control Flow Obfuscation","anchor":"control-flow-obfuscation","text":"Attribute | Type | Default | Command line | Description\nControlFlowObfuscation | Boolean / Key=Value | false | --controlflow | Whether to obfuscate the control flow of the methods. Key-value pairs select the algorithms, including chain=on for Chained State  (Ultimate).\nControlFlowIterations | Int | 3 | --iterations | Number of iterations of the control flow obfuscation algorithms. 0 disables control flow obfuscation. ILIterations and Iterations are accepted as aliases.\nEmitInvalidOpcodes | Boolean / String | false | --invalidopcodes | Whether to emit invalid MSIL op-codes, which makes the assembly not verifiable. The value enhanced inserts additional invalid op-codes."},{"page":12,"heading":"Encryption and Protection","anchor":"encryption-and-protection","text":"Attribute | Type | Default | Command line | Description\nDebuggingProtection | Boolean | false | --antidebugging | Whether to enable anti-debugging protection.\nDynamicProxy | Boolean / String | false | --proxy | Whether to wrap method calls in dynamically generated proxies. The value selects the calls to proxy: internal, external or all.\nDynamicProxyCallFilters | String |  | --proxy | List of regular expressions that select the method calls to proxy.\nMsilEncryption | Boolean / String | false | --msilencryption | Whether to encrypt the MSIL code of the methods. Regular expressions select the methods to encrypt by signature.\nResourceEncryption | Boolean / Key=Value | false | --resourceencryption | Whether to encrypt the managed resources. Key-value pairs enable encryption and compression separately.\nSingleFile 12.0 | Boolean | false | --singlefile | Signals that the target is published as a single-file, trimmed or NativeAOT application. On desktop targets the tampering detection check is inert for such a publish, and Babel emits a warning when it is requested.\nStringEncryption | Boolean / String | false | --stringencryption | Whether to encrypt the user strings. The value selects the algorithm: xor, hash, or stream 12.0  (Ultimate).\nSuppressIldasm | Boolean | false | --ildasm | Whether to prevent ILDASM from disassembling the obfuscated assembly."},{"page":12,"heading":"Encryption and Protection","anchor":"encryption-and-protection","text":"SuppressReflection | Boolean / Int | false | --reflection | Whether to emit invalid metadata that stops reflection-based tools. An integer sets the level: the higher the level, the more invalid metadata is generated.\nTamperingDetection | Boolean | false | --tamperingdetection | Whether to enable tampering detection.\nTrustedBundle 12.0  (Ultimate) | String |  | --trustedbundle | Trusted iOS bundle identifier (CFBundleIdentifier) pinned by the iOS package-integrity check.\nTrustedSigner 12.0  (Ultimate) | String |  | --trustedsigner | List of SHA-256 fingerprints, 64 hexadecimal characters each, of the trusted Android APK signing certificates pinned by the Android package-integrity check.\nTrustedTeam 12.0  (Ultimate) | String |  | --trustedteam | Trusted Apple Developer Team ID pinned by the iOS package-integrity check.\nValueEncryption | Boolean / Key=Value | false | --valueencryption | Whether to encrypt the constant values and arrays. Key-value pairs select the kinds of value to encrypt."},{"page":12,"heading":"Optimizations","anchor":"optimizations","text":"Attribute | Type | Default | Command line | Description\nCleanAttributes | Boolean / String | false | --cleanattrs | Whether to remove unwanted attributes. Regular expressions select the full names of the attribute types to remove.\nConstRemoval | Boolean | false | --constremoval | Whether to remove the constant fields.\nDeadCodeElimination | Boolean / String | false | --deadcode | Whether to remove the methods, properties and events not used by the application. Regular expressions set the entry points where the search starts.\nDisgregateRemoval | Boolean | false | --disgregateremoval | Whether to remove the property and event metadata.\nEnumRemoval | Boolean | false | --enumremoval | Whether to remove the System.Enum types.\nInlineExpansion | Boolean | false | --inlineexpansion | Whether to replace the calls to the methods marked for inline expansion with the method body.\nSealClasses | Boolean | false | --seal | Whether to seal the classes that are not used in any inheritance chain."},{"page":12,"heading":"Code Generation","anchor":"code-generation","text":"Attribute | Type | Default | Command line | Description\nAddReferences | String |  | --addreference | List of assemblies to add as references of the target assembly.\nFramework | String |  |  | Target framework name forced for the processed assembly.\nGenerateDebug | Boolean / String | false | --debug | Whether to generate the debug symbols of the obfuscated assembly. A symbol store path can be specified as the value.\nInstrument | Boolean / String | false | --instrument | Whether to instrument the code. Regular expressions select the full names of the methods to instrument.\nInstrumentEmptyMethods | Boolean | false | --emptymethods | Whether to instrument the methods with an empty body.\nModuleInitializer | Boolean / String | false | --moduleinitializer | Whether to add module initializer code to the target assembly.\nModuleInitializerTarget | String |  | --moduleinitializer | Signature of the static method, without parameters, called after the module loads.\nModuleVersionId | Boolean / String | false | --moduleversionid | Whether to set the module version identifier (MVID) of the obfuscated assembly. A GUID string sets the value, otherwise a random one is generated."},{"page":12,"heading":"Packages","anchor":"packages","text":"Attribute | Type | Default | Command line | Description\nAndroidSigningKeyAlias | String |  | --keyalias | Alias of the key in the Android key store (APK packages).\nAndroidSigningKeyPass | String |  | --keypass | Password of the key in the Android key store (APK packages).\nAndroidSigningKeyStore | String |  | --keystore | Android key store file (APK packages).\nAndroidSigningStorePass | String |  | --storepass | Password of the Android key store (APK packages).\nRemoveFiles | String |  | --remove | List of deployed assemblies to remove from the package.\nSkipFiles | String |  | --skip | List of deployed assemblies that are not obfuscated.\nTakeFiles | String |  | --take | List of deployed assemblies to obfuscate.\nXapCompressionLevel | Int | 6 | --compress | Compression level of the package, from 0 (no compression) to 9 (XAP packages)."},{"page":12,"heading":"Task Outputs","anchor":"task-outputs","text":"Output | Description\nCommandLineArgs | The command line passed to Babel, available when ProvideCommandLineArgs is true.\nExitCode | The exit code returned by Babel."},{"page":12,"heading":"Example","anchor":"example","text":"The task below obfuscates the intermediate assembly of a .NET MAUI Android project with STREAM string encryption and tampering detection pinned to the APK signing certificate, and captures the command line passed to Babel:\n<Target Name=\"Obfuscate\" AfterTargets=\"Compile\" Condition=\"'$(DesignTimeBuild)' != 'true'\">\n  <Babel InputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\"\n         OutputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\"\n         StringEncryption=\"stream\"\n         ControlFlowObfuscation=\"true\"\n         ControlFlowIterations=\"3\"\n         TamperingDetection=\"true\"\n         TrustedSigner=\"2924C53EE9C511E9F26E0720FD8151064F7621681667D7AB1899E551CDB25104\"\n         ProvideCommandLineArgs=\"true\">\n    <Output TaskParameter=\"CommandLineArgs\" ItemName=\"BabelCommandLineArgs\" />\n  </Babel>\n  <Message Importance=\"high\" Text=\"@(BabelCommandLineArgs, ' ')\" />\n</Target>"},{"page":13,"heading":"","anchor":"","text":"The MSBuild Babel task attributes are defined in the schema file Babel.Build.xsd, shipped next to Babel.Build.dll in the MSBuild folder of the babel_net* zip packages. Registering this schema with your editor gives you completion and inline documentation for the Babel task and its attributes while editing project files, which makes build scripts that use the Babel task easier to write and maintain."},{"page":13,"heading":"Visual Studio","anchor":"visual-studio","text":"Visual Studio keeps its MSBuild schemas in the Xml\\Schemas\\1033 folder under the installation directory.\nFind your schema folder\nVersion | Schema folder\nVisual Studio 2026 | C:\\Program Files\\Microsoft Visual Studio\\18\\<edition>\\Xml\\Schemas\\1033\nVisual Studio 2022 | C:\\Program Files\\Microsoft Visual Studio\\2022\\<edition>\\Xml\\Schemas\\1033\nVisual Studio 2019 | C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\<edition>\\Xml\\Schemas\\1033\nWhere <edition> is Community, Professional or Enterprise. Note that Visual Studio 2026 names its folder after the major version number (18) rather than the year, and that Visual Studio 2019 lives under Program Files (x86). If you installed Visual Studio to a custom location, use the Xml\\Schemas\\1033 folder under that path instead.\nCopy the schema file\nCopy Babel.Build.xsd into the folder that matches your version and edition.\nAdd the Babel include\nOpen Microsoft.Build.xsd in the same folder and add the Babel include right after the existing include of the MSBuild common types:\n<xs:include schemaLocation=\"MSBuild\\Microsoft.Build.CommonTypes.xsd\"/>\n<!-- Import of the Babel Build XSD definition -->\n<xs:include schemaLocation=\"Babel.Build.xsd\"/>\nRestart Visual Studio\nRestart Visual Studio for the change to take effect. Editing files under Program Files requires administrator rights, and a Visual Studio update can replace Microsoft.Build.xsd: if completion for the Babel task stops working after an update, re-apply the include."},{"page":13,"heading":"Other Editors","anchor":"other-editors","text":"Babel.Build.xsd targets the MSBuild namespace (http://schemas.microsoft.com/developer/msbuild/2003) and includes MSBuild\\Microsoft.Build.Core.xsd, so it is designed to sit next to the MSBuild schema set and be pulled in from Microsoft.Build.xsd exactly as shown above. Editors other than Visual Studio do not read the Visual Studio schema folder, but they can be pointed at a schema set you assemble yourself:\nCreate a folder containing Microsoft.Build.xsd and its MSBuild\\ subfolder. Copy them from a Visual Studio installation, or take them from the MSBuild repository. Place Babel.Build.xsd next to Microsoft.Build.xsd and add the include line shown above.\nBecause the schema declares a target namespace, the project file must declare the MSBuild namespace on its root element for the association to apply. MSBuild accepts the namespace on SDK-style projects too:\n<Project Sdk=\"Microsoft.NET.Sdk\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\nVisual Studio Code\nWith the XML extension by Red Hat installed, associate your project files with the schema set in settings.json:\n\"xml.fileAssociations\": [\n  { \"pattern\": \"**/*.csproj\",  \"systemId\": \"C:/Schemas/MSBuild/Microsoft.Build.xsd\" },\n  { \"pattern\": \"**/*.props\",   \"systemId\": \"C:/Schemas/MSBuild/Microsoft.Build.xsd\" },\n  { \"pattern\": \"**/*.targets\", \"systemId\": \"C:/Schemas/MSBuild/Microsoft.Build.xsd\" }\n]\nReplace C:/Schemas/MSBuild/ with the folder created in step 1.\nJetBrains Rider"},{"page":13,"heading":"Other Editors","anchor":"other-editors","text":"Go to Settings | Languages & Frameworks | Schemas and DTDs, click Add to open the Map External Resource dialog, enter http://schemas.microsoft.com/developer/msbuild/2003 as the URI and select your Microsoft.Build.xsd as the location. Rider then validates and completes project files that declare that namespace against the mapped schema, Babel task included."},{"page":14,"heading":"","anchor":"","text":"The Babel Obfuscator NuGet packages let you run Babel on any build machine or\nCI server that has the .NET SDK, on Windows, Linux and macOS, without\ninstalling the product.\nBabel Obfuscator ships two NuGet packages. Both come with the Ultimate edition and with the Babel Licensing site editions (Server and Data Center), and neither is published on nuget.org: you receive them with the product and host them on a private feed or in a local folder, as described in Package Setup.\nPackage | What it provides\nBabel.Obfuscator | Build integration. Referencing the package adds the Babel MSBuild task to the project and runs it at the right point of the build, so dotnet build, dotnet publish and Visual Studio produce obfuscated output. Most of this section is about this package.\nBabel.Obfuscator.Tool | The babel command line packaged as a dotnet tool, for scripted obfuscation outside the build. See Babel Obfuscator Tool."},{"page":14,"heading":"Why the Package Instead of the Babel Task","anchor":"why-the-package-instead-of-the-babel-task","text":"You can always add the Babel task to a project by hand. The package does that for you, and it also solves a problem that is hard to solve by hand in SDK-style projects: the .NET SDK runs several IL-level steps after compilation (dependency resolution, trimming, single-file bundling, ahead-of-time compilation), and obfuscation must happen before all of them. The package inserts the Babel task right after the compiler, on the assembly in the intermediate obj folder, so every later step of the build works on the obfuscated assembly. See Build Pipeline.\nBeyond placement, the package:\nShips the Babel build tools for every supported MSBuild host, that is .NET Framework MSBuild, Mono, and the .NET SDK from 6.0 to 10.0, and picks the right one automatically.\nConfigures the Babel task from what the project already knows: assembly search directories from the project references, the strong-name key, debug symbols, the rules file and the license file.\nSkips design-time builds in Visual Studio and incremental builds where the compiler did not run, keeping the IDE responsive.\nKeeps dotnet publish consistent when assemblies are merged or embedded, by updating the .deps.json file and the set of published files."},{"page":14,"heading":"Requirements","anchor":"requirements","text":"A .NET SDK from 6.0 to 10.0, Visual Studio 2022 or later, or Mono MSBuild. .NET Framework projects built with MSBuild.exe are supported as well.\nA valid license: a babel.licenses file or a license key (see Activating the License). Without a license the package runs in evaluation mode and the obfuscated assemblies stop working after a short period.\nThe package hosted on a NuGet feed your build can reach (see Install)."},{"page":14,"heading":"Quick Start","anchor":"quick-start","text":"Add the package\nAdd the Babel.Obfuscator package to your feed, or to a local folder registered as a package source.\nReference the package\nReference the package from the project to obfuscate:\n<ItemGroup>\n  <PackageReference Include=\"Babel.Obfuscator\" Version=\"12.0.0\">\n    <PrivateAssets>all</PrivateAssets>\n    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n  </PackageReference>\n</ItemGroup>\nProvide the license\nCopy babel.licenses into the solution folder, or set the BabelLicense property.\nConfigure obfuscation\nAdd the obfuscation settings you want as MSBuild properties, for example:\n<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <StringEncryption>stream</StringEncryption>\n  <ControlFlowObfuscation>if=on;switch=on;call=on</ControlFlowObfuscation>\n  <ResourceEncryption>true</ResourceEncryption>\n</PropertyGroup>\nBuild\nBuild. The Babel log appears in the build output and the output assembly is obfuscated.\n\nBabel Obfuscator Visual Studio Output"},{"page":14,"heading":"In This Section","anchor":"in-this-section","text":"Package Setup — hosting the package, adding the reference, activating the license and verifying the first build.\nConfiguring Obfuscation — the MSBuild properties and items that drive every Babel feature, including the settings introduced in version 12.\nBuild Pipeline — where obfuscation runs, how to move it, the targets you can extend, publishing, and how the build tools are selected.\nBabel Obfuscator Tool — the babel command line as a dotnet tool.\nPackage Reference — every property, item and target defined by the package, and the mapping to the Babel task attributes."},{"page":14,"heading":"Examples","anchor":"examples","text":"The following examples in the manual use the Babel Obfuscator NuGet package.\nAndroid Application: Obfuscate a .NET for Android app with the package and custom rules.\nObfuscate .NET MAUI: Protect a MAUI app and choose the right linker mode for iOS.\nPublish .NET App: Cross-assembly renaming and publishing with the BeforeObfuscate target.\nGitHub Actions: Install the package from GitHub Packages and pass the license as a secret.\nUnit Tests: Run unit tests against obfuscated assemblies using map files.\nClickOnce Deploy: Obfuscate a ClickOnce application.\nBlazor Web App: Protect the Razor pages of a Blazor application with rules.\nAzure DevOps: Set up the package on an Azure Pipelines build.\nAppVeyor: Deploy the package on an AppVeyor build."},{"page":15,"heading":"","anchor":"","text":"How to make the Babel.Obfuscator package available to your builds, reference\nit from a project, activate the license and verify the first obfuscated\nbuild."},{"page":15,"heading":"Hosting the Package","anchor":"hosting-the-package","text":"The Babel NuGet packages are not published on nuget.org. Every build that references Babel.Obfuscator must be able to restore it from a feed you control:\nA private feed such as Azure Artifacts, GitHub Packages, GitLab, MyGet or a self-hosted NuGet server. This is the right choice for build servers and teams. The GitHub Actions example shows how to push the package to GitHub Packages and how to authenticate the restore step with a token.\nA local folder registered as a package source, which is enough for a single developer machine.\nBoth options are described step by step in Install. Whichever you choose, keep the feed configuration in a NuGet.config file next to the solution, so that dotnet restore finds the package on every machine, CI agents included:\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n    <add key=\"babel\" value=\"https://nuget.pkg.github.com/YOUR_ORG/index.json\" />\n  </packageSources>\n</configuration>"},{"page":15,"heading":"Adding the Package Reference","anchor":"adding-the-package-reference","text":"From Visual Studio\nRight-click the project in Solution Explorer, choose Manage NuGet Packages…, select the package source that hosts the Babel packages and install Babel.Obfuscator. Visual Studio adds a PackageReference with the correct metadata to the project file.\nFrom the dotnet CLI\ndotnet add package Babel.Obfuscator\nBy editing the project file\nAdd the following item to the .csproj or .vbproj file:\n<ItemGroup>\n  <PackageReference Include=\"Babel.Obfuscator\" Version=\"12.0.0\">\n    <PrivateAssets>all</PrivateAssets>\n    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n  </PackageReference>\n</ItemGroup>\nThe two metadata elements matter:\nPrivateAssets set to all marks the package as a development dependency, so it is not propagated to the projects or packages that reference yours.\nIncludeAssets brings in the build assets, which is where the package's .props and .targets files live. Without build in the list the Babel task is never wired into the project and nothing is obfuscated.\nWarning: If you write the PackageReference by hand, always include the metadata above. Referencing the package without it can add the Babel tools as a reference of your assembly and leave the build unobfuscated.\nSeveral projects in one solution\nTo obfuscate several projects without repeating the reference, put it in a Directory.Build.props file at the root of the repository. A condition keeps test projects and other non-shipping projects out:"},{"page":15,"heading":"Adding the Package Reference","anchor":"adding-the-package-reference","text":"<Project>\n  <ItemGroup Condition=\"!$(MSBuildProjectName.EndsWith('.Tests'))\">\n    <PackageReference Include=\"Babel.Obfuscator\" Version=\"12.0.0\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n</Project>\nIf you use Central Package Management, declare the version once with a PackageVersion item in Directory.Packages.props and drop the Version attribute from the PackageReference."},{"page":15,"heading":"Activating the License","anchor":"activating-the-license","text":"The Babel task needs a valid license every time it runs. The package looks for one in this order:\nThe BabelLicense property, when set in the project.\nA babel.licenses file in the project folder or in any parent folder. Copying the license file next to the solution file is therefore enough for every project in the solution.\nBabelLicense accepts the same values as the --license command line switch: the path of a license file, a license key, or a floating license user key:\n<PropertyGroup>\n  <!-- A license file -->\n  <BabelLicense>$(MSBuildThisFileDirectory)build\\babel.licenses</BabelLicense>\n\n  <!-- or a license key held in an environment variable (a build server secret) -->\n  <BabelLicense>$(BABEL_LICENSE)</BabelLicense>\n\n  <!-- or a floating license user key -->\n  <BabelLicense>floating:P1N1J-EH5VA-VGSFU-7EOK8</BabelLicense>\n</PropertyGroup>\nOn build servers keep the key out of the repository: store it as a secret, expose it to the build step as an environment variable and reference that variable from BabelLicense, as the GitHub Actions example does. Floating licenses are described in Product Activation.\nInfo: A license file is tied to a product version. When you update the package to a new version, install the license file that came with that version. Since version 11.8, a license that is provided explicitly but is not valid for the version being run stops the build with an error instead of silently falling back to evaluation mode.\nEvaluation mode"},{"page":15,"heading":"Activating the License","anchor":"activating-the-license","text":"When no license is found, Babel runs in evaluation mode: only symbol renaming is applied, and the obfuscated assembly stops working after a short period, as reported by warning W00000 in the build log. To make sure such an assembly never leaves the build server, turn that warning into an error:\n<PropertyGroup>\n  <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>\n</PropertyGroup>"},{"page":15,"heading":"Building and Verifying","anchor":"building-and-verifying","text":"Build the project as usual, from Visual Studio, dotnet build or msbuild. The Babel log is written to the build output at the verbosity set by VerboseLevel (1 by default).\ndotnet build -c Release\nBabel Obfuscator Visual Studio Output\nTo see exactly how the package invokes Babel, set BabelProvideCommandLineArgs to true: the full command line is written to the log and stored in the @(BabelCommandLineArgs) item, which is useful to reproduce a build problem with the command line tool. GenerateLogFile writes the complete obfuscation log to a file next to the target assembly, or to the path set by BabelLogFile.\nConfirm that the output is obfuscated by opening the built assembly with a decompiler, or by reading the statistics printed at the end of the Babel log. Babel processes the assembly the compiler writes to the intermediate obj folder, so the copies in bin and in the publish folder are all obfuscated. See Build Pipeline."},{"page":15,"heading":"Disabling Obfuscation for a Configuration","anchor":"disabling-obfuscation-for-a-configuration","text":"Obfuscation is rarely wanted in Debug builds. Set BabelEnabled to false in the Debug configuration and the package skips every Babel step, publish adjustments included:\n<PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\n  <BabelEnabled>false</BabelEnabled>\n</PropertyGroup>\nThe same property can be switched from the command line for a one-off unobfuscated build:\ndotnet build -c Release -p:BabelEnabled=false"},{"page":15,"heading":"Updating the Package","anchor":"updating-the-package","text":"Every Babel release ships a new package version together with a new license file. To update:\nPush the new package\nPush the new Babel.Obfuscator package to your feed.\nBump the version\nBump the Version attribute of the PackageReference, or the PackageVersion entry.\nReplace the license file\nReplace babel.licenses with the file received with the new version.\nKeep Babel.Obfuscator and Babel.Obfuscator.Tool at the same version when you use both."},{"page":16,"heading":"","anchor":"","text":"With the package installed, every Babel Obfuscator feature is configured with\nMSBuild properties and items in the project file. This page shows the\nsettings you will use most, feature by feature."},{"page":16,"heading":"How Settings Reach Babel","anchor":"how-settings-reach-babel","text":"The package defines one MSBuild property or item for each attribute of the Babel task, and passes them to the task when the CoreObfuscate target runs. Most properties have the same name as the task attribute and accept the same values as the corresponding command line switch. The ones that differ, such as BabelLicense, MergeInternalize or BabelRules, are listed in the Property Mapping table.\nSettings go in a PropertyGroup, usually conditioned on the build configuration so that Debug builds stay readable:\n<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <StringEncryption>stream</StringEncryption>\n  <ControlFlowObfuscation>if=on;switch=on;call=on</ControlFlowObfuscation>\n  <ControlFlowIterations>3</ControlFlowIterations>\n  <ValueEncryption>true</ValueEncryption>\n  <ResourceEncryption>true</ResourceEncryption>\n  <DebuggingProtection>true</DebuggingProtection>\n  <VerboseLevel>2</VerboseLevel>\n</PropertyGroup>\nLists of files are expressed as items in an ItemGroup: BabelRules, MergeAssembly, EmbedAssembly, MapInFile and BabelPlugin.\nInfo: Properties are evaluated before any target runs, so a value set in the project body applies to the whole build. To compute a setting from something that is only known while building, such as the resolved path of a package reference, set it inside the BeforeObfuscate target instead. See Overriding the Task Configuration."},{"page":16,"heading":"Defaults Applied by the Package","anchor":"defaults-applied-by-the-package","text":"Without any setting, a project that references the package is obfuscated as follows:\nSymbol renaming is on for types, methods, properties, fields, events and parameters, virtual members included, and namespaces are flattened. The SymbolsRenaming property switches all of these at once; the individual ObfuscateTypes, ObfuscateMethods, ObfuscateProperties, ObfuscateFields, ObfuscateEvents, ObfuscateParameters, VirtualFunctions and FlattenNamespaces properties override it one by one.\nEvery other feature is off until you enable it.\nDebug symbols are regenerated when the compiler produced a PDB next to the assembly (GenerateDebug is set automatically), so obfuscated builds stay debuggable and stack traces can be decoded.\nAssembly search directories are built from the project references, so Babel resolves every dependency the compiler saw.\nThe Babel configuration file is ignored (NoConfiguration is true), so the build depends only on what the project declares.\nA babelRules.xml file in the project folder is picked up automatically.\nThe strong-name key resolved by MSBuild for the project (KeyOriginatorFile, or KeyContainerName) is passed to Babel, so the obfuscated assembly is signed like the original.\nTo turn renaming off, for a test project or for a string-encryption-only pass:\n<PropertyGroup>\n  <SymbolsRenaming>false</SymbolsRenaming>\n</PropertyGroup>"},{"page":16,"heading":"Obfuscation Rules","anchor":"obfuscation-rules","text":"Rules exclude symbols from a feature or apply a feature to a set of symbols. There are three ways to provide them:\nAdd a babelRules.xml file to the project folder: it is used automatically.\nReference any number of rules files with BabelRules items:\n<ItemGroup>\n  <BabelRules Include=\"rules\\renaming.xml\" />\n  <BabelRules Include=\"rules\\encryption.xml\" />\n</ItemGroup>\nWrite the rules inline in the XmlRules property, which is convenient for a small set of rules that belongs to the project:\n<PropertyGroup>\n  <XmlRules>\n    <Rules>\n      <Rule name=\"rename public types\" feature=\"renaming\" exclude=\"false\">\n        <Access>Public</Access>\n        <Pattern>*</Pattern>\n      </Rule>\n    </Rules>\n  </XmlRules>\n</PropertyGroup>\nThe Android Application example uses an inline rule to rename public types, and the Blazor Web App example uses a rules file to obfuscate the classes behind Razor pages. Rules can also be attached to the code with custom attributes."},{"page":16,"heading":"String Encryption","anchor":"string-encryption","text":"StringEncryption enables string encryption and selects the algorithm, exactly like the --stringencryption switch: true uses the default algorithm, while xor, hash, stream or custom selects one. See Standard Algorithms for a comparison.\n<PropertyGroup>\n  <StringEncryption>stream</StringEncryption>\n</PropertyGroup>\nSTREAM (Ultimate) is the algorithm to prefer for modern targets: it is fully managed, so it works with trimming, NativeAOT and on FIPS-constrained hosts, and it is verified from .NET Framework through .NET 10, Android, iOS and .NET MAUI included. On Android, iOS and MAUI projects the package already runs Babel after compilation and before packaging, which is where string encryption has to happen for the packaged app to carry the encrypted strings. Strings declared const cannot be encrypted; see Encryption of Const Strings."},{"page":16,"heading":"Control Flow Obfuscation","anchor":"control-flow-obfuscation","text":"ControlFlowObfuscation takes the same key-value list as --controlflow, and ControlFlowIterations the number of passes (ILIterations is accepted as an alias):\n<PropertyGroup>\n  <ControlFlowObfuscation>goto=on;if=on;switch=on;case=on;call=on</ControlFlowObfuscation>\n  <ControlFlowIterations>3</ControlFlowIterations>\n</PropertyGroup>\nVersion 12 adds the Chained State algorithm (Ultimate) as a flattening transform hardened against automated deobfuscators. Enable it with chain=on, alone or together with the other algorithms:\n<PropertyGroup>\n  <ControlFlowObfuscation>switch=on;case=on;chain=on</ControlFlowObfuscation>\n</PropertyGroup>\nFlattening has a runtime cost. Use rules to keep it off hot methods, as explained in Performance & Tuning."},{"page":16,"heading":"Code Encryption","anchor":"code-encryption","text":"MsilEncryption encrypts method bodies. true encrypts every eligible method, while a regular expression restricts encryption to the methods whose full name matches it:\n<PropertyGroup>\n  <MsilEncryption>MyApp\\.Licensing\\..*</MsilEncryption>\n</PropertyGroup>\nSee Code Encryption for the runtime behaviour, password-protected code and the methods that cannot be encrypted."},{"page":16,"heading":"Value, Resource and Call Protection","anchor":"value-resource-and-call-protection","text":"<PropertyGroup>\n  <ValueEncryption>array=true;true</ValueEncryption>\n  <ResourceEncryption>true</ResourceEncryption>\n  <DynamicProxy>all</DynamicProxy>\n  <SuppressIldasm>true</SuppressIldasm>\n  <SuppressReflection>true</SuppressReflection>\n</PropertyGroup>\nEach property accepts the values of the corresponding switch: see Value and Array Encryption, Resource Encryption and Dynamic Proxy."},{"page":16,"heading":"Tampering Detection and Anti-Debugging","anchor":"tampering-detection-and-anti-debugging","text":"<PropertyGroup>\n  <TamperingDetection>true</TamperingDetection>\n  <DebuggingProtection>true</DebuggingProtection>\n</PropertyGroup>\nOn desktop targets the tampering check hashes the loaded image in memory, so it is inert in single-file, trimmed or AOT-published applications. The package forwards the project's PublishSingleFile setting to Babel, which warns when tampering detection is requested for such a publish. See Tampering Detection and Anti-Debugging.\nAndroid and iOS package integrity (Ultimate)\nStarting with version 12, on .NET for Android and iOS targets (.NET MAUI included) tampering detection verifies the integrity of the package instead of the image: the APK signing certificate on Android, the bundle identifier and the Apple Team ID on iOS. Pin the expected values with the properties added in this version:\n<!-- Android: SHA-256 fingerprint of the release signing certificate -->\n<PropertyGroup Condition=\"$(TargetFramework.Contains('-android'))\">\n  <TamperingDetection>true</TamperingDetection>\n  <TrustedSigner>2924C53EE9C511E9F26E0720FD8151064F7621681667D7AB1899E551CDB25104</TrustedSigner>\n</PropertyGroup>\n\n<!-- iOS: bundle identifier and Apple Team ID -->\n<PropertyGroup Condition=\"$(TargetFramework.Contains('-ios'))\">\n  <TamperingDetection>true</TamperingDetection>\n  <TrustedBundle>com.mycompany.myapp</TrustedBundle>\n  <TrustedTeam>ABCDE12345</TrustedTeam>\n</PropertyGroup>"},{"page":16,"heading":"Tampering Detection and Anti-Debugging","anchor":"tampering-detection-and-anti-debugging","text":"TrustedSigner accepts several fingerprints separated by semicolons, for example an upload key and the Google Play app-signing key. How to obtain each value, and what happens when a pin is missing, is explained in Android (MAUI) Package Integrity and iOS (MAUI) Package Integrity. The Android Application example shows a complete Android project file."},{"page":16,"heading":"Managed AES for FIPS Hosts","anchor":"managed-aes-for-fips-hosts","text":"The runtime decryptors injected for code, string (XOR and HASH), value and resource encryption use the platform cryptographic provider, and a host with a broken OpenSSL FIPS configuration cannot start such an assembly. Since version 11.8, encryption=aesmanaged selects a self-contained managed decryptor instead:\n<PropertyGroup>\n  <MsilEncryption>true</MsilEncryption>\n  <Use>encryption=aesmanaged</Use>\n</PropertyGroup>\nUse accepts any key-value pair accepted by the --use switch, separated by semicolons, for example tagassembly=on. See FIPS Compliance for the trade-offs of the managed decryptor."},{"page":16,"heading":"Merging and Embedding Assemblies","anchor":"merging-and-embedding-assemblies","text":"MergeAssembly and EmbedAssembly items list the assemblies to merge into, or embed in, the target assembly. MergeInternalize makes the merged public types internal, and MergeCopyAttributes controls whether their assembly-level attributes are copied:\n<ItemGroup>\n  <MergeAssembly Include=\"$(TargetDir)Acme.View.dll\" />\n  <MergeAssembly Include=\"$(TargetDir)Acme.ViewModel.dll\" />\n  <EmbedAssembly Include=\"$(TargetDir)Framework.Mvvm.dll\" />\n</ItemGroup>\n<PropertyGroup>\n  <MergeInternalize>true</MergeInternalize>\n</PropertyGroup>\nInfo: Babel runs right after compilation, before the build copies dependencies to the output folder, so on a clean build a path under $(TargetDir) may not exist yet. The reliable source is the list of references resolved for the compiler, which you can filter inside the BeforeObfuscate target:\n<Target Name=\"BeforeObfuscate\">\n  <ItemGroup>\n    <MergeAssembly Include=\"@(ReferencePathWithRefAssemblies)\"\n                   Condition=\"'%(Filename)' == 'Acme.View' Or '%(Filename)' == 'Acme.ViewModel'\" />\n  </ItemGroup>\n</Target>\nThe package also removes merged and embedded assemblies from the .deps.json file and from the publish set, so dotnet publish does not ship them twice. See Merge and Embed for the feature and Publishing for the build-side details."},{"page":16,"heading":"Map Files and Cross-Assembly Renaming","anchor":"map-files-and-cross-assembly-renaming","text":"GenerateMapOutFile writes the XML map file of the obfuscated assembly, used to decode stack traces and to rename the public interface of a library consistently across assemblies. MapInFile items feed the map files of already obfuscated assemblies back to Babel:\n<PropertyGroup>\n  <GenerateMapOutFile>true</GenerateMapOutFile>\n  <BabelMapOutFile>$(SolutionDir)MapOut\\$(TargetFileName).map.xml</BabelMapOutFile>\n</PropertyGroup>\n<ItemGroup>\n  <MapInFile Include=\"$(SolutionDir)MapOut\\Acme.Core.dll.map.xml\" />\n</ItemGroup>\nSee XML Map Files and Cross Assembly Renaming. The Unit Tests example uses a map file to run tests against an obfuscated library, and the Publish .NET App example obfuscates the public interface of a NuGet dependency and feeds its map file to the application."},{"page":16,"heading":"Optimizations","anchor":"optimizations","text":"<PropertyGroup>\n  <DeadCodeElimination>true</DeadCodeElimination>\n  <SealClasses>true</SealClasses>\n  <EnumRemoval>true</EnumRemoval>\n  <ConstRemoval>true</ConstRemoval>\n  <DisgregateRemoval>true</DisgregateRemoval>\n  <InlineExpansion>true</InlineExpansion>\n  <CleanAttributes>true</CleanAttributes>\n</PropertyGroup>\nEach optimization is described in Optimizations."},{"page":16,"heading":"Plugins","anchor":"plugins","text":"BabelPlugin items reference the plugin assemblies to load, and PluginsArguments passes key-value arguments to them. The BabelEncrypt plugin ships inside the package, in the same folder as the build tools:\n<ItemGroup>\n  <BabelPlugin Include=\"$(BabelTaskDir)BabelEncrypt.dll\" />\n</ItemGroup>\n<PropertyGroup>\n  <PluginsArguments>dictionary=exclusionlist.txt</PluginsArguments>\n</PropertyGroup>\nSee Babel Obfuscator Plugins and the Encrypt Plugin."},{"page":16,"heading":"Logging and Diagnostics","anchor":"logging-and-diagnostics","text":"<PropertyGroup>\n  <VerboseLevel>3</VerboseLevel>\n  <GenerateLogFile>true</GenerateLogFile>\n  <BabelLogFile>$(IntermediateOutputPath)babel.log</BabelLogFile>\n  <BabelProvideCommandLineArgs>true</BabelProvideCommandLineArgs>\n  <ShowStatistics>true</ShowStatistics>\n  <Trace>MyApp\\.Services\\..*</Trace>\n  <BabelWarningsToIgnore>W00008</BabelWarningsToIgnore>\n  <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>\n</PropertyGroup>\nVerboseLevel controls how much of the Babel log reaches the build output; GenerateLogFile and BabelLogFile save the complete log to a file.\nBabelProvideCommandLineArgs prints the command line the package passes to Babel and stores it in the @(BabelCommandLineArgs) item.\nTrace takes a regular expression and explains, symbol by symbol, why a match was or was not obfuscated: the fastest way to debug rules.\nBabelWarningsToIgnore, BabelWarningsAsErrors and BabelWarningsAsInfos take lists of warning codes and change how they are reported.\nMakeBabelProjectFile writes an MSBuild project equivalent to the current configuration, which is useful to reproduce a build with the Babel task or the command line tool.\nEvery property accepted by the package is listed in the Package Reference."},{"page":17,"heading":"","anchor":"","text":"Where the package runs Babel inside the MSBuild pipeline, how to move that\nstep, the targets you can hook, what happens on publish, and how the build\ntools are selected."},{"page":17,"heading":"Where Obfuscation Runs","anchor":"where-obfuscation-runs","text":"By default the package runs Babel right after CoreCompile, on the assembly the compiler has just written to the intermediate folder, $(IntermediateOutputPath)$(TargetFileName), that is the obj folder. Every later step of the build then works on the obfuscated assembly: the copy to bin, the generation of .deps.json, satellite assemblies, and on publish trimming, single-file bundling, ReadyToRun or NativeAOT compilation, and packaging into an APK or an app bundle.\nThis ordering is the reason to use the package in SDK-style projects. The .NET SDK rewrites IL after compilation, and Babel has to see the assembly before it does; an assembly taken from bin or from the publish folder has already been through those steps. Placing the task after CoreCompile by hand is fragile, because the exact target sequence depends on the project type and the SDK version. The package resolves that for you.\nTwo more rules keep the IDE responsive:\nDesign-time builds are skipped. Visual Studio and code analyzers run background builds continuously; the package does not inject the obfuscation step into them.\nObfuscation runs only when the compiler ran. An incremental build that finds the assembly up to date skips Babel as well, so the already obfuscated assembly in obj is never processed twice."},{"page":17,"heading":"Moving the Obfuscation Step","anchor":"moving-the-obfuscation-step","text":"Three properties change the injection point:\nProperty | Effect\nRunBabelAfterBuild | When true, Babel runs at the end of the build, after the output has been copied to bin, and processes $(TargetPath) instead of the intermediate assembly.\nBabelAfterTargets | Runs the obfuscation step after the named MSBuild target.\nBabelBeforeTargets | Runs the obfuscation step before the named MSBuild target.\nSetting any of them disables the default placement after CoreCompile. With BabelAfterTargets or BabelBeforeTargets Babel still processes the intermediate assembly; if the chosen target runs after the output has been copied, point BabelInputFile and BabelOutputFile to $(TargetPath).\nA typical use is a Windows Forms application with localized resources, where Babel should run once the satellite assemblies have been generated so that it can process them too:\n<PropertyGroup>\n  <BabelAfterTargets>CoreGenerateSatelliteAssemblies</BabelAfterTargets>\n</PropertyGroup>\nWarning: Whatever runs between compilation and the moved obfuscation step sees the unobfuscated assembly. Keep the default placement for trimmed, single-file and AOT-published projects, and for any project where an SDK step rewrites IL after compilation."},{"page":17,"heading":"Target Sequence and Extension Points","anchor":"target-sequence-and-extension-points","text":"The obfuscation step is the ObfuscateBuild target. It first prepares the Babel task configuration, then runs it:\nObfuscateBuild\n├─ ObfuscateSettings\n│  ├─ ObfuscateDefaultSettings      renaming defaults, license lookup, babelRules.xml, search directories\n│  ├─ ObfuscateFrameworkSettings    selects the assembly to process (obj, or $(TargetPath))\n│  ├─ ObfuscateSetupBabelFiles      BabelInputFile / BabelOutputFile, GenerateDebug when a PDB exists\n│  ├─ ObfuscateCustomSettings       empty, yours to redefine\n│  ├─ SetupObfuscate                empty, yours to redefine\n│  └─ ConfigureBabel                empty, yours to redefine\n└─ Obfuscate\n   ├─ BeforeObfuscate               empty, yours to redefine\n   ├─ CoreObfuscate                 runs the Babel task\n   └─ AfterObfuscate                empty, yours to redefine\nRedefine an empty target in the project file to run your own steps at that point:\nTarget | Runs | Use it to\nObfuscateCustomSettings, SetupObfuscate, ConfigureBabel | After the package computed its defaults and the input and output files, before Babel runs | Override computed properties such as BabelInputFile, BabelOutputFile, GenerateDebug or the search directories.\nBeforeObfuscate | Just before the Babel task | Obfuscate a dependency first, compute settings from resolved references, generate rules.\nAfterObfuscate | Just after the Babel task | Copy the map or log file somewhere, run a check on the obfuscated assembly."},{"page":17,"heading":"Target Sequence and Extension Points","anchor":"target-sequence-and-extension-points","text":"CoreObfuscate publishes two outputs you can read in AfterObfuscate: the BabelExitCode property, and the @(BabelCommandLineArgs) item holding the command line when BabelProvideCommandLineArgs is true.\nOverriding the Task Configuration\nThe package configures the Babel task from the project: search directories from the references, the strong-name key, the PDB, the rules file. When the defaults do not fit, adjust them in BeforeObfuscate. The example below forces debug symbol generation and replaces the search directories with the output folder:\n<Target Name=\"BeforeObfuscate\">\n  <!-- Override computed properties -->\n  <PropertyGroup>\n    <GenerateDebug>true</GenerateDebug>\n  </PropertyGroup>\n\n  <!-- Replace the Babel search directories -->\n  <ItemGroup>\n    <BabelSearchDirectories Remove=\"@(BabelSearchDirectories)\" />\n    <BabelSearchDirectories Include=\"$(TargetDir)\" />\n  </ItemGroup>\n</Target>\nBeforeObfuscate is also the place to run a second Babel task on a dependency before the main assembly is obfuscated, as the Publish .NET App example does to rename the public interface of a NuGet package with cross-assembly renaming.\nAn AfterObfuscate target can collect the artifacts Babel produced, for example the map file for a shared folder used by the Unit Tests example:"},{"page":17,"heading":"Target Sequence and Extension Points","anchor":"target-sequence-and-extension-points","text":"<PropertyGroup>\n  <GenerateMapOutFile>true</GenerateMapOutFile>\n  <BabelMapOutFile>$(IntermediateOutputPath)$(TargetFileName).map.xml</BabelMapOutFile>\n</PropertyGroup>\n\n<Target Name=\"AfterObfuscate\">\n  <Copy SourceFiles=\"$(BabelMapOutFile)\" DestinationFolder=\"$(SolutionDir)MapOut\" />\n</Target>"},{"page":17,"heading":"Publishing","anchor":"publishing","text":"Because obfuscation happens before the publish steps, dotnet publish and Visual Studio publish profiles produce obfuscated output with no extra configuration. The package adds three adjustments on top:\nMerged and embedded assemblies are removed from the publish set. The UpdateBabelFilesToPublish target, which runs after ComputeFilesToPublish, drops every MergeAssembly and EmbedAssembly item, together with its .pdb and .xml files, from the files to publish. Set BabelPublishEnabled to false to keep them.\nThe .deps.json files are updated. The UpdateBabelBuildDependencyFile and UpdateBabelPublishDependencyFile targets remove the merged and embedded assemblies, and the package itself, from the build and publish dependency manifests, so the host does not look for assemblies that no longer exist as separate files. Set BabelUpdateDependencyFile to false to leave the manifests alone.\nDebug symbols are not published in Release. The package sets CopyOutputSymbolsToPublishDirectory to false for the Release configuration unless the project sets it, because PDB files give an attacker the file names and line numbers of the original code. Set it to true to publish them anyway.\nSingle-file, trimmed and AOT publishing work with the obfuscated assembly, with two caveats: the desktop tampering check cannot verify a single-file image, and Babel warns about it (see Tampering Detection), and for .NET MAUI iOS the linker should be set to Link SDK assemblies only, as explained in Obfuscate .NET MAUI."},{"page":17,"heading":"Selecting the Build Tools","anchor":"selecting-the-build-tools","text":"The package ships one set of Babel build tools per MSBuild host and selects it from the host that is running the build:\nMSBuild host | Tools folder\n.NET SDK 6.0, 7.0, 8.0, 9.0 or 10.0 (dotnet build, Visual Studio) | tools\\net6.0 … tools\\net10.0, matching the SDK version\nAny other .NET SDK version | tools\\net9.0\n.NET Framework MSBuild (MSBuild.exe) | tools\\net472\nMono MSBuild | tools\\Mono\nThe selected folder is exposed as BabelTaskDir, and BabelPackageDir points to the root of the extracted package. To force a different set of tools, set BabelTaskDir in the project file:\n<PropertyGroup>\n  <BabelTaskDir>$(BabelPackageDir)tools\\net8.0\\</BabelTaskDir>\n</PropertyGroup>\nSet it in the project file or in Directory.Build.targets, not in Directory.Build.props: the package's own .props file is imported after Directory.Build.props and would overwrite the value.\nTo run a Babel installed outside the package, for example the command line tool extracted from a babel_net* zip package, set BabelPath to its folder and, if needed, BabelExe to the executable name (babel.exe or babel.dll)."},{"page":17,"heading":"Build Servers","anchor":"build-servers","text":"Nothing in the package is specific to a machine, so a project that builds obfuscated on a developer PC builds obfuscated on any agent that can restore the package and reach a license. The examples cover the common services:\nGitHub Actions — package on GitHub Packages, license key from a repository secret.\nAzure DevOps — package on an Azure Artifacts feed, license key from a secret pipeline variable.\nAppVeyor — package on the account feed, license key from an encrypted variable.\nUnit Tests — testing the obfuscated assemblies in the same pipeline.\nLinux agents and containers run the tools\\netX.0 build of Babel. Hosts with a broken OpenSSL FIPS configuration need the settings described in FIPS Compliance."},{"page":18,"heading":"","anchor":"","text":"Babel.Obfuscator.Tool packages the babel command line as a dotnet tool, so\nyou can run Babel Obfuscator from a terminal or a script on Windows, Linux\nand macOS with nothing but the .NET SDK installed."},{"page":18,"heading":"What the Package Contains","anchor":"what-the-package-contains","text":"Babel.Obfuscator.Tool is a .NET tool package that installs the babel command. It is the same command line tool shipped in the babel_net* zip packages, with the same options, and it comes with the Ultimate edition and the Babel Licensing site editions (Server and Data Center). The package ships one build of the tool for each supported runtime, .NET 6.0 through .NET 10.0, and the dotnet CLI picks the build that matches the SDK on the machine. Each build contains:\nbabel.dll, the command line tool, with its runtime configuration.\nThe BabelEncrypt plugin, ready to be loaded with --plugin.\nBabel.Build.dll, the Babel MSBuild task assembly, for build scripts that reference the Babel task by file path.\nLike Babel.Obfuscator, the tool package is not on nuget.org: host it on your own feed as described in Hosting the Package."},{"page":18,"heading":"When to Use the Tool","anchor":"when-to-use-the-tool","text":"Use the tool when you want to run Babel yourself rather than as a step of an MSBuild build:\nObfuscating assemblies that are already built, for example .NET Framework binaries produced by another build system.\nScripted or batch obfuscation of many assemblies, and agent-driven automation through the AI-friendly mode.\nRunning the command line tool on Linux and macOS build machines and agents.\nUtility commands such as decoding a stack trace (--stacktrace), checking the license (--license) or generating an MSBuild project from a command line (--makeproject).\nWarning: The tool is not a replacement for the Babel.Obfuscator package in dotnet build and dotnet publish pipelines. The .NET SDK rewrites IL after compilation (dependency resolution, trimming, single-file bundling, ahead-of-time compilation) and an assembly taken from bin, obj or the publish folder has already been through those steps, so obfuscating it afterwards is not supported. Reference the package instead: it runs Babel at the right point inside the build."},{"page":18,"heading":"Installing the Tool","anchor":"installing-the-tool","text":"Global tool\nA global tool is installed once per user and available from every terminal:\ndotnet tool install Babel.Obfuscator.Tool -g\nWhen the feed is not listed in a NuGet.config file, pass it explicitly. The source can be a feed URL or a local folder:\ndotnet tool install Babel.Obfuscator.Tool -g --add-source ~/NuGet\nOn Linux and macOS make sure the tools folder is on the path, or the babel command is not found:\nexport PATH=\"$PATH:$HOME/.dotnet/tools\"\nLocal tool\nA local tool is pinned to a repository through a tool manifest, so every developer and CI agent runs the same Babel version:\ndotnet new tool-manifest\ndotnet tool install Babel.Obfuscator.Tool\nThis records the tool in .config/dotnet-tools.json, which you commit. On any other machine, dotnet tool restore installs the pinned version. A local tool is invoked through the dotnet CLI:\ndotnet babel --version\nUpdating and removing\ndotnet tool update Babel.Obfuscator.Tool -g\ndotnet tool list -g\ndotnet tool uninstall Babel.Obfuscator.Tool -g\nDrop -g for a local tool. The same commands are described in Install."},{"page":18,"heading":"Licensing the Tool","anchor":"licensing-the-tool","text":"The tool needs the same license as the product. A dotnet tool has no installation folder you can copy babel.licenses into, so give Babel the license in one of these ways:\nSet the BABEL_LICENSE_PATH environment variable to the full path of the license file. This is the recommended setup on developer machines and build agents:\nexport BABEL_LICENSE_PATH=~/Babel/babel.licenses\nPass --license on each invocation, with the path of the license file or of a folder to search.\nPass --license env:BABEL_LICENSE, where the variable holds a license key: the right choice on build servers, where the key lives in a secret. For a floating license, store the user key as floating:<user key>.\nbabel --license with no argument prints the license in use. Remember that a license file is valid for one product version: use the file that came with the same version as the tool, and update both together."},{"page":18,"heading":"Using the Tool","anchor":"using-the-tool","text":"The babel command accepts the syntax and the switches documented in Command Line and in the Command Line Reference. A typical invocation names the assembly to obfuscate, the output file and the features to enable:\nbabel MyApp.dll --output obfuscated/MyApp.dll --stringencryption stream --controlflow if=on --controlflow switch=on --iterations 3 --resourceencryption --rules babelRules.xml --mapout\nEvery feature described in this manual is available from the tool: rules with --rules, merging and embedding with extra assembly arguments and --embed, map files with --mapin and --mapout, plugins with --plugin, and the managed AES decryptor with --use encryption=aesmanaged. With a local tool, prefix the command with dotnet.\nScripting and automation\nSince version 11.7 the command line has an AI-friendly mode designed for scripts and agents:\nbabel MyApp.dll --stringencryption stream --format ndjson --quiet --strict-exit\n--format json or ndjson turns the output into a machine-readable stream and routes human diagnostics to standard error, --quiet removes the banner and makes any interactive prompt fail fast, and --strict-exit returns a distinct exit code for invalid arguments, missing input, obfuscation, licensing and signing failures.\nRunning on a build server"},{"page":18,"heading":"Using the Tool","anchor":"using-the-tool","text":"The tool fits pipelines that obfuscate build artifacts as a separate step. With a tool manifest committed to the repository and the feed configured in NuGet.config (see the GitHub Actions example for a configuration that authenticates against GitHub Packages), a GitHub Actions job looks like this:\nsteps:\n  - uses: actions/checkout@v4\n  - uses: actions/setup-dotnet@v4\n    with:\n      dotnet-version: '10.0.x'\n  - name: Restore tools\n    run: dotnet tool restore\n    env:\n      PACKAGES_TOKEN: ${{ secrets.PACKAGES_TOKEN }}\n  - name: Obfuscate\n    run: dotnet babel artifacts/MyLib.dll --license env:BABEL_LICENSE --stringencryption stream --strict-exit\n    env:\n      BABEL_LICENSE: ${{ secrets.BABEL_LICENSE_SECRET }}"},{"page":18,"heading":"FIPS-Enabled Hosts","anchor":"fips-enabled-hosts","text":"Since version 11.8 the tool binaries are self-obfuscated with the managed AES algorithm, so babel starts on hosts whose OpenSSL FIPS provider is broken. The assemblies you protect on such hosts still need a managed decryptor of their own: use the STREAM string encryption algorithm and --use encryption=aesmanaged for the other encryption features, as explained in FIPS Compliance."},{"page":18,"heading":"Troubleshooting","anchor":"troubleshooting","text":"babel: command not found — the global tools folder is not on the path; add ~/.dotnet/tools to PATH, or use a local tool and run dotnet babel.\nA message asking to install .NET — the selected build of the tool needs the matching .NET runtime, from 6.0 to 10.0. Install that runtime, or set DOTNET_ROLL_FORWARD=Major to run the tool on a newer runtime.\nA valid license could not be found — check BABEL_LICENSE_PATH or the --license argument, then run babel --license to see what Babel loaded. A license file for a different version is reported as not valid.\nThe output differs from a Babel Desktop run — Babel Desktop applies the settings stored in its .babel project, while the tool applies only the switches on the command line. Compare the two configurations, in particular the obfuscation agent and the rules."},{"page":19,"heading":"","anchor":"","text":"Every MSBuild property, item and target defined by the Babel.Obfuscator\npackage, and the mapping between the package properties and the attributes\nof the Babel task."},{"page":19,"heading":"Package Properties","anchor":"package-properties","text":"The properties below control the package itself. Obfuscation settings are listed in the Property Mapping table."},{"page":19,"heading":"Package Properties","anchor":"package-properties","text":"Property | Default | Description\nBabelEnabled | true | Master switch. When false, no Babel target runs, publish adjustments included.\nBabelPublishEnabled | $(BabelEnabled) | Whether merged and embedded assemblies are removed from the publish set.\nBabelUpdateDependencyFile | $(BabelEnabled) | Whether the build and publish .deps.json files are updated after obfuscation.\nBabelOverrideCompile | true | Whether the package injects the obfuscation step after CoreCompile. Set to false to wire the ObfuscateBuild target yourself.\nRunBabelAfterBuild | false | When true, Babel runs at the end of the build on $(TargetPath) instead of on the intermediate assembly.\nBabelBeforeTargets |  | Runs the obfuscation step before the named target, disabling the default placement.\nBabelAfterTargets |  | Runs the obfuscation step after the named target, disabling the default placement.\nBabelPackageDir | package root | Root folder of the extracted package.\nBabelTaskDir | per host | Folder the Babel task and tools are loaded from; see Selecting the Build Tools.\nBabelPath | $(BabelTaskDir) | Folder of the Babel executable to run (task attribute ToolPath).\nBabelExe |  | Name of the Babel executable, babel.exe or babel.dll (task attribute ToolExe).\nBabelInputFile | intermediate assembly | Assembly to obfuscate. Computed by the package; override it in a settings target.\nBabelOutputFile | $(BabelInputFile) | Obfuscated output. Computed by the package; override it in a settings target."},{"page":19,"heading":"Package Properties","anchor":"package-properties","text":"BabelLicense | babel.licenses found in the project folder or a parent folder | License file path, license key or floating: user key.\nBabelLicenseDir |  | Folder where babel.licenses was found, set by the package.\nSymbolsRenaming | true | Enables or disables every renaming feature at once.\nNoConfiguration | true | Whether Babel ignores its configuration file.\nGenerateDebug | true when a PDB exists | Whether debug symbols are generated for the obfuscated assembly.\nCopyOutputSymbolsToPublishDirectory | false in Release | Standard SDK property; the package turns it off in Release so PDB files are not published.\nBabelProvideCommandLineArgs | false | Writes the Babel command line to the log and to the @(BabelCommandLineArgs) item.\nBabelWarningsAsErrors |  | Warning codes to report as errors. Set it to W00000 to fail builds that run in evaluation mode.\nBabelWarningsAsInfos |  | Warning codes to report as informational messages.\nBabelWarningsToIgnore |  | Warning codes to suppress.\nBabelExitCode |  | Output: exit code of the Babel task, available after CoreObfuscate."},{"page":19,"heading":"Package Items","anchor":"package-items","text":"Item | Description\nBabelRules | XML rules files. babelRules.xml in the project folder is added automatically.\nMergeAssembly | Assemblies to merge into the target assembly.\nEmbedAssembly | Assemblies to embed in the target assembly.\nMapInFile | XML map files of already obfuscated assemblies.\nBabelPlugin | Plugin assemblies to load.\nBabelSearchDirectories | Assembly search directories. Computed from the project references; replace or extend it in a settings target.\nBabelTargetReferences | Additional search entries passed as references.\nAddReferences | Assemblies to add as references of the obfuscated assembly.\nSatelliteAssembly | Satellite assemblies to process.\nXmlDocumentationFile | XML documentation files to process together with the assembly.\nBabelCommandLineArgs | Output: the command line passed to Babel, when BabelProvideCommandLineArgs is true."},{"page":19,"heading":"Targets","anchor":"targets","text":"Target | Description\nObfuscateBuild | The obfuscation step injected into the build. Runs ObfuscateSettings then Obfuscate.\nObfuscateSettings | Prepares the Babel task configuration by running the settings targets below.\nObfuscateDefaultSettings | Applies the renaming defaults, looks up the license file, adds babelRules.xml and builds the search directories.\nObfuscateFrameworkSettings | Selects the assembly to process: the intermediate assembly, or $(TargetPath) when RunBabelAfterBuild is true.\nObfuscateSetupBabelFiles | Sets BabelInputFile and BabelOutputFile, and enables GenerateDebug when a PDB exists.\nObfuscateCustomSettings, SetupObfuscate, ConfigureBabel | Empty targets, redefine them to adjust the computed configuration before Babel runs.\nObfuscate | Runs BeforeObfuscate, CoreObfuscate and AfterObfuscate.\nBeforeObfuscate | Empty target, redefine it to run tasks just before the Babel task.\nCoreObfuscate | Runs the Babel task. Do not redefine it.\nAfterObfuscate | Empty target, redefine it to run tasks just after the Babel task.\nUpdateBabelBuildDependencyFile | After GenerateBuildDependencyFile: removes merged and embedded assemblies and the package from the build .deps.json.\nUpdateBabelPublishDependencyFile | After GeneratePublishDependencyFile: the same for the publish .deps.json.\nUpdateBabelFilesToPublish | After ComputeFilesToPublish: removes merged and embedded assemblies from the publish set."},{"page":19,"heading":"Targets","anchor":"targets","text":"OverrideCompileWithBabel | After PrepareForBuild: inserts ObfuscateBuild after CoreCompile, unless the step has been moved or the build is a design-time build.\nEnableObfuscationFlag | Triggered by compilation: enables ObfuscateBuild only when the compiler actually ran."},{"page":19,"heading":"Property Mapping","anchor":"property-mapping","text":"The table maps every attribute of the Babel task to the MSBuild property or item the package reads. Properties accept the same values as the corresponding command line switch. Attributes marked 12.0 were added in version 12."},{"page":19,"heading":"Property Mapping","anchor":"property-mapping","text":"Babel task attribute | Kind | Package property or item\nAddReferences | Item | @(AddReferences)\nAndroidSigningKeyAlias | Property | AndroidSigningKeyAlias\nAndroidSigningKeyPass | Property | AndroidSigningKeyPass\nAndroidSigningKeyStore | Property | AndroidSigningKeyStore\nAndroidSigningStorePass | Property | AndroidSigningStorePass\nBabelDirectory | Property | BabelDirectory\nCleanAttributes | Property | CleanAttributes\nConstRemoval | Property | ConstRemoval\nControlFlowIterations | Property | ControlFlowIterations (ILIterations is accepted as an alias)\nControlFlowObfuscation | Property | ControlFlowObfuscation\nCopyAttributes | Property | MergeCopyAttributes\nDbgHelpDllDir | Property | DbgHelpDllDir\nDeadCodeElimination | Property | DeadCodeElimination\nDebuggingProtection | Property | DebuggingProtection\nDependenciesManifest | Property | DependenciesManifest\nDetectIfObfuscated | Property | DetectIfObfuscated\nDisgregateRemoval | Property | DisgregateRemoval\nDynamicProxy | Property | DynamicProxy\nDynamicProxyCallFilters | Property | DynamicProxyCallFilters\nEmbedAssemblies | Item | @(EmbedAssembly)\nEmitInvalidOpcodes | Property | EmitInvalidOpcodes\nEnableObfuscationAgent | Property | EnableObfuscationAgent\nEnumRemoval | Property | EnumRemoval\nFlattenNamespaces | Property | FlattenNamespaces\nFramework | Property | Framework\nGenerateDebug | Property | GenerateDebug\nGenerateLogFile | Property | GenerateLogFile\nGenerateMapOutFile | Property | GenerateMapOutFile"},{"page":19,"heading":"Property Mapping","anchor":"property-mapping","text":"InlineExpansion | Property | InlineExpansion\nInputFile | Property | BabelInputFile\nInstrument | Property | BabelInstrument\nInstrumentEmptyMethods | Property | InstrumentEmptyMethods\nInternalize | Property | MergeInternalize\nKeyContainer | Property | KeyContainerName\nKeyFile | Property | KeyOriginatorFile\nKeyPwd | Property | SigningCertPassword\nLicense | Property | BabelLicense\nLogFile | Property | BabelLogFile\nMakeProject | Property | MakeBabelProjectFile\nMapInFiles | Item | @(MapInFile)\nMapOutFile | Property | BabelMapOutFile\nMergeAssemblies | Item | @(MergeAssembly)\nModuleInitializer | Property | ModuleInitializer\nModuleInitializerTarget | Property | ModuleInitializerTarget\nModuleVersionId | Property | ModuleVersionId\nMsilEncryption | Property | MsilEncryption\nNameLength | Property | NameLength\nNamePrefix | Property | NamePrefix\nNoConfiguration | Property | NoConfiguration\nNoWarnings | Property | BabelWarningsToIgnore\nObfuscateEvents | Property | ObfuscateEvents\nObfuscateFields | Property | ObfuscateFields\nObfuscateMethods | Property | ObfuscateMethods\nObfuscateParameters | Property | ObfuscateParameters\nObfuscateProperties | Property | ObfuscateProperties\nObfuscateTypes | Property | ObfuscateTypes\nObfuscateXaml | Property | ObfuscateXaml\nOutputFile | Property | BabelOutputFile\nOverloadedRenaming | Property | OverloadedRenaming\nPdbFile | Property | PdbFile\nPdbPwd | Property | PdbPwd\nPlugins | Item | @(BabelPlugin)\nPluginsArguments | Property | PluginsArguments"},{"page":19,"heading":"Property Mapping","anchor":"property-mapping","text":"ProvideCommandLineArgs | Property | BabelProvideCommandLineArgs\nRandomSeed | Property | RandomSeed\nReferences | Item | @(BabelTargetReferences)\nRemoveFiles | Property | BabelRemoveFiles\nResourceEncryption | Property | ResourceEncryption\nRulesFiles | Item | @(BabelRules)\nSatelliteAssemblies | Item | @(SatelliteAssembly)\nSealClasses | Property | SealClasses\nSearchDirectories | Item | @(BabelSearchDirectories)\nSearchSatelliteAssemblies | Property | SearchSatelliteAssemblies\nShowLogo | Property | ShowLogo\nShowStatistics | Property | ShowStatistics\nSingleFile | Property | PublishSingleFile (standard SDK property)\nSkipFiles | Property | BabelSkipFiles\nStatisticsFile | Property | StatisticsFile\nStringEncryption | Property | StringEncryption\nSuppressIldasm | Property | SuppressIldasm\nSuppressReflection | Property | SuppressReflection\nTakeFiles | Property | BabelTakeFiles\nTamperingDetection | Property | TamperingDetection\nTargetAssemblyName | Property | TargetAssemblyName\nToolExe | Property | BabelExe\nToolPath | Property | BabelPath\nTrace | Property | Trace\nTrustedBundle 12.0 | Property | TrustedBundle\nTrustedSigner 12.0 | Property | TrustedSigner (several fingerprints separated by ;)\nTrustedTeam 12.0 | Property | TrustedTeam\nUnicodeNormalization | Property | UnicodeNormalization\nUse | Property | Use\nValueEncryption | Property | ValueEncryption\nVerboseLevel | Property | VerboseLevel\nVirtualFunctions | Property | VirtualFunctions\nWarningsAsErrors | Property | BabelWarningsAsErrors"},{"page":19,"heading":"Property Mapping","anchor":"property-mapping","text":"WarningsAsInfos | Property | BabelWarningsAsInfos\nXapCompressionLevel | Property | XapCompressionLevel\nXmlDocFiles | Item | @(XmlDocumentationFile)\nXmlRules | Property | XmlRules"},{"page":19,"heading":"Setting the String Encryption Algorithm","anchor":"setting-the-string-encryption-algorithm","text":"The StringEncryption package property enables string encryption and selects the algorithm, exactly like the --stringencryption command-line switch. Accepted values are xor, hash, stream and custom (see String Encryption for a description of each). A boolean true enables string encryption with the default algorithm, while an algorithm name both enables it and selects that algorithm.\nFor example, to encrypt strings with the STREAM algorithm (authenticated per-string encryption, fully managed, AOT/trim/FIPS-safe, and supported from .NET Framework through .NET 10 including Android/iOS/MAUI), add to your project file:\n<PropertyGroup>\n  <StringEncryption>stream</StringEncryption>\n</PropertyGroup>\nThe STREAM algorithm (Ultimate) is not included in lower editions: with those, stream falls back to the default algorithm.\nOn .NET Android / iOS / MAUI projects, run the obfuscation as a string-encryption-only pass so that type and member names stay intact for the platform interop layer."},{"page":20,"heading":"","anchor":"","text":"Babel Obfuscator can perform a series of tasks according to a set of pre-defined rules (Agent), chosen to avoid some common issues introduced by obfuscation, which might otherwise break the resulting assembly.\nAlthough the predefined rules defined, in most cases, are sufficient to prevent the common problems due to obfuscation, sometimes the user wants to define his own custom rules to finetune Babel or make the obfuscated assembly to work as expected.\nObfuscation rules can be specified using XML files or embedded in source code using custom attributes already provided by .NET."},{"page":21,"heading":"","anchor":"","text":"In addition to options specified on the command line or through the MSBuild\nBabel task, Babel Obfuscator can be controlled and configured using rules defined in external XML\nfiles. These XML rules provide fine-grained control over the obfuscation process, allowing you to target specific assemblies, types, methods, and other code elements."},{"page":21,"heading":"Rules Files","anchor":"rules-files","text":"Babel rules files are XML documents that contain configuration information used to customize and control the obfuscation process. These files allow you to define precisely which obfuscation features should be applied to specific parts of your code, giving you granular control over the protection of your assemblies.\n<Rules xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <Rule name=\"rule 1\" feature=\"default\" exclude=\"false\">\n  </Rule>\n  <Rule name=\"rule 2\" feature=\"control flow\" exclude=\"true\">\n  </Rule>\n</Rules>\nThe Rules element can define a targetAssembly attribute that limits the scope of the rules it contains to a specific assembly. If the targetAssembly attribute is not specified, the rules will apply to all assemblies being processed. Example:\n<Rules xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       targetAssembly=\"ACME.Data\">\nInfo: In the XML rule file, rules are processed sequentially from top to bottom in the order they appear. This sequential processing allows you to override any existing rules with more specific rules that are listed subsequently, providing a flexible and hierarchical rule structure."},{"page":21,"heading":"Rules Element","anchor":"rules-element","text":"The Rules element serves as the root container that defines a set of rules to be applied to the target assembly. This element can contain multiple Rule child elements, each specifying different obfuscation behaviors.\nAttribute | Description\ntargetAssembly | Specifies the fully qualified name of the assembly to which the rules are applied. If not defined, the rules will apply to all assemblies involved in the obfuscation process."},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"The Rule element is used to define a Babel obfuscation rule that can target one or more Babel Obfuscator features. Each rule specifies which code elements should be affected and how the obfuscation features should be applied to them.\nAttribute | Description\nname | A friendly, descriptive name for the rule that helps identify its purpose\nfeature | The obfuscator feature name, or a comma-separated list of feature names, that this rule targets. Multiple features can be specified to apply the same rule to different obfuscation aspects\nexclude | Boolean value indicating whether this rule will prevent the specified feature(s) from being executed. Set to \"true\" to exclude symbols from obfuscation, or \"false\" to explicitly include them\napplyToMembers | Boolean value indicating whether to apply the rule to all members of a symbol that matches the rule criteria. When enabled, the rule cascades to nested members\nlocked | Boolean value indicating whether this rule is immutable and cannot be overridden by subsequent rules in the processing order\nThe feature attribute defines the obfuscator feature on which the rule acts. The name and exclude attributes are mandatory, while the feature attribute is optional. If not specified, the feature defaults to \"default\", which refers to the renaming feature.\nThe obfuscator features are predefined strings that correspond to specific obfuscation capabilities. All supported feature names are listed in the tables below.\nFeature Table"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"The following features can target all symbol types defined inside an assembly, including types, methods, properties, fields, and events:"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"Feature | Description\nall | Targets all available obfuscation features\ndefault | The default feature refers to symbol renaming obfuscation\nagent | Targets the obfuscation agent functionality\ncleanup attributes | Removes unwanted attributes from the assembly metadata\ncontrol flow | Applies control flow obfuscation to make code logic harder to understand\ndead code | Enables dead code removal optimization\ndynamic proxy | Replaces direct method calls with dynamic proxy calls\nembed | Embeds dependent assemblies into the target assembly\nmerge | Merges multiple assemblies into a single assembly\nmsil encryption | Encrypts method bodies using MSIL (Microsoft Intermediate Language) code encryption\nrenaming | Obfuscates member names (types, methods, properties, fields, events)\nrenaming blob | Renames literal strings that correspond to renamed symbols, maintaining code functionality\nresource encryption | Encrypts embedded resources within the assembly\nstring encryption | Encrypts inline string literals within the code\nvalue encryption | Encrypts inline constant values and array initializations\ninline | Inlines method calls to reduce code structure visibility\ninstrumentation | Enables code instrumentation for monitoring and analysis\noptimizations | Applies various metadata and code optimizations\nxaml | Handles renaming of symbols referenced in XAML or BAML resources\nThe following obfuscation features are method-specific and can only be applied to method symbols:"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"Feature | Description\nmsil encryption get stream | Declares the method used to retrieve the encrypted code source stream for MSIL decryption\nstring encryption encrypt method | Defines the custom method used to encrypt string literals\nstring encryption decrypt method | Defines the custom method used to decrypt string literals at runtime\ninstrumentation on entry method | Defines the method to be called when entering an instrumented method\ninstrumentation on exit method | Defines the method to be called when exiting an instrumented method\ninstrumentation on exception method | Defines the method to be called when an exception occurs in an instrumented method\nmodule initializer | Designates a method to be executed automatically when the module is initialized by the runtime\nAny Rule element can contain child elements such as Access, Target, Pattern, HasAttribute, Properties and Description. The Pattern element is mandatory, while all others are optional. These child elements provide additional filtering and configuration capabilities for the rule. Example:\n<Rule name=\"DataWriter\" feature=\"msil encryption\" exclude=\"false\">\n  <Target>Methods</Target>\n  <Pattern>SQLUtils.DataWriter::*</Pattern>\n  <Properties>\n    <Cache>true</Cache>\n    <MinInstructionCount>6</MinInstructionCount>\n  </Properties>\n  <Description>Encrypt all methods of the DataWriter class.</Description>\n</Rule>\nBelow is the complete list of all possible Rule child elements:"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"Element\nAccess\nTargets\nPattern\nHasAttribute\nHasBase\nImplements\nNamespace\nProperties\nDescription\nAccess Element\nRestricts the rule's scope to symbols with the specified visibility modifiers. Possible values are All or any combination of Public, Protected, Internal, Private, FamilyAndAssembly, and FamilyOrAssembly. If this element is not present, the default value All is used, meaning the rule applies to symbols of any visibility.\nAccess | Description\nPublic | Accessible from any type in any assembly.\nProtected | Accessible from within the same type as the member, and from any derived types that inherit from it (also known as Family access).\nInternal | Accessible only within the same assembly in which the type is defined (also known as Assembly access).\nPrivate | Accessible only from within the same type as the member, or from a nested type within that type.\nFamilyOrAssembly | Accessible from types that qualify for either family access or assembly access (C# protected internal).\nFamilyAndAssembly | Accessible only from types that qualify for both family access and assembly access (C# private protected).\nTargets Element\nRestricts the scope of the rule to specific types of code symbols. Accepted values are All or any combination of Classes, Delegates, Structures, Interfaces, Enums, Events, Methods, Properties, Fields, StaticFields, and Resources. If this element is not present, the default value All is assumed, applying the rule to all symbol types.\nPattern Element"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"The Pattern element within Babel Obfuscator's XML Rule definition serves as a crucial component for identifying and matching assembly symbols that are subject to obfuscation. This element accepts either a fully qualified symbol name, a wildcard expression, or a regular expression, thereby establishing a versatile and adaptable filtering mechanism for targeting specific code elements.\nWildcard Expressions: For simpler selection criteria, the Pattern element can incorporate wildcard characters. The '?' character represents any single character, while '*' denotes zero or more characters. This feature enables broad yet controlled selection criteria for symbol matching, making it easy to target groups of related symbols without writing complex patterns.\nRegular Expressions: For more complex and precise filtering requirements, regular expressions can be employed within the Pattern element. When using regular expressions, the attribute isRegEx must be set to \"true\" to indicate that the pattern should be interpreted as a regular expression rather than a literal string or wildcard pattern. It is advisable to encapsulate the regular expression within a CDATA section to ensure proper XML parsing and accurate interpretation of special characters. For example:\n<Pattern isRegEx=\"true\"><![CDATA[^Properties.*]]></Pattern>\nFully Qualified Name Format"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"The format of a fully qualified symbol name in Babel Obfuscator's XML Rule pattern definition varies depending on the type of symbol being targeted. This nuanced approach ensures precise and effective obfuscation across various symbol types while maintaining clarity and consistency.\nTypes (Classes, Structures, Enums, Interfaces): The conventional format is represented as NamespaceName.TypeName, providing a straightforward notation for basic type declarations.\nNested Types: For nested types (types defined within other types), the format uses a forward slash separator: NamespaceName.TypeName/NestedTypeName. This notation clearly differentiates nested types from their parent types and maintains the hierarchical relationship.\nGeneric Types: The representation for generic types begins with NamespaceName.TypeName, followed by the generic type arguments enclosed within angle brackets:\nNamespaceName.TypeName<GenericArgumentList>\nGenericArgumentList: This element is not an independent pattern but rather an integral part of the Generic Types pattern. It defines the comma-separated list of generic type arguments, each specified with their full namespace and type name:\nNamespaceName.TypeName1,NamespaceName.TypeName2,...,NamespaceName.TypeNameN\nMethods: The typical format for methods includes the namespace, type name, method name, parameter list, and optionally the return type:\nNamespaceName.TypeName::MethodName(ParameterList):ReturnType"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"It is worth noting that the inclusion of the ReturnType in the pattern is optional and may be omitted in most cases.\nProperties: The prescribed format for properties follows this structure:\nNamespaceName.TypeName::PropertyName:PropertyType\nGenerally, the property type does not need to be included in the pattern and can be omitted.\nEvents: The format for events is expressed as:\nNamespaceName.TypeName::EventName:EventHandlerType\nThis format encompasses both the event name and its associated handler type.\nFields: Fields follow the format:\nNamespaceName.TypeName::FieldName:FieldType\nSimilar to properties, the field type is typically optional and not required in most pattern definitions.\nParameterList: This component is exclusively associated with the Methods pattern. It details the fully qualified type names of parameters, separated by commas:\nNamespaceName.TypeName1,NamespaceName.TypeName2,...,NamespaceName.TypeNameN\nRemember, these patterns are used to specify precisely which parts of the code Babel Obfuscator should target for obfuscation. The exact syntax may vary slightly depending on the context and the specific requirements of your obfuscation strategy. Using accurate patterns ensures that only the intended symbols are affected by the obfuscation rules.\nHasAttribute Element"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"Specifies a comma-separated list of fully qualified custom attribute type names. If the target symbol is decorated with at least one of these attributes, the rule will be applied to that symbol. This element provides attribute-based filtering for precise rule targeting.\nThis element supports the optional onEnclosingType attribute. When set to \"true\", this attribute specifies that the custom attribute should be checked on the target symbol's enclosing type rather than on the symbol itself:\n<HasAttribute onEnclosingType=\"true\">System.SerializableAttribute</HasAttribute>\nThis configuration will match symbols such as methods, properties, fields, and events that belong to any type decorated with the SerializableAttribute.\nHasBase Element\nSpecifies a comma-separated list of fully qualified base type names. The rule will match a type symbol if the target type derives from one of these specified base types. This element enables inheritance-based filtering for rule application.\nThis element supports the optional onEnclosingType attribute. When set to \"true\", this attribute specifies that Babel should search within the enclosing type hierarchy of the target symbols, allowing you to apply rules based on the inheritance structure of containing types.\nNamespace Element\nRestricts the rule to symbols within a specified namespace. This provides namespace-level filtering for rule application.\n<Namespace>ACME.Data</Namespace>"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"The rule will be applied to all symbols defined within the ACME.Data namespace and its sub-namespaces.\nProperties Element\nThe Properties element defines a collection of XML child elements used to customize the behavior of the selected rule feature. Each obfuscation feature supports specific properties that control its operation and fine-tune how it processes the matched symbols.\n<Rule name=\"DataWriter\" feature=\"msil encryption\" exclude=\"false\">\n  <Target>Methods</Target>\n  <Pattern>ACME.Data.DataWriter::*</Pattern>\n  <Properties>\n    <Cache>true</Cache>\n    <MinInstructionCount>6</MinInstructionCount>\n  </Properties>\n  <Description>Encrypts code in the DataWriter class.</Description>\n</Rule>\nThis rule configures the msil encryption feature by setting the Cache and MinInstructionCount properties for all methods in the DataWriter class.\nBelow is the comprehensive list of property elements supported by each obfuscation feature:\nagent\nProperty | Type | Description\nTaskNameList | String | A comma-separated list of agent task names to which the rule applies.\ncleanup attributes"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"Property | Type | Description\nAttributes | String | A comma-separated list of qualified type attribute names or regular expressions that match the members to include in the search.\nIncludeMembers | String | A comma-separated list of qualified symbol names or regular expressions that match the members to include in the search.\nExcludeMembers | String | A comma-separated list of qualified symbol names or regular expressions that match the members to exclude in the search.\ncontrol flow"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"Property | Type | Description\nILIterations | Integer | Specifies the number of iterations to apply during control flow obfuscation, with higher values producing more complex code structures.\nEmitInvalidOpcodes | Boolean | When enabled, adds invalid instruction opcodes within the method flow to confuse disassemblers and decompilers.\nChangeIfStatement | Boolean | When enabled, transforms and obfuscates conditional if statement instructions to make logic harder to follow.\nAddSwitchStatement | Boolean | When enabled, enriches control flow by inserting switch statement instructions into the method flow, creating more complex execution paths.\nScrambleControlFlow | Boolean | When enabled, produces \"spaghetti code\" by inserting irrelevant branches and jump instructions that significantly obscure the original control flow.\nMaxSwitchTargets | Integer | Sets the maximum number of case targets allowed in switch control flow obfuscation, controlling the complexity of generated switch statements.\nHideCaseConstantExpressions | Boolean | When enabled, hides the calculated constant values in switch control flow obfuscation by using computed expressions instead of literal values.\nRandomCall | Boolean | When enabled, adds random method call instructions to further confuse analysis (only available when switch control flow is enabled).\nAddMethodToken (*) | Boolean | When enabled, enriches control flow by adding load token instructions into the method flow, creating additional complexity."},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"StackUnderflow (*) | Boolean | When enabled, inserts instructions that create conditions where the evaluation stack underflows, making static analysis more difficult.\n(*) These options generate unverifiable IL code. If your assembly must run in a partially trusted environment or must pass PEVerify validation, do not enable these options.\nrenaming\nProperty | Type | Description\nDisableOverloading | Boolean | When enabled, disables overloaded renaming, meaning methods with different signatures will receive different obfuscated names rather than sharing the same name.\nDisableUnicode | Boolean | When enabled, prevents the use of Unicode characters in obfuscated names, restricting names to ASCII-only characters.\nInternalize | Boolean | When enabled, changes the visibility of all public types that match the rule from public to internal, reducing the assembly's API surface.\nNameLength | Integer | Specifies the desired length for renamed symbol names, allowing you to control how long or short obfuscated identifiers should be.\nNamePrefix | String | Defines a prefix string to be prepended to all renamed symbols, helping to identify or categorize obfuscated names.\nstring encryption"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"Property | Type | Description\nMinInstructionCount | Integer | Sets the minimum threshold for the number of method instructions required for the rule to be applied. Methods with fewer instructions will be excluded.\nMaxInstructionCount | Integer | Sets the maximum threshold for the number of method instructions allowed for the rule to be applied. Methods with more instructions will be excluded.\nmerge\nProperty | Type | Description\nCopyAttributes | String | A comma-separated list of fully qualified custom attribute type names or regular expressions used to filter which attributes should be copied from the source assembly to the target assembly during merging.\nNoCopyAttributes | String | A comma-separated list of fully qualified custom attribute type names or regular expressions used to filter which attributes should NOT be copied to the target assembly during merging.\nInternalize | Boolean | When enabled, changes the visibility from public to internal for all merged types that match the rule, hiding them from external assemblies.\nMergeAction | Default/Discard/Redirect | Specifies the merge action to be taken for the selected type. Default performs normal merging, Discard excludes the type from merging, and Redirect redirects references to another type in the target assembly (specified by the RedirectTo property).\nRedirectTo | String | Contains the fully qualified target assembly type name that will replace the source type when the Redirect merge action has been specified."},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"msil encryption\nProperty | Type | Description\nCache | Boolean | When enabled, caches the decrypted method in memory so that JIT compilation occurs only on the first access, improving subsequent performance.\nInternal | Boolean | When enabled, stores the MSIL-encrypted code inside the target assembly itself; when disabled, stores it in an external file.\nPassword | String | Specifies the password used to encrypt the method code, adding an additional layer of protection.\nSource | String | Defines a source identifier name for the encrypted code, useful for organizing multiple encryption sources.\nMinInstructionCount | Integer | Sets the minimum threshold for the number of method instructions required for the rule to be applied.\nMaxInstructionCount | Integer | Sets the maximum threshold for the number of method instructions allowed for the rule to be applied.\noptimizations"},{"page":21,"heading":"Rule Element","anchor":"rule-element","text":"Property | Type | Description\nClassSealing | Boolean | When enabled, applies class sealing optimization by marking classes as sealed (final) when they have no derived types, improving performance.\nConstRemoval | Boolean | When enabled, removes constant field metadata, replacing references with literal values directly in the code.\nDisgregateRemoval | Boolean | When enabled, removes properties and events metadata, reducing the assembly's metadata footprint.\nEnumRemoval | Boolean | When enabled, removes enum type definitions, replacing them with their underlying integral types.\nUnwantedAttributes | Boolean | When enabled, removes unwanted custom attributes that may expose implementation details or debugging information.\nDescription Element\nProvides a descriptive text explanation of the rule's purpose and behavior. This description will be displayed in the obfuscation log, making it easier to understand what each rule does when reviewing the obfuscation process."},{"page":21,"heading":"Configuring Rules","anchor":"configuring-rules","text":"You can pass rules files to Babel Obfuscator from the command line, the MSBuild Babel task, or Babel Desktop. Pick the one that fits your build.\nCommand Line\nbabel myapp.exe --rules babelRules.xml\nThe --rules option can be specified multiple times on the command line to include additional XML rules files. This allows you to organize rules into separate files and combine them as needed.\nMSBuild Babel Task\n<ItemGroup>\n  <RuleFile Include=\"babelRules.xml\" />\n</ItemGroup>\n\n<Babel RulesFiles=\"@(RuleFile)\" />\nThe RulesFiles option in Babel Obfuscator accepts a list of XML rules files, which can be defined using the ItemGroup element in your MSBuild project file. This approach allows multiple rule files to be specified and easily managed within the project structure. Each rule file listed in the item group is treated as a separate input for Babel Obfuscator and can be used to specify different obfuscation rules and settings for different parts of your codebase.\nIn addition to using external XML rules files, you can embed the XML rules definition directly inside the project file by using the XmlRules attribute of the Babel task, as shown below:"},{"page":21,"heading":"Configuring Rules","anchor":"configuring-rules","text":"<PropertyGroup>\n  <XmlRules>\n    <Rules targetAssembly=\"Acme, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f66185f16ea61c16\">\n      <Rule name=\"rule1\" feature=\"msil encryption\" exclude=\"false\">\n        <Target>Methods</Target>\n        <Pattern>Acme.Engine*</Pattern>\n        <Description>Enable MSIL Code Encryption in Acme Engine</Description>\n      </Rule>\n    </Rules>\n    <Rules targetAssembly=\"Acme.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f66185f16ea61c16\">\n      <Rule name=\"rule2\" feature=\"control flow\" exclude=\"true\">\n        <Target>Methods</Target>\n        <Pattern>Acme.Entities.*</Pattern>\n        <Description>Disable Control Flow Obfuscation for EF classes</Description>\n      </Rule>\n    </Rules>\n  </XmlRules>\n</PropertyGroup>\n\n<Babel XmlRules=\"$(XmlRules)\" />\nWhen using Babel Obfuscator to process multiple target assemblies in a project, you can specify which target assembly a set of rules should be applied to by using the targetAssembly attribute in the XML rules. This attribute allows you to target a specific assembly by its fully qualified name, including version, culture, and public key token. If the targetAssembly attribute is omitted, the rules will be applied to all target assemblies defined in the project.\nBabel Desktop\nTo use external XML rules files, select the target assembly on the project canvas and add the files to RulesFiles in the Files & dependencies group of the properties panel."},{"page":21,"heading":"Configuring Rules","anchor":"configuring-rules","text":"To write rules inline, open the XML rules view of the selected assembly (the XML rules tab of the properties panel, or Settings > Selected assembly > XML rules). The editor validates the rules against the Babel XML schema and reports errors with their line and column, and it can open and save rules documents as XML files.\nInline rules are stored in the project file, in the XmlRules property of the Babel task, as in the MSBuild example above, so they are saved and version-controlled together with the project configuration. See Obfuscation Projects for how to work with projects in Babel Desktop."},{"page":22,"heading":"","anchor":"","text":"To tailor the Babel Obfuscator's obfuscation process, users can craft their own XML rules. These guidelines dictate how the obfuscator interacts with particular classes, methods, and properties, among others. Offering detailed control, these rules enable users to refine the obfuscator's results. This section presents several examples of XML rules for Babel Obfuscator."},{"page":22,"heading":"Disable Class Renaming","anchor":"disable-class-renaming-","text":"To disable renaming for a given class using Babel Obfuscator's XML rules, you can use the following XML rule:\n<Rule name=\"disable-myclass-renaming\" feature=\"renaming\" exclude=\"true\" \n      applyToMembers=\"true\">\n  <Target>Classes</Target>\n  <Pattern>MyNamespace.MyClass</Pattern>\n  <Description>Disable renaming for MyClass.</Description>\n</Rule>\nNote:\nReplace MyNamespace.MyClass with the fully qualified name of the class you want to exclude from renaming.\nThe feature attribute is set to \"renaming\" to target the renaming feature.\nThe exclude attribute is set to \"true\" to prevent renaming for the specified class.\nThe applyToMembers is set to \"true\" to prevent the renaming of class members.\nThe Target element specifies that the rule applies to classes.\nThe Pattern element specifies the fully qualified name of the class."},{"page":22,"heading":"Compiled Generated Code","anchor":"compiled-generated-code","text":"The following rule will prevent some enhanced obfuscation features for compiler-generated code.\n<Rule name=\"no-compiler-generated\" \n      feature=\"control flow, value encryption, string encryption\" \n      exclude=\"true\" applyToMembers=\"false\">\n  <Target>Classes</Target>\n  <Pattern>*</Pattern>\n  <HasAttribute onEnclosingType=\"false\">\n    System.Runtime.CompilerServices.CompilerGeneratedAttribute,\n    System.Diagnostics.DebuggerHiddenAttribute\n  </HasAttribute>\n  <Description>Do not obfuscate compiler-generated methods.</Description>\n</Rule>"},{"page":22,"heading":"Anonymous Types","anchor":"anonymous-types","text":"In C#, an anonymous type is a type that is defined without a name using the new operator together with an object initializer.\nvar query =\n    from prod in products\n    select new { prod.Name, prod.Price };\n\nforeach (var v in query)\n{\n    Console.WriteLine(\"Name={0}, Price={1}\", v.Name, v.Price);\n}\nThis allows for creating objects on the fly without the need to define a specific type beforehand. The compiler generates a type name for the anonymous type, which typically starts with the characters <>f__Anonymous. The generated name is unique and is not meant to be used by the developer.\nAnonymous types are used extensively in LINQ queries and other scenarios like ASP.NET web applications where the creation of objects on the fly is required.\nIn the context of obfuscation, anonymous types can pose a challenge as their generated names could be obfuscated. Renaming them may cause issues with the code that uses them, so it is often recommended to exclude them from obfuscation.\nOne way to achieve this is by adding the rule targeting any symbol with the attribute\nSystem.Runtime.CompilerServices.CompilerGeneratedAttribute\nto exclude all compiler-generated code, including anonymous types.\n<Rule name=\"rule1\" feature=\"renaming, dead code\" exclude=\"true\" applyToMembers=\"true\">\n  <Pattern>*</Pattern>\n  <HasAttribute>System.Runtime.CompilerServices.CompilerGeneratedAttribute</HasAttribute>\n</Rule>"},{"page":22,"heading":"Anonymous Types","anchor":"anonymous-types","text":"Another option is to use a regular expression pattern to match the name of any inline type, as these types typically have the prefix <>f__Anonymous.\n<Pattern isRegEx=\"true\">\n  <![CDATA[<>f__Anonymous.*]]>\n</Pattern>\nBy checking the name of the anonymous type in any .NET assembly inspector like ILSpy or dotPeek, you can verify if it follows this rule."},{"page":22,"heading":"Using Dynamic Proxy Calls Filters","anchor":"using-dynamic-proxy-calls-filters","text":"Dynamic Proxy Call Filters provide a valuable tool within Babel Obfuscator to fine-tune Dynamic Proxy generation and achieve the desired level of obfuscation while maintaining optimal performance (see Dynamic Proxy).\n<Rule name=\"rule1\" feature=\"dynamic proxy\" exclude=\"false\" applyToMembers=\"true\">\n  <Pattern>*</Pattern>\n  <Description>Set Dynamic Proxy Call Filters</Description>\n  <Properties>\n    <DynamicProxyCallFilters>IEnumerator.*;ICollection.*</DynamicProxyCallFilters>\n  </Properties>\n</Rule>\nThe provided XML rule represents a configuration in Babel to set Dynamic Proxy Call Filters.\nBy setting Dynamic Proxy Call Filters, you can precisely define which method calls should be intercepted and replaced with dynamic proxies. This allows you to protect critical sections of your code while leaving others untouched. With the ability to specify regular expressions for the filters, you have the flexibility to tailor the rule to match specific method naming patterns or behaviours that require dynamic proxying. This allows you to adapt the obfuscation and protection strategies based on your application's unique requirements."},{"page":22,"heading":"Controlling Obfuscation Agent","anchor":"controlling-obfuscation-agent","text":"The Obfuscation Agent in Babel Obfuscator is responsible for executing a series of tasks during the obfuscation process based on predefined rules. Its primary purpose is to prevent potential issues that obfuscation might introduce, which could break the resulting assembly. For instance, the Agent ensures that symbols used in reflection aren't obfuscated because doing so could lead to runtime errors. The tasks performed by the Agent can range from simple checks, like examining fields of serializable types, to more complex operations involving MSIL code static analysis.\nWhile the Obfuscation Agent is crucial for ensuring the smooth functioning of obfuscated code, there might be scenarios where developers want to achieve specific obfuscation results that require disabling certain Agent tasks.\nTo skip specific Agent tasks using XML rules, developers can define an exclude rule targeting the agent feature. For instance, to disable tasks like \"Serializable types\" and \"Reflected strings\", an XML rule would look like:\n<Rule name=\"rule1\" feature=\"agent\" exclude=\"true\">\n    <Pattern>ACME.Data.*</Pattern>\n    <Properties>\n        <TaskNameList>Serializable types;Reflected strings</TaskNameList>\n    </Properties>\n</Rule>"},{"page":22,"heading":"Controlling Obfuscation Agent","anchor":"controlling-obfuscation-agent","text":"In conclusion, while the Obfuscation Agent plays a pivotal role in ensuring that obfuscated code operates without hitches, there are situations where developers might need to disable specific tasks to achieve their desired obfuscation outcomes. It's essential to approach this with caution, understanding the implications of each disabled task on the final application."},{"page":23,"heading":"","anchor":"","text":"Babel supports declarative obfuscation using the custom attributes System.Reflection.ObfuscationAttribute and System.Reflection.ObfuscateAssemblyAttribute provided by the .NET Framework and .NET."},{"page":23,"heading":"The ObfuscateAssembly Attribute","anchor":"the-obfuscateassembly-attribute","text":"The System.Reflection.ObfuscateAssemblyAttribute, is an assembly-level attribute that instructs Babel Obfuscator to use obfuscation rules reserved for private assemblies.\nA private assembly is an assembly that will not be used as a library: no other software components will use the assembly. Babel fully obfuscates private assemblies_,_ which will rename all public symbols.\n[assembly: ObfuscateAssembly(true)]\nThe Boolean constructor argument assemblyIsPrivate=true tells Babel that the assembly is used within the scope of one application and the public interface can be safely renamed."},{"page":23,"heading":"The Obfuscation Attribute","anchor":"the-obfuscation-attribute","text":"The System.Reflection.ObfuscationAttribute attribute can be used on assembly members like types, methods, events, properties and fields to configure the action taken for a specific obfuscation feature.\nThe Obfuscation attribute has the following properties:\nFeature\nThe Feature property maps a string value to a specific obfuscator feature or a list of features. The default value for the Feature property is “all”.\nInfo: Babel uses \"all\" to map the complete set of available features. and \"default\" to map the renaming feature.\nPlease refer to the obfuscation feature table to know more.\nExclude\nIndicates whether the obfuscation feature should be excluded for the associated member.\nApplyToMembers\nSpecifies whether the action taken by the obfuscator for the associated type should be applied to all its members.\nStripAfterObfuscation\nSpecifies whether the attribute should be removed after processing.\nThe following code example shows how ObfuscationAttribute can be used to target a method to enable code encryption:\n[Obfuscation(Feature=\"msil encryption\", Exclude=false)]\npublic string DoSomething()\n{\nExtended Feature Syntax\nBabel Obfuscator supports an extended syntax for feature strings that will allow setting feature properties as a list of key-value pairs after the name of each feature.\n[Obfuscation(Feature=\"msil encryption:source=opt;cache=true\", Exclude=false)]#"},{"page":23,"heading":"The Obfuscation Attribute","anchor":"the-obfuscation-attribute","text":"The extended Feature syntax will allow setting the ObfuscationAttribute at the assembly level to configure features for the entire assembly:\nRenaming\n[assembly: Obfuscation(Feature=\"renaming:flatten namespaces=ACME.Test.*\", Exclude=false)]\n[assembly: Obfuscation(Feature=\"renaming:flattenNamespaces=ACME.Data.*\", Exclude=false)]\n[assembly: Obfuscation(Feature=\"renaming:internalize=true;rename parameters=true\", Exclude=false)]\n[assembly: Obfuscation(Feature=\"renaming:overloaded=true;unicode=false\", Exclude=false)]\n[assembly: Obfuscation(Feature=\"renaming:name length=5;name prefix=Acme_\", Exclude=false)]\nObfuscation Agent\nDisable the obfuscation Agent for Serializable types and Reflected enum tasks.\n[assembly: Obfuscation(Feature=\"agent:tasknamelist=Serializable types,Reflected enums\", Exclude=true)]\nValue Encryption\nEncrypts values and arrays of methods having several instructions between 10 and 100.\n[assembly: Obfuscation(Feature=\"value encryption:min instruction count=10; max instruction count=100\", Exclude=false)]\nWarning: The Obfuscation attribute alone is not sufficient to activate the chosen feature. The attribute can only function if the feature is globally enabled in the configuration.\nOther Examples\nDo not obfuscate compiler-generated code.\n[assembly: Obfuscation(Feature=\"all:compilergenerated=true\", Exclude=true)]"},{"page":24,"heading":"","anchor":"","text":"During the obfuscation process, Babel can perform a series of tasks based on a set of pre-defined rules, known as the Obfuscation Agent.\nThe Agent is designed to avoid common issues that can be introduced by obfuscation and which could potentially break the resulting assembly. For example, the Agent can ensure that certain symbols, such as those used in reflection, are not obfuscated. This is because the obfuscation of these symbols can cause issues with the runtime environment and result in errors or crashes.\nTo accomplish this, the Agent performs a series of tasks against the target assembly. These tasks are preconfigured and can vary in complexity, with some being straightforward, such as checking fields of serializable types, while others involving more advanced techniques, such as MSIL code static analysis.\nHere is the list of available Agent task names in Babel Obfuscator"},{"page":24,"heading":"","anchor":"","text":"Task Name | Description\nBase types | Prevents renaming of types derived from a specified base type\nCode analysis | Prevents renaming of types reserved to code analysis\nDynamic language | Prevents renaming symbols used by the dynamic language runtime\nExposed attributes | Prevents renaming of symbols that expose specific attributes\nRazor webapp | Handle obfuscation of Razor webapp\nReflected enums | Prevents renaming of enum types consumed by reflection\nReflected strings | Prevents obfuscation of strings consumed by reflection\nReflected types | Prevents renaming of types consumed by reflection\nSerializable types | Prevents renaming of serializable types\nWinRT types | Prevents renaming of WinRT private types\nThe Obfuscation Agent's tasks are continuously updated with each new product release. This ensures that Babel is always up to date with the latest CLR design rules and can accurately determine which symbols should and should not be obfuscated.\nBy following these pre-defined rules, Babel Obfuscator can ensure that the obfuscated code remains fully functional and free from issues that could potentially break the application.\nOverall, the Obfuscation Agent is a critical component of Babel that helps ensure the protection of .NET applications by preventing symbol names from being obfuscated in violation of CLR design rules."},{"page":24,"heading":"Overriding Agent Rules","anchor":"overriding-agent-rules","text":"The Obfuscation Agent is enabled by default and should be left enabled whenever possible to ensure that obfuscation is performed correctly. Disabling the Agent is generally not recommended because it can cause issues with the runtime environment and result in errors or application crashes. However, in some cases, users may want to disable certain Agent tasks to achieve specific obfuscation results.\nIt's important to note that the Agent tasks run after the Rules processing phase. This means that any custom XML rule not enforced on a member will be overridden by the Agent task. Therefore, users should carefully consider the impact of disabling or customizing Agent tasks before making any changes to the default settings.\nIt is possible to skip a specific Agen task using XML Rules. This can be accomplished by defining an exclude rule targeting the agent feature that specifies the task names to skip in the TaskNameList element as a child of the rule Properties element. This will prevent the specified tasks from being run during obfuscation.\nFor example, to disable the Serializable types and Reflected strings tasks, you would define an XML rule like this:\n<Rule name=\"rule1\" feature=\"agent\" exclude=\"true\">\n  <Pattern>ACME.Data.*</Pattern>\n  <Properties>\n    <TaskNameList>Serializable types;Reflected strings</TaskNameList>\n  </Properties>\n</Rule>"},{"page":24,"heading":"Overriding Agent Rules","anchor":"overriding-agent-rules","text":"In this rule targeting the \"agent\" feature, the exclude attribute is set to \"true\", which tells Babel Obfuscator not to run the Serializable types and Reflected strings agent tasks when processing the assembly.\nDisabling a task from running is not always feasible because it can lead to unexpected runtime issues. Therefore one way to achieve the obfuscation outcome of a specific symbol is using an XML rule that can be enforced by setting the \"locked\" attribute to \"true\", which prevents the agent from overriding it.\n<Rule name=\"rule1\" feature=\"renaming\" exclude=\"false\" locked=\"true\">\n  <Target>Classes</Target>\n  <Pattern>ACME.Data.*</Pattern>  \n  <Description>Force renaming of all types in ACME.Data namespace, \n     including serializable ones.\n  </Description>\n</Rule>\nThis rule will enforce renaming for all the classes inside the ACME.Data namespace, including all serializable types."},{"page":25,"heading":"","anchor":"","text":"Babel Obfuscator provides the capability to merge and embed multiple .NET assemblies into a single target assembly. By merging and embedding the required assemblies into a single file, it simplifies the application deployment process, making it easier to distribute and install the application. Additionally, merging assemblies into the target assembly can increases the protection level, making it more difficult for attackers to reverse-engineer the application code."},{"page":26,"heading":"","anchor":"","text":"You can merge assemblies with the babel command line tool, the MSBuild Babel task, or Babel Desktop.\nWarning: Avalonia applications cannot be merged. Avalonia compiles each assembly's XAML into per-assembly CompiledAvaloniaXaml types and a single !AvaloniaResources blob, and resolves assets through avares://<AssemblyName>/… URIs keyed by assembly identity. Merging the XAML-bearing assemblies collides those types and resources and breaks avares:// resolution at runtime. To ship an Avalonia application as a single file, use assembly embedding instead, which preserves each assembly's identity."},{"page":26,"heading":"Merging From Command Line","anchor":"merging-from-command-line","text":"Using the babel tool, you can merge assemblies by specifying the target assembly followed by the list of assembly files to be merged with the primary assembly as well as any other configuration options:\nbabel <primary assembly source> [<other assemblies>...] [options]\nThe Babel Obfuscator provides several options to configure assembly merging.\n--[no]copyattrs [regex]\nThis option allows users to specify whether Babel should copy assembly-level attributes into the primary assembly. It is also possible to specify an optional regular expression to match the attribute's full name that should be merged. Users can enter multiple --copyattrs commands to specify several attribute filters. To disable copying assembly-level attributes, users can enter the --nocopyattrs command.\nIf assembly-level attributes are copied, users can use XML rules to filter the attributes to be copied or excluded using the CopyAttributes and NoCopyAttributes properties, which take a regular expression to match the assembly-level attribute full type name:\n<Rule name=\"merge attributes\" feature=\"merge\" exclude=\"false\">\n  <Target>Assembly</Target>\n  <Pattern>*</Pattern>\n  <Properties>\n    <NoCopyAttributes>.*TypeLibVersion</NoCopyAttributes>\n  </Properties>\n</Rule>"},{"page":26,"heading":"Merging From Command Line","anchor":"merging-from-command-line","text":"The CopyAttributes filter expression is used to selectively include assembly-level attributes in the merged assembly based on their fully qualified attribute type name. In other words, only the attributes that match the filter expression will be merged into the target assembly, while all others will be excluded.\nOn the other hand, the NoCopyAttributes filter expression is used to selectively exclude assembly-level attributes from the merged assembly based on their fully qualified attribute type name. This means that all attributes that match the filter expression will not be merged into the target assembly, while all others will be included.\n--[no]internalize:\nWhen enabled, it modifies the visibility of all the merged assembly types from public to internal.\nInfo: Changing the type visibility can prevent merged types from being consumed outside the primary assembly, so this option should only be enabled if the merged types are intended to be used only by the primary assembly."},{"page":26,"heading":"Merging From MSBuild Babel Task","anchor":"merging-from-msbuild-babel-task","text":"To merge assmebies using the Babel task, you must define an additional ItemGroup element in the MSBuild project file. This ItemGroup contains all the assemblies you want to merge with the primary assembly. The Babel task will then use this ItemGroup to perform the merge during the build process.\nHere is an example of how to define the ItemGroup element\n<ItemGroup>\n  <MergeAssembly Include=\"path/to/assembly1.dll\"/>\n  <MergeAssembly Include=\"path/to/assembly2.dll\"/>\n</ItemGroup>\nIn this example, path/to/assembly1.dll and path/to/assembly2.dll are the paths to the assemblies you want to merge with the primary assembly. You can include as many assemblies as you need in the ItemGroup.\nOnce you have defined the ItemGroup, you can pass it to the Babel task using the MergeAssemblies parameter:\n<Babel MergeAssemblies=\"@(MergeAssembly)\" Internalize=\"true\" />\nThe Internalize attribute specifies whether to change the visibility of merged types from public to internal."},{"page":26,"heading":"Merging From Babel Desktop","anchor":"merging-from-babel-desktop","text":"To merge assemblies using Babel Desktop, follow these steps:\nOpen or create a project\nOpen an existing project or create a new one.\nAdd the assemblies\nAdd the primary assembly and the assemblies to merge to the project canvas.\nConnect the dependencies\nConnect each dependency to the primary assembly: drag from the bottom anchor of the dependency to the top anchor of the primary assembly.\nSet the connection type to Merge\nMake sure the connection type is Merge. New connections select Merge automatically when the primary assembly references the dependency; otherwise click the connection and change its type.\nConfigure the merging options\nSelect the primary assembly to configure the merging options in the properties panel, such as Internalize and CopyAttributes in the Optimization group.\nSee Obfuscation Projects for more about the project canvas."},{"page":27,"heading":"","anchor":"","text":"Babel Obfuscator provides a feature to embed multiple assemblies into the main application, which can reduce the overall size of the deployed assembly. When embedding assemblies with Babel Obfuscator, the embedded assemblies are first encrypted and compressed before being stored as managed resources within the main application assembly.\nError: It is important to note that embedded assemblies are not obfuscated. Therefore, it's recommended only to embed assemblies that do not contain proprietary code or components that are not meant to be protected.\nInfo: Embedding is the recommended way to produce a single-file Avalonia application. Because embedded assemblies keep their original identity, Avalonia's avares://<AssemblyName>/… resource URIs still resolve — unlike merging, which is not compatible with Avalonia.\nTo protect the code as well, obfuscate each dependency first (keeping its public API so cross-assembly references stay intact), then embed the already-obfuscated assemblies:\nbabel MyApp.View.dll --output obf/MyApp.View.dll [obfuscation options]\nbabel MyApp.dll --embed obf/MyApp.View.dll [obfuscation options]"},{"page":27,"heading":"Embedding From Command Line","anchor":"embedding-from-command-line","text":"To embed assemblies from the command line using the Babel tool, you can use the --embed option followed by the assembly file path to embed. You can enter the command multiple times to embed several assemblies.\nbabel MyApp.exe --embed Library1.dll --embed Library2.dll\nThis command will embed Library1.dll and Library2.dll into MyApp.exe. The embedded assemblies will be stored as managed resources within the main assembly.\nYou can also use an XML rules file to specify additional settings, such as compression or encryption. For example, create a file named embed.xml with the following contents:\n<Rules>\n  <Rule name=\"Library1\" feature=\"embed\" exclude=\"false\">\n    <Target>Assembly</Target>\n    <Pattern>Library1.dll</Pattern>\n    <Properties>\n      <Compress>false</Compress>\n    </Properties>\n  </Rule>\n  <Rule name=\"Library2\" feature=\"embed\" exclude=\"false\">\n    <Target>Assembly</Target>\n    <Pattern>Library2.dll</Pattern>\n    <Properties>\n      <Encrypt>false</Encrypt>\n    </Properties>\n  </Rule>\n</Rules>\nThen run the following command to embed the assemblies based on the rules file:\nbabel MyApp.exe --embed Library1.dll --embed Library2.dll --rules embed.xml"},{"page":27,"heading":"Embedding From MSBuild Babel Task","anchor":"embedding-from-msbuild-babel-task","text":"To embed assemblies using the MSBuild Babel task, you need to add a new ItemGroup element in your project file. Inside the ItemGroup, you can define multiple EmbedAssembly items, each one specifying a path to an assembly file to embed. For example:\n<ItemGroup>\n   <EmbedAssembly Include=\"path/to/Assembly1.dll\" />\n   <EmbedAssembly Include=\"path/to/Assembly2.dll\" />\n</ItemGroup>\nYou can reference the EmbedAssembly in the Babel task using the EmbedAssemblies attribute:\n<Babel EmbedAssemblies=\"@(EmbedAssembly)\" RulesFiles=\"embed.xml\" />\nYou can optionally specify a rule file to customize the compression and encryption settings for each embedded assembly. By default, embedded assemblies are compressed and encrypted using Babel's default settings, but a rule file can be used to customize these settings if necessary."},{"page":27,"heading":"Embedding From Babel Desktop","anchor":"embedding-from-babel-desktop","text":"To embed assemblies using Babel Desktop, follow these steps:\nOpen or create a project\nOpen an existing project or create a new one.\nAdd the assemblies\nAdd the primary assembly and the assemblies to embed to the project canvas.\nConnect the dependencies\nConnect each dependency to the primary assembly: drag from the bottom anchor of the dependency to the top anchor of the primary assembly.\nSet the connection type to Embed\nClick the connection and set its type to Embed. New connections default to Merge when the primary assembly references the dependency, otherwise to Reference.\nConfigure compression and encryption\nConfigure the compression and encryption of the embedded assemblies with XML rules in the XML rules view of the primary assembly.\nSee Obfuscation Projects for more about the project canvas."},{"page":28,"heading":"","anchor":"","text":"Babel Obfuscator can rename namespaces, types, methods, properties, events, and fields, making reverse engineering challenging. By default, it uses ASCII for renaming, but you can opt for Unicode for more unreadable symbols.\nBabel automatically renames internal symbols, but not those visible to other assemblies. Thus, private and internal symbols are renamed, while public and protected members remain unchanged unless custom rules are applied to enforce renaming.\nIt's important to note that renaming public symbols can potentially break the public interface of the component, as external code may depend on the specific names of those symbols. It is generally recommended to avoid renaming externally visible symbols and instead focuses on obfuscating internal implementation details.\nInfo: If a symbol is not meant to be used externally, it should be declared as internal, which will ensure that it is not visible outside of the assembly and will not be part of the public interface.\nBy lowering the visibility of public types to internal, you can increase the overall number of members obfuscated while still preserving the public interface of the component."},{"page":28,"heading":"Configuring Symbols Renaming","anchor":"configuring-symbols-renaming","text":"You can configure renaming in Babel Desktop, from the command line or with the MSBuild task.\nBabel Desktop\nTo configure renaming in Babel Desktop, open or create a project, select the assembly on the project canvas and set the options in the Renaming group of the properties panel. The group holds the type and member flags (ObfuscateTypes, ObfuscateMethods, ObfuscateProperties, ObfuscateEvents, ObfuscateFields, ObfuscateParameters), namespace flattening (FlattenNamespaces), Unicode names (UnicodeNormalization), name length and prefix (NameLength, NamePrefix) and overloaded renaming (OverloadedRenaming). See Obfuscation Projects for how projects work in Babel Desktop.\nCommand Line\nConfiguring renaming in Babel Obfuscator via the Command Line Interface (CLI) offers a powerful and flexible approach for integrating obfuscation into your build process if you are using CLI scripts.\nTo configure renaming in Babel Obfuscator, from the Command Prompt on Windows or Terminal on macOS or Linux, navigate to where your project is located and enter:\nbabel myapp.exe --types --methods --properties --events --fields --parameters\nHere myapp.exe should be replaced with the name of your built assembly that you intend to obfuscate. The following CLI switches indicate the types of symbols you wish to rename."},{"page":28,"heading":"Configuring Symbols Renaming","anchor":"configuring-symbols-renaming","text":"Each switch (--types, --methods, etc.) enables renaming for that specific category of symbols within your assembly. By including these switches, you're instructing Babel Obfuscator to apply renaming to types, methods, properties, events, fields, and parameters. If you need to exclude a specific category from renaming, you use the --no prefix with the symbol type. For example, to disable renaming for types, you would use --notypes. This can be done for any symbol type to customize which elements are obfuscated.\nTo access command line help for specific renaming switches, enter the following command\nbabel --help types\nThis will display detailed help information for the --types switch.\nMSBuild Babel Task\nThe MSBuild Babel Task seamlessly integrates Babel Obfuscator into your build workflow, granting fine-grained control over obfuscation preferences. This capability enables you to precisely designate which elements of your code are to be obfuscated, tailoring the obfuscation process to meet your specific needs."},{"page":28,"heading":"Configuring Symbols Renaming","anchor":"configuring-symbols-renaming","text":"<PropertyGroup>\n  <ObfuscateTypes>true</ObfuscateTypes>\n  <ObfuscateMethods>true</ObfuscateMethods>\n  <ObfuscateProperties>true</ObfuscateProperties>\n  <ObfuscateEvents>true</ObfuscateEvents>\n  <ObfuscateFields>true</ObfuscateFields>\n  <ObfuscateParameters>true</ObfuscateParameters>\n</PropertyGroup>\n\n<Babel ObfuscateTypes=\"$(ObfuscateTypes)\" ObfuscateMethods=\"$(ObfuscateMethods)\" ObfuscateProperties=\"$(ObfuscateProperties)\" ObfuscateEvents=\"$(ObfuscateEvents)\" ObfuscateFields=\"$(ObfuscateFields)\" ObfuscateParameters=\"$(ObfuscateParameters)\" />"},{"page":28,"heading":"Name Prefix","anchor":"name-prefix","text":"Babel Obfuscator allows you to apply a name prefix to every generated symbol name. You can specify the prefix to be applied to a particular kind of symbol, such as types, methods, properties, events, fields or parameters. The prefix can be specified using the --nameprefix or --prefix followed by the desired prefix string. Additionally, you can specify the kind of symbol that the prefix should be applied to by using the syntax --prefix [kind]=[prefix]\nInfo: Babel accepts the prefix $name, which will be replaced with the original symbol name during renaming. This can be helpful for debugging purposes or to identify issues that might arise due to renaming.\nCommand Line\nbabel myapp.exe --prefix xy_ --prefix types=tp_ --prefix fields=m_\nTo learn more about name prefix command line switch enter:\nbabel --help prefix\nMSBuild Babel Task\n<PropertyGroup>\n  <NamePrefix>xy_;types=tp_;fields=m_</NamePrefix>\n</PropertyGroup>\n\n<Babel NamePrefix=\"$(NamePrefix)\" />"},{"page":28,"heading":"Name Length","anchor":"name-length","text":"In Babel Obfuscator, you can specify the minimum length of the generated obfuscated names by using the --namelength option followed by the desired length. This can be useful if you want to ensure that the obfuscated names are of a certain length. Additionally, you can specify the kind of symbol that the name length should be applied to by using the syntax --namelength [kind]=[value]\nCommand Line\nbabel myapp.exe --namelength 3 --namelength types=8\nTo learn more about name length command line switch enter:\nbabel --help namelength\nMSBuild Babel Task\n<PropertyGroup>\n  <NameLength>3;types=8</NameLength>\n</PropertyGroup>\n\n<Babel NameLength=\"$(NameLength)\" />"},{"page":28,"heading":"Unicode Character Set","anchor":"unicode-character-set","text":"Babel allows you to specify the Unicode character set to be used when generating obfuscated names. You can use comma-separated values of Unicode characters or ranges of characters represented in hexadecimal, decimal, or character form.\nCommand Line\nbabel myapp.exe --unicode 10,13,a-z,0x4E00-0x4FFF\nTo disable unicode renaming enter:\nbabel myapp.exe --nounicode\nMSBuild Babel Task\n<PropertyGroup>\n    <UnicodeNormalization>10,13,a-z,0x4E00-0x4FFF</UnicodeNormalization>\n</PropertyGroup>\n\n<Babel UnicodeNormalization=\"$(UnicodeNormalization)\" />"},{"page":28,"heading":"Flatten Namespaces","anchor":"flatten-namespaces","text":"When Flatten Namespace is enabled, Babel will remove all namespace information from the obfuscated assembly and move all renamed types into the global namespace. This makes it more difficult for an attacker to understand the organization of the code and to locate specific types or members within the assembly.\nOptionally, you can specify the name of the namespace Babel will use as a global container for all renamed types.\nInfo: Note that in Babel, only renamed types will have their namespace name updated according to the flat namespace settings.\nCommand Line\nbabel myapp.exe --flatns\nbabel myapp.exe --flatns glbns\nTo disable namespace flattening enter:\nbabel myapp.exe --noflatns\nMSBuild Babel Task\n<PropertyGroup>\n    <FlattenNamespaces>true</FlattenNamespaces>\n</PropertyGroup>\n\n<Babel FlattenNamespaces=\"$(FlattenNamespaces)\" />"},{"page":28,"heading":"Overloaded Renaming","anchor":"overloaded-renaming","text":"Overloaded renaming is a technique used by Babel to rename methods with different signatures using the same name, as long as it is allowed by the .NET Framework design rules. This makes it harder for a hacker to understand and reverse engineer the code. Additionally, Babel renames overloads even when only the method return type differs, which makes it impossible to fully decompile the code to high-level languages like C# and VB.NET since overloading the return type is not allowed in these languages.\nCommand Line\nbabel myapp.exe --overloaded\nTo disable overloaded renaming enter:\nbabel myapp.exe --nooverloaded\nMSBuild Babel Task\n<PropertyGroup>\n    <OverloadedRenaming>true</OverloadedRenaming>\n</PropertyGroup>\n\n<Babel OverloadedRenaming=\"$(OverloadedRenaming)\" />"},{"page":28,"heading":"Virtual Functions","anchor":"virtual-functions","text":"Babel can obfuscate virtual functions by renaming them in a way that preserves their virtual nature. This means that the original virtual function table (vtable) layout is maintained, even after obfuscation. This is important to ensure that the program continues to function correctly since virtual functions are a critical part of many object-oriented programs. By obfuscating virtual functions, Babel can make it more difficult for attackers to understand the program's behaviour and exploit vulnerabilities.\nCommand Line\nbabel myapp.exe --virtuals\nTo disable virtual functions obfuscation enter:\nbabel myapp.exe --novirtuals\nMSBuild Babel Task\n<PropertyGroup>\n    <VirtualFunctions>true</VirtualFunctions>\n</PropertyGroup>\n\n<Babel VirtualFunctions=\"$(VirtualFunctions)\" />"},{"page":28,"heading":"Renaming Local Variables","anchor":"renaming-local-variables","text":"In .NET metadata, local variable names are not explicitly stored. Instead, they are inferred by decompilers based on various factors. For example, when a variable's type is explicitly specified, such as in the case of\nvar list1 = new List<string>();\nthe decompiler can determine the variable name as \"list1\" based on the assignment statement.\nAlternatively, local variable names can be loaded from the assembly Program Database (PDB) file. The PDB file contains additional debugging information, including variable names, which can be utilized by decompilers to reconstruct the original names.\nTo mitigate the exposure of local variable names, Babel Obfuscator offers the option to enable Dynamic Proxy generation for external types.\nbabel myapp.exe --proxy external\nThis feature wraps the original types, like List<string>, in proxy types that are renamed, effectively hiding the variable types.\nIt is essential to ensure that the decompiler being used does not load the PDB file, as this would enable it to reconstruct the original variable names. By disabling PDB loading or deleting the PDB file, the decompiler will have limited access to the debugging information."},{"page":28,"heading":"Renaming Local Variables","anchor":"renaming-local-variables","text":"For comprehensive protection of method code, it is recommended to enable Code Encryption whenever possible. Code encryption transforms the method code into an encrypted form, making it significantly more challenging for reverse engineers to understand or modify the code, even if they manage to retrieve the original variable names."},{"page":29,"heading":"","anchor":"","text":"During the obfuscation process, Babel Obfuscator renames all the symbols that are not externally visible to the assembly, which includes private and internal symbols. This means that Babel will change the names of fields, methods, classes, and other code elements that are not meant to be accessed outside of the assembly.\nBabel will not rename symbols externally visible to the assembly, such as public symbols. This is because public symbols are meant to be accessed by other assemblies, and renaming them would break the application's functionality. Therefore, Babel only renames the symbols not meant to be accessed by other assemblies, ensuring that the application still works as intended.\nHowever, Babel provides the ability to obfuscate both public and internal members across multiple assemblies. This is accomplished by fixing the names of the obfuscated symbols referenced in each assembly using XML map files.\nThis is because when an assembly is obfuscated, the names of its symbols are changed. Thus, any reference to these symbols made by another assembly must be updated to reflect the new names. By specifying these input and output XML map files, Babel Obfuscator can use them to fix cross-name references between all participating assemblies. This ensures that the obfuscated code works correctly and does not break due to incorrect symbol names."},{"page":29,"heading":"","anchor":"","text":"Warning: It is important to keep map files private and not deploy them with the obfuscated application under any circumstances, as they can be used to reverse engineer the obfuscation and compromise the security of the application."},{"page":29,"heading":"Setup Cross Assembly Renaming","anchor":"setup-cross-assembly-renaming","text":"To setup cross assembly renaming we have to consider all the assemblies that partecipate to renaming process. Consider the main assembly application MainAssembly.dll which consumes the public interface of two external components: Library1.dll and Library2.dll. Where Library1.dll also need to access Library2.dll public interface according to the following scheme:\nMainAssembly.dll\nLibrary1.dll\nLibrary2.dll\nLibrary1.dll\nLibrary2.dll\nThis configuration highlights the relationships between the assemblies involved in the obfuscation process. The first step is to configure Babel to obfuscate the public symbols in Library1.dll and Library2.dll. You can achieve this by adding the following assembly-level custom attribute to the source code of both libraries:\n[assembly: System.Reflection.ObfuscateAssembly(true)]\nThis attribute instructs Babel to obfuscate the public symbols of the specified assembly without the need for external XML rule files. Setting the Boolean parameter to true ensures that the assembly’s public interface is treated as private, allowing public member names to be safely obfuscated.\nAlternatively, you can configure Babel to rename the public interface of an assembly using an XML rules file. This method provides greater flexibility and control, allowing you to selectively obfuscate parts of the public interface. Below is an example of an XML rule file named public.xml that forces the obfuscation of all public member names:"},{"page":29,"heading":"Setup Cross Assembly Renaming","anchor":"setup-cross-assembly-renaming","text":"<Rules>\n  <Rule name=\"obfuscate public\" exclude=\"false\">\n    <Access>Public</Access>\n    <Pattern isRegEx=\"false\">*</Pattern>\n    <Description>Obfuscate all public symbols.</Description>\n  </Rule>\n</Rules>\nCompared to the ObfuscateAssembly attribute, the XML rule approach offers more granular control over which public symbols to obfuscate. Using the Pattern expression, you can specify which parts of the public interface should be obfuscated, allowing for tailored obfuscation strategies.\nAt this point, we have Library1.dll and Library2.dll configured to use either the ObfuscateAssembly attribute or the XML rule file (in this case, public.xml)\nMainAssembly.dll\nLibrary1.dll (configured with public.xml)\nLibrary2.dll (configured with public.xml)\nFor each assembly that has been configured to rename its public interface, we need to enable the generation of an XML map file.\nThis file contains the mapping between the original symbol names and their obfuscated counterparts. The XML map file will be utilized by all assemblies participating in the obfuscation process that reference at least one assembly with a renamed public interface. This ensures proper name resolution across the obfuscated assemblies.\nTo obfuscate Library1.dll and Library2.dll, we use the following CLI syntax:\nbabel Library2.dll --rules public.xml --mapout"},{"page":29,"heading":"Setup Cross Assembly Renaming","anchor":"setup-cross-assembly-renaming","text":"This first command obfuscates Library2.dll and generates an XML map file named Library2.map.xml, which contains the mapping between original symbol names and the obfuscated names.\nSince Library1.dll references Library2.dll and consumes its public interface, when obfuscating Library1.dll, we must provide the Library2.map.xml file as input to ensure proper mapping of Library2.dll’s obfuscated symbols. Additionally, as we want to obfuscate the public interface of Library1.dll, we configure Babel to load the public.xml rule file and generate a corresponding XML map file for Library1.dll.\nThe CLI command for this step is as follows:\nbabel Library1.dll --rules public.xml --mapout --mapin Library2.map.xml\nThis ensures that Library1.dll correctly references the obfuscated symbols from Library2.dll, while also generating its own map file for subsequent use in the obfuscation process.\nFinally, to obfuscate MainAssembly.dll, we need to configure Babel to load the XML map files for both Library1.dll and Library2.dll, as these assemblies are referenced by MainAssembly. This ensures that MainAssembly can correctly resolve the obfuscated symbols from its dependent libraries during the obfuscation process.\nThe CLI command for this step is:\nbabel MainAssembly.dll --mapin Library1.map.xml --mapin Library2.map.xml"},{"page":29,"heading":"Setup Cross Assembly Renaming","anchor":"setup-cross-assembly-renaming","text":"This command takes in the previously generated map files (Library1.map.xml and Library2.map.xml) to ensure that the references to the obfuscated symbols in these libraries are properly handled in MainAssembly.\nIt’s crucial to follow the correct order when obfuscating assemblies. Libraries referenced by other assemblies, such as Library2.dll and Library1.dll, must be obfuscated first to generate the necessary map files. Then, dependent assemblies like Library1.dll and MainAssembly.dll can be obfuscated using the map files."},{"page":29,"heading":"Setup From MSBuild Task","anchor":"setup-from-msbuild-task","text":"To configure cross-assembly renaming with MSBuild, it is necessary to specify the input and output XML map files for each assembly involved in the obfuscation project including the XML rule file. Each obfuscated assembly must generate an XML map file, which will then be provided as input to all other obfuscated assemblies that reference this target assembly.\nHere's an example of how to configure cross-assembly renaming between one main assembly and two referenced assemblies arranged according to the following scheme.\nMainAssembly.dll\nLibrary1.dll\nLibrary2.dll\nLibrary1.dll\nLibrary2.dll\nWe begin with the Library2 project, which has no dependencies. Since it doesn’t rely on any other assemblies, it can be obfuscated independently without requiring any input XML map files.\nLibrary2 Assembly Project\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <GenerateMapOutFile>true</GenerateMapOutFile>\n  </PropertyGroup>\n\n  <Target Name=\"Obfuscate\" AfterTargets=\"CoreCompile\">\n    <ItemGroup>\n      <RulesFile Include=\"path\\to\\referenced\\public.xml\" />\n    </ItemGroup>\n    <Babel Input=\"$(TargetPath)\" RulesFiles=\"@(RulesFile)\" \n           GenerateMapOutFile=\"$(GenerateMapOutFile)\" />\n  </Target>\n</Project>\nIt is worth noticing that as Library1 references Library2, the obfuscation project, besides generating the XML map file with GenerateMapOutFile=true, must also reference the mapping file generated for Library2.\nLibrary1 Assembly Project"},{"page":29,"heading":"Setup From MSBuild Task","anchor":"setup-from-msbuild-task","text":"<Project Sdk=\"Microsoft.NET.Sdk\">\n  <ItemGroup>\n    <Reference Include=\"path\\to\\referenced\\Library2.dll\" />\n  </ItemGroup>\n  <PropertyGroup>\n    <GenerateMapOutFile>true</GenerateMapOutFile>\n  </PropertyGroup>\n\n  <Target Name=\"Obfuscate\" AfterTargets=\"CoreCompile\">\n    <ItemGroup>\n      <MapInFile Include=\"path\\to\\referenced\\Library2.dll.map.xml\" />\n    </ItemGroup>\n    <ItemGroup>\n      <RulesFile Include=\"path\\to\\referenced\\public.xml\" />\n    </ItemGroup>\n    <Babel Input=\"$(TargetPath)\" MapInFiles=\"@(MapInFile)\" RulesFiles=\"@(RulesFile)\" \n           GenerateMapOutFile=\"$(GenerateMapOutFile)\" />\n  </Target>\n</Project>\nAs the MainAssembly project references the two libraries, Library1 and Library2, which have been obfuscated in their public interface, the Babel task needs to be configured to load the two XML mapping files generated for each library.\nMain Assembly Project\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <ItemGroup>\n    <Reference Include=\"path\\to\\referenced\\Library1.dll\" />\n    <Reference Include=\"path\\to\\referenced\\Library2.dll\" />\n  </ItemGroup>\n  \n  <Target Name=\"Obfuscate\" AfterTargets=\"CoreCompile\">\n    <ItemGroup>\n      <MapInFile Include=\"path\\to\\referenced\\Library1.dll.map.xml\" />\n      <MapInFile Include=\"path\\to\\referenced\\Library2.dll.map.xml\" />\n    </ItemGroup>\n    <Babel Input=\"$(TargetPath)\" MapInFiles=\"@(MapInFile)\" />\n  </Target>\n</Project>"},{"page":29,"heading":"Setup From MSBuild Task","anchor":"setup-from-msbuild-task","text":"This ensures that any cross-referencing between Library1 and Library2 is handled correctly during the obfuscation process. Without referencing the XML map file generated for Library2, the obfuscation process for Library1 may not correctly handle cross-referencing between the two libraries, leading to potential issues at runtime. Therefore, it is essential to ensure that all necessary XML map files are generated and referenced correctly when configuring cross-assembly renaming."},{"page":29,"heading":"Setup From Babel Desktop","anchor":"setup-from-babel-desktop","text":"A Babel Desktop project can hold all the assemblies involved. On the project canvas, connect each library to the assembly that uses it and choose Pass the map file: the library then writes its map file, the consumer reads it, and the library is obfuscated first. In the example above, connect Library2 to Library1 and to MainAssembly, and Library1 to MainAssembly. A connection with Execution order only sets the order but passes no map file.\nYou still add the public renaming rules to each library, with XML rules or RulesFiles. The Map files group of the target properties shows the maps each target writes and reads, and lets you add map files from earlier builds. See Execution Order and Map Files."},{"page":30,"heading":"","anchor":"","text":"Obfuscating an application provides a layer of protection for intellectual property, offering a competitive advantage by making reverse engineering more difficult. However, this added security introduces challenges in error reporting. Obfuscation can make crash analysis harder since the stack trace often becomes a series of unreadable symbols, complicating the debugging process."},{"page":30,"heading":"Decoding Stack Traces in .NET","anchor":"decoding-stack-traces-in-net","text":".NET developers typically rely on stack traces to pinpoint the cause of application errors. However, obfuscation turns these traces into an unintelligible mess. With Babel Obfuscator, decoding these obfuscated stack traces becomes straightforward. The tool requires a mapping file, which is generated during the obfuscation process."},{"page":30,"heading":"Generating the Mapping File","anchor":"generating-the-mapping-file","text":"When you enable XML mapping file generation in Babel Obfuscator, the mapping file is generated in the same directory as the obfuscated assembly by default. The file is named after the original assembly with .map.xml appended (e.g., MyApp.exe.map.xml).\nThe generated mapping file contains the relationship between obfuscated and original symbol names.\nWarning: Note that overloaded renaming should be disabled (--nooverloaded) because it assigns the same name to different methods, potentially adding ambiguity when decoding the stack trace. If overloaded renaming is enabled, Babel will provide all possible method matches during decoding.\nYou can customize the output location of the mapping file using different methods depending on how you're using Babel.\nCommand Line\nbabel MyApp.exe --mapout CustomPath/MyMapping.xml\nIf you omit the file path parameter, it will use the default naming convention in the target directory.\nMSBuild Task\n<Babel GenerateMapOutFile=\"true\" MapOutFile=\"CustomPath/MyMapping.xml\" />\nBabel Obfuscator NuGet Package\n<PropertyGroup>\n  <GenerateMapOutFile>true</GenerateMapOutFile>\n  <BabelMapOutFile>CustomPath/MyMapping.xml</BabelMapOutFile>\n</PropertyGroup>\nBabel Desktop\nIn Babel Desktop, select the assembly and enable GenerateMapOutFile in the Output & diagnostics group of the properties panel. Set MapOutFile to write the map file to a custom path. See Obfuscation Projects."},{"page":30,"heading":"Decoding the Obfuscated Stack Trace","anchor":"decoding-the-obfuscated-stack-trace","text":"When an obfuscated application crashes and produces an obfuscated stack trace, use Babel to decode it. Babel Obfuscator provides built-in tools for decoding obfuscated stack traces using the mapping files."},{"page":30,"heading":"Babel Desktop","anchor":"babel-desktop-1","text":"The steps below are a summary; see Stack Decoder for the complete guide.\nOpen the Stack decoder\nOpen the command palette and run Tools: Stack decoder.\nAdd the map files\nAdd the XML map files with Add map files…, or drop them onto the decoder. You can add several map files when the trace spans multiple assemblies.\nPaste the stack trace\nPaste the obfuscated stack trace, or load it from a file with Open trace….\nDecode\nPress Decode to reveal the decoded stack trace."},{"page":30,"heading":"Command Line","anchor":"command-line-1","text":"Alternatively, use the babel command line tool:\nbabel --stacktrace StackTrace.txt --mapin MyApp.exe.map.xml --mapin Library.dll.map.xml\nYou can include multiple mapping files if the stack trace involves multiple assemblies."},{"page":30,"heading":"Dynamic Proxy Frames","anchor":"dynamic-proxy-frames","text":"When Dynamic Proxy is enabled, Babel routes eligible calls through generated bridge methods. Each bridge shows up as an extra frame, so a decoded trace interleaves your own methods with Babel's plumbing. Babel records, in the mapping file, the method each bridge stands in for, and the decoder prints it:\nat Acme.Backup.ZipReader.OpenZip(System.String filename)\n   at (System.String ) -> proxy for System.IO.Compression.ZipFile::OpenRead\n   at Acme.Backup.BackupReader.IsBackupFile(System.String path)\nThe -> proxy for <DeclaringType>::<Method> annotation tells you exactly which method the bridge was calling. The signature is already shown on the frame, so it is not repeated in the annotation. Mapping files produced by older versions of Babel, which do not record the proxy target, decode as before, showing the generic -> babel generated code note instead.\nHiding Babel generated frames\nIf you only care about your own call chain, Babel can drop every frame it generated — the proxy bridges and the anonymous run-time frames they call through — leaving a trace identical to the one you would get from the unobfuscated application.\nFrom the command line, add the frames=user key to the --stacktrace option:\nbabel --stacktrace StackTrace.txt --stacktrace frames=user --mapin MyApp.exe.map.xml\nframes=all is the default and keeps every frame. In Babel Desktop the stack decoder hides these frames by default: Hide frames Babel added is ticked. Clear it to keep every frame."},{"page":30,"heading":"Dynamic Proxy Frames","anchor":"dynamic-proxy-frames","text":"With generated frames hidden, the trace above becomes:\nat System.IO.Compression.ZipFile.Open(System.String archiveFileName)\n   at Acme.Backup.ZipReader.OpenZip(System.String filename)\n   at Acme.Backup.BackupReader.IsBackupFile(System.String path)"},{"page":30,"heading":"Automating Stack Trace Deobfuscation","anchor":"automating-stack-trace-deobfuscation","text":"Babel Obfuscator provides an interface to automate stack trace decoding. Include a reference to babel.dll or (babel.exe for legacy .NET Framework applications), in your .NET assembly and use the provided API to decode stack traces programmatically.\nThe code snippet below demonstrates how to configure a console application to deobfuscate a stack trace loaded from an external file:\n// Example of setting up the console application\nstatic int Main(string[] args)\n{\n    if (args.Length < 2)\n    {\n        Console.WriteLine(\"Usage: stackdecode.exe <filename> <xmlmapfile1> [xmlmapfile2 ...]\");\n        return 1;\n    }\n \n    StackTraceDeobfuscator stk = new StackTraceDeobfuscator();\n \n    foreach (var xmlMapFile in args.Skip(1))\n    {\n        try\n        {\n            stk.AddMapFile(xmlMapFile);\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine(String.Format(\"Error reading XML map file '{0}':n{1}\", xmlMapFile, ex.Message));\n            return 1;\n        }\n    }\n \n    try\n    {\n        StreamReader sr = new StreamReader(args[0]);\n \n        Console.WriteLine(\"Deobfuscated Stack Trace:\");\n        Console.WriteLine(stk.DeobfuscateStack(sr));\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine(String.Format(\"Could not decode stack trace file '{0}':n{1}\", args[0], ex.Message));\n        return 1;\n    }\n \n    return 0;\n}"},{"page":30,"heading":"Automating Stack Trace Deobfuscation","anchor":"automating-stack-trace-deobfuscation","text":"To drop the frames Babel generated (see Hiding Babel generated frames) when decoding programmatically, set HideGeneratedFrames on the deobfuscator before calling DeobfuscateStack:\nStackTraceDeobfuscator stk = new StackTraceDeobfuscator();\nstk.HideGeneratedFrames = true;\nUtilizing the programmatic interface to deobfuscate stack traces offers developers a powerful tool to enhance their debugging practices seamlessly. By integrating this mechanism into their applications, developers can automate the decoding process, handle obfuscated stack traces efficiently, and maintain the integrity and security of their codebase."},{"page":30,"heading":"Using PDB Files with Obfuscated Stack Traces","anchor":"using-pdb-files-with-obfuscated-stack-traces","text":"Optionally, use PDB files in production to obtain source file and line numbers in the decoded stack trace. Specifically, Babel can encrypt file names and symbol names within the PDBs, ensuring that they appear encrypted in stack traces, which prevents revealing sensitive file path information.\nTo enable this feature, set a PDB password. Choose a secure password: it encrypts the file names in the PDB and is required later to deobfuscate the stack traces.\nCommand line: use the --pdbpwd option, for example babel MyApp.exe --debug --pdbpwd <password>.\nMSBuild: set the PdbPwd property of the Babel task.\nBabel Desktop: select the assembly and set PdbPwd in the Advanced group of the properties panel. The password is kept for the current session only: it is not saved in the project and must be entered again after restarting Babel Desktop.\nOnce this feature is enabled and the PDB password is set, Babel will encrypt file names and other relevant information during the obfuscation process. As a result, in your stack traces, the file names will appear as encrypted strings rather than the original file paths.\nSystem.Exception: (0x80131904): A network-related or instance-specific error occurred while establishing a connection to the server.\n   at System.Data.SqlClient.SqlConnection.Open()   \n   at b.a(String g)\n   at c.b() in <GFpQHv9iwQzX1Zmh+… >:line 21\n   at c.a(String h)\n   at Acme.ViewModel.MainViewModel.get_Message() in <GFpQHv9iwQzX1Zmh+… >:line 28"},{"page":30,"heading":"Using PDB Files with Obfuscated Stack Traces","anchor":"using-pdb-files-with-obfuscated-stack-traces","text":"All necessary decryption data is stored in the XML mapping file, so the PDB file isn't required for decoding. The decoded stack trace will contain the decrypted file name.\nSystem.Exception: (0x80131904): A network-related or instance-specific error occurred while establishing a connection to the server.\n   at System.Data.SqlClient.SqlConnection.Open()\n   at Acme.Entities.DatabaseContext.ConnectToDatabase(System.String connectionString)\n   at Acme.ViewModel.RS.CheckResourceLoaded() in C:AcmeAcme.ViewModelRS.cs:line 21\n   at Acme.ViewModel.RS.GetString(System.String name)\n   at Acme.ViewModel.MainViewModel.get_Message() in C:AcmeAcme.ViewModelViewModelMainViewModel.cs:line 28\nThis method offers a balance between security and maintainability. It protects the intellectual property embedded in your file structures while still allowing you to gain useful insights into stack traces for debugging and error analysis.\nBy setting up PDB encryption, you ensure that your application’s internal structure and file organization remain secure and confidential, even when sharing PDBs for troubleshooting or support purposes."},{"page":31,"heading":"","anchor":"","text":"Windows Presentation Foundation (WPF) and, more recently, MAUI applications use XAML declarative markup language and BAML (compiled XAML) to directly enable visual designers to create user interface elements.\nBabel Obfuscator can analyse XAML and BAML resources and rename all the members referenced within them, which increases the percentage of obfuscated symbols and makes the XAML code more difficult to read. Additionally, Babel can merge multiple assembly files containing XAML or BAML resources into a single assembly file, improving the organization and simplifying the deployment of the application.\nThe XAML and BAML symbols renaming is enabled by entering the --xaml flag at the command line. This switch has additional optional parameters, which can be used to enhance the XAML (BAML) obfuscation.\nCommand Line\nbabel.exe myapp.exe --xaml\nMSBuild Babel Task\n<PropertyGroup>\n  <ObfuscateXaml>true</ObfuscateXaml>\n</PropertyGroup>\n\n<Babel ObfuscateXaml=\"$(ObfuscateXaml)\" />\nBabel Obfuscator allows some advanced XAML settings for additional configuration of the XAML obfuscation process by using key-value pairs passed after the --xaml switch.\nAvailable key-value pairs include:\nkeys\nIn XAML, a static resource is a resource that is defined at design-time and can be referenced from other parts of the application, such as controls or styles. The resource is identified by a key name used to reference it from the XAML code."},{"page":31,"heading":"","anchor":"","text":"When enabled, Babel Obfuscator will rename the key names of static resources in the XAML/BAML code. This can help increase the level of obfuscation of the code and make it more difficult for attackers to understand the original purpose of a resource.\nres\nWhen enabled, allows Babel to obfuscate the XAML/BAML resource names. This means that the names of any resources used in the XAML/BAML code, such as images or strings, will be renamed to obscure their original purpose. This can make it more difficult for attackers to understand the structure and function of the XAML/BAML code, which can improve the overall security of your application.\nstrip\nThis option is used to remove line information and white spaces from the obfuscated XAML/BAML code. This can make it more difficult for attackers to reverse engineer the original code, as it removes debug information that could potentially help an attacker reconstruct the original source code. Removing line information and white spaces can also help to reduce the size of the obfuscated XAML/BAML file, making it more efficient and faster to load.\nmanual"},{"page":31,"heading":"","anchor":"","text":"By default, Babel Obfuscator automatically obfuscates all public members referenced within the XAML or BAML code. However, in cases where a more fine-tuned approach is necessary, the manual option can be enabled. This allows the user to manually specify which public members should be obfuscated, using either quick rule or XML rule files. This gives greater control over the obfuscation process but requires more configuration by the user.\nbabel.exe myapp.exe --xaml keys=on --xaml res=on --xaml strip=on\n<PropertyGroup>\n  <ObfuscateXaml>keys=true;strip=true;manual=false;res=true;true</ObfuscateXaml>\n</PropertyGroup>\n\n<Babel ObfuscateXaml=\"$(ObfuscateXaml)\" />"},{"page":31,"heading":"Aligning string literals with renamed XAML-bound members","anchor":"aligning-string-literals-with-renamed-xaml-bound-members","text":"When a WPF assembly is built, the compiler typically embeds each XAML page as BAML — the binary form of XAML — into the assembly's resources. During the read phase, Babel inspects this BAML and, for every x:Name declaration, attempts to bind the name to the corresponding code-behind backing field on the root element type. A field that the binding succeeds for is treated as XAML-bound for the rest of the obfuscation run.\nWhen such a XAML-bound member is renamed, Babel performs an additional alignment step on the declaring type. It walks every method body in the type and rewrites every string literal whose value equals the member's original name, replacing it with the member's new name. The match is plain string equality on the literal text, and the rewrite is applied to all such literals in the type regardless of how they are subsequently used. The only literals exempt from this rewrite are those passed to System.Resources.ResourceManager and call sites explicitly excluded by user-supplied renaming rules."},{"page":31,"heading":"Aligning string literals with renamed XAML-bound members","anchor":"aligning-string-literals-with-renamed-xaml-bound-members","text":"The intent is to keep WPF name-based runtime lookups in code-behind working after renaming. Patterns like this.FindName(\"tabPreise\"), custom helpers such as GetControlByName<T>(string name), or any other code that resolves a member or named element by its source-time string name continue to function because the literals have been kept in sync with the renamed field. Because the matcher is structural rather than attribute-based, this alignment picks up user-defined helpers automatically without requiring an opt-in attribute on the helper.\nFor example, given the following code-behind:\nprivate TabItem tabPreise { get; set; }\n\nvoid Wire()\n{\n    var tab = GetControlByName<TabItem>(\"tabPreise\");\n    // ...\n}\nAfter Babel obfuscates the assembly, the field is renamed and the literal that names it is aligned to the new name:\nprivate TabItem cm { get; set; }\n\nvoid Wire()\n{\n    var tab = GetControlByName<TabItem>(\"cm\");\n    // ...\n}"},{"page":31,"heading":"Aligning string literals with renamed XAML-bound members","anchor":"aligning-string-literals-with-renamed-xaml-bound-members","text":"The alignment fires only when the BAML binding described above succeeds. If the BAML element type cannot be resolved — typically because the assembly that defines it is not on Babel's search path and the resolver emits warning W00013 for that assembly — the binding silently fails, and the member is not flagged as XAML-bound. Field renaming itself does not depend on the XAML flag, so the field still receives its new name; the literals naming the original field, however, are left untouched, and the obfuscated assembly will contain inconsistent IL. Any name-based runtime lookup that relied on those literals will fail at runtime.\nTwo mitigations apply, in order:\nTreat W00013 as build-blocking for projects that contain embedded BAML. Add the directories containing every referenced assembly that defines XAML element types to Babel's search path with the --addsearch option, so that the BAML resolver can bind every element type. With every element type resolved, the alignment step runs as designed.\nWhere keeping the original name is the desired outcome — for example when standalone .xaml files are shipped alongside the assembly and reference the field by its original name — exclude the field from renaming with a locked XML rule:"},{"page":31,"heading":"Aligning string literals with renamed XAML-bound members","anchor":"aligning-string-literals-with-renamed-xaml-bound-members","text":"<Rule name=\"keep-xname-tabPreise\"\n      feature=\"renaming\" exclude=\"true\" locked=\"true\">\n  <Target>Fields,Properties,Methods</Target>\n  <Pattern>MyNamespace.MyForm::tabPreise</Pattern>\n  <Pattern>MyNamespace.MyForm::get_tabPreise</Pattern>\n  <Pattern>MyNamespace.MyForm::set_tabPreise</Pattern>\n</Rule>\nWith the field name unchanged, the alignment step has nothing to rewrite, and the assembly remains consistent with both BAML and any loose XAML files that reference tabPreise.\nFor the broader picture of when W00013 is informational versus when it correlates with a real change in the obfuscated output, see W00013 in the BAML-binding path in the command-line reference."},{"page":32,"heading":"","anchor":"","text":"Babel Obfuscator uses XML map files to map the original, unobfuscated names of classes, methods, properties, events and fields to their obfuscated names. These files can be generated by the Babel Obfuscator during the obfuscation process, and they are stored in the same directory as the obfuscated assembly.\nThe XML map files are important because they allow developers to:\nDeobfuscate the exception stack traces.\nObfuscate the public interface of an assembly.\nDeobfuscate Stack Trace\nWhen an exception is thrown in an obfuscated application, the stack trace contains the names of the obfuscated symbols, which are not easily readable or identifiable. However, by using the XML map files, the obfuscated names can be mapped back to their original names, allowing developers to more easily identify the source of the exception and debug the issue. This makes the XML map files a valuable tool for developers working with obfuscated applications.\nTo learn more about deobfuscating stack traces, see Decoding Stack Traces.\nObfuscate Public Interface"},{"page":32,"heading":"","anchor":"","text":"Since .NET assemblies often reference other assemblies, including third-party libraries, it is common for the names of objects, methods, and properties in one assembly to be used in another. When these assemblies are obfuscated separately, the obfuscation process may change the original names of externally visible objects and methods in one assembly, causing the other assemblies that reference them to no longer work properly. The obfuscation of externally visible assembly members is often referred to as Cross Assembly Renaming.\nXML map files provide a way to maintain the relationships between the original names and the obfuscated names across multiple assemblies. When multiple assemblies are obfuscated, their respective XML map files can be combined to ensure that the original relationships between the names are preserved. This allows the obfuscated code to work correctly even when it is being called from other assemblies that have not been obfuscated."},{"page":32,"heading":"Configuring XML Map File Generation","anchor":"configuring-xml-map-file-generation","text":"The XML map file generation can be configured from the command line, Babel Desktop, or in build environments through the MSBuild Babel task and the Babel Obfuscator NuGet package.\nCommand Line\nThe Babel Obfuscator command line tool can accept the --mapout option to enable XML map file generation. The basic syntax for enabling map file generation is as follows:\nbabel MyApp.exe --mapout [output file]\nThe option can accept the full path of the generated XML map file. If the path is not specified, the XML map file will be named as the original target file name adding the “.map.xml” extension and stored in the same directory of the obfuscated assembly.\nFor example, if the obfuscated assembly is named \"MyApp.exe\", the XML map file will be named \"MyApp.exe.map.xml\".\nYou can also specify additional options to customize the map file generation, such as specifying a different output encoding format for the map file names:\nbabel MyApp.exe --mapout encoding=base64\nThe supported formats are 'none' and 'base64'. If the encoding format is not specified, babel will choose the base64 format when the Unicode Normalization is enabled.\nMSBuild Babel Task\nTo enable the generation of XML map files in the MSBuild Babel task, set the GenerateMapOutFile task attribute to true. Optionally you can specify the generated file path using the MapOutFile attribute:\n<Babel GenerateMapOutFile=\"true\" MapOutFile=\"MyAssembly.map.xml\" />"},{"page":32,"heading":"Configuring XML Map File Generation","anchor":"configuring-xml-map-file-generation","text":"If you are using in your project file, the Babel Obfuscator NuGet package, you can add the following XML element to your project file to enable the generation of the XML map file of the obfuscated target assembly:\n<PropertyGroup>\n  <GenerateMapOutFile>true</GenerateMapOutFile>\n</PropertyGroup>\nYou can override the file path of the generated XML map file using the following property:\n<PropertyGroup>\n  <GenerateMapOutFile>true</GenerateMapOutFile>\n  <BabelMapOutFile>MyAssembly.map.xml</BabelMapOutFile>\n</PropertyGroup>\nBabel Desktop\nTo enable XML map file generation in Babel Desktop, select the assembly on the project canvas and, in the Output & diagnostics group of the properties panel, enable GenerateMapOutFile. Optionally set MapOutFile to choose where the map file is written, then save the project.\nAfter enabling the generation of XML map files, Babel Obfuscator will create a map file for the input assembly that it obfuscates, with the same name as the obfuscated assembly but with a .map.xml extension. The map files will be saved to the path specified by MapOutFile, or next to the obfuscated assembly."},{"page":33,"heading":"","anchor":"","text":"Babel Obfuscator provides the ability to encrypt code-inline strings using integrated string encryption algorithms. In addition to these built-in encryption algorithms, Babel also allows for custom string algorithms to be implemented through external code or plugins. This enables users to create their own unique encryption methods tailored to their specific needs."},{"page":33,"heading":"Configuring String Encryption","anchor":"configuring-string-encryption","text":"Configuring string encryption with Babel Obfuscator involves selecting an encryption algorithm and setting it up for your application. Babel supports the XOR, HASH and STREAM algorithms out of the box. You can select any of the three in Babel Desktop, with command line flags or in your MSBuild project file. If none of them fits, you can implement Custom string encryption methods.\nWhether opting for built-in algorithms or custom implementations, configuring string encryption enhances the security of your application by protecting sensitive strings from straightforward interception or manipulation.\nDeploying on FIPS-enabled hosts? The XOR and HASH algorithms decrypt strings at runtime through the platform crypto provider, so a container running on a FIPS-enabled host without a certified OpenSSL FIPS provider can fail to start. See FIPS Compliance for the cause and the fix. The STREAM algorithm is not affected: its decryptor is fully managed and never calls the platform crypto provider.\nEncryption Of Const Strings"},{"page":33,"heading":"Configuring String Encryption","anchor":"configuring-string-encryption","text":"A limitation within Babel Obfuscator is its inability to encrypt constant (const) strings because they are compiled into the application's metadata, making them directly accessible by the CLR at runtime. To enable encryption for these strings, they must be converted to static readonly (for C#) or Shared ReadOnly (for VB.NET) fields. This approach allows Babel Obfuscator to process and encrypt such strings, thereby enhancing the security of your application by safeguarding sensitive information that would otherwise be exposed in plain text.\n// Strings declared const cannot be encrypted\npublic const string Connection = \"Server=myServerAddress;Database=myDB;...\";\n\n// To encrypt, convert the above declaration to static readonly\npublic static readonly string Connection = \"Server=myServerAddress;Database=myDB;...\";"},{"page":33,"heading":"Babel Desktop","anchor":"babel-desktop","text":"In Babel Desktop, select the assembly on the project canvas and choose the algorithm (xor, hash, stream or custom) for StringEncryption in the Code encryption group of the properties panel. The list offers only the algorithms your license includes. For custom, the EncryptString and DecryptString methods must be defined in your code."},{"page":33,"heading":"In This Section","anchor":"in-this-section","text":"Standard Algorithms — the built-in XOR, HASH and STREAM algorithms, how to enable each one, and a side-by-side comparison to help you choose.\nCustom Algorithm — implement your own EncryptString / DecryptString methods to encrypt strings with an algorithm of your choice."},{"page":34,"heading":"","anchor":"","text":"Babel Obfuscator ships with three built-in string encryption algorithms: XOR, HASH and STREAM. All three are self-contained — they decrypt without any external input — so choosing between them is a trade-off between load time, output size, and how hard the strings are to recover. This page describes each algorithm and how to enable it; the comparison table at the end summarizes the differences."},{"page":34,"heading":"XOR Algorithm","anchor":"xor-algorithm","text":"The XOR algorithm used by Babel Obfuscator for string encryption is a simple one that involves XOR-ing the in-line string characters with a random integer key. This method has the advantage of allowing for faster decryption and less load time compared to other encryption algorithms.\nCommand Line\nTo configure the XOR encryption algorithm for your application using Babel Obfuscator from the command line, use the simple command:\nbabel myapp.exe --string xor\nThis command instructs Babel to apply XOR encryption to the inline strings within your application executable, leveraging the simplicity and speed of the XOR algorithm for secure string obfuscation.\nMSBuild Babel Task\nConfiguring the XOR algorithm for string encryption in your project using the Babel MSBuild task is straightforward. Simply add a property group and a Babel task to your MSBuild project file with the specific configuration for the XOR encryption method:\n<PropertyGroup>\n  <StringEncryption>xor</StringEncryption>\n</PropertyGroup>\n\n<Babel StringEncryption=\"$(StringEncryption)\" />\nThis configuration ensures that Babel Obfuscator will apply the XOR encryption algorithm to the strings in your project, enhancing their security and making them more resistant to tampering and reverse-engineering efforts."},{"page":34,"heading":"HASH Algorithm","anchor":"hash-algorithm","text":"The HASH algorithm used by Babel Obfuscator is based on hash tables addressed by integer keys. This algorithm performs both compression and encryption of string data, which can help to reduce the overall file size of the string data. However, since the compressed string data needs to be decrypted at runtime, it can have an impact on the load time of the application. Compared to the XOR algorithm, which xor-ed the inlined string characters with a random integer key, the HASH algorithm offers better protection against string decryption attacks but at the cost of a slower load time.\nCommand Line\nTo set up HASH encryption with Babel Obfuscator via CLI, use this command:\nbabel myapp.exe --string hash\nMSBuild Babel Task\nTo enable HASH encryption using Babel's MSBuild task, set the StringEncryption property as follow:\n<PropertyGroup>\n  <StringEncryption>hash</StringEncryption>\n</PropertyGroup>\n\n<Babel StringEncryption=\"$(StringEncryption)\" />\nThis integration of the HASH algorithm ensures that during the build process, your project's strings are adequately protected."},{"page":34,"heading":"STREAM Algorithm (Ultimate)","anchor":"stream-algorithm","text":"The STREAM algorithm is the modern, authenticated string-encryption option in Babel Obfuscator. It encrypts each string individually with a strong, industry-standard cipher and verifies an authentication tag before returning it. This gives STREAM four properties the older algorithms do not have:"},{"page":34,"heading":"STREAM Algorithm (Ultimate)","anchor":"stream-algorithm","text":"Lazy, per-string decryption. A string is decrypted only the first time it is actually used, and the result is cached. Unlike HASH, STREAM never decrypts the whole set up front, so a memory dump only ever exposes the few strings the application has already touched — there is no single point in time where every string sits in memory in clear text.\nIntegrity and per-string randomization. The authentication tag detects any tampering with the encrypted data, and two identical strings encrypt to different bytes, defeating the frequency and equality analysis that a simple XOR scheme leaks.\nA key that is never stored inline. The key is not held as a literal next to the decryption call, so an automated deobfuscator has to execute the real code to recover a string rather than simply reading a key beside the call.\nDecryption bound to your code's call context. Executing the decryptor is not enough: it returns a string only to a caller running inside the protected assembly itself (or inside the .NET runtime, so LINQ/PLINQ and async paths keep working). The usual one-command way an automated deobfuscator dumps every encrypted string at once — binding a delegate straight to the decryptor and batch-invoking it from its own helper assembly — is turned away. This does not make strings impossible to recover under full dynamic analysis, but it removes the cheap bulk-extraction path and forces an attacker to drive your real code."},{"page":34,"heading":"STREAM Algorithm (Ultimate)","anchor":"stream-algorithm","text":"The decryptor is written entirely in managed code, with no dependency on the platform cryptographic provider. As a result STREAM runs unchanged from .NET Framework 4.x (and 2.0) through .NET 10, on Mono/Xamarin, and — because it uses no Reflection.Emit — in NativeAOT and trimmed applications. It is also unaffected by the FIPS startup issue that can affect the platform-based algorithms.\nSTREAM is self-contained: like XOR and HASH it decrypts without any external input. Being a local-only scheme, it cannot make strings impossible to recover under full dynamic analysis — no self-contained scheme can — but it raises the cost of both automated extraction and manual reverse engineering well above XOR and HASH.\nPlatform and Framework Support\nBecause the decryptor is fully managed and uses no Reflection.Emit, dynamic code, stack walking, or platform crypto provider, STREAM has been verified across the whole .NET range and on mobile:"},{"page":34,"heading":"STREAM Algorithm (Ultimate)","anchor":"stream-algorithm","text":".NET Framework 2.0 / 4.x through .NET 10, .NET Core, and Mono / Xamarin.\nTrimmed (ILLink) and NativeAOT applications — the injected decryptor and its embedded string table survive linking, and the code compiles ahead-of-time without a JIT.\nAndroid and iOS — verified end to end with real obfuscated apps on the Android emulator and the iOS simulator, including Release, fully trimmed builds: the strings decrypt at runtime and no plaintext remains in the packaged assembly. .NET MAUI builds on these same runtimes (net*-android / net*-ios), so the same support applies. iOS device full-AOT is covered by the NativeAOT compatibility above.\nOn mobile, apply STREAM as a string-encryption-only pass so type and member names stay intact for the Java / Objective-C interop layer:\nbabel MyApp.dll --stringencryption stream --notypes --nomethods --nofields --noproperties --noevents --noparameters --novirtualmembers\nWhen Babel runs as an MSBuild step inside a .NET Android / iOS / MAUI build, hook it after the app assembly is compiled and before packaging, so the packaged app carries the obfuscated assembly.\nCommand Line\nTo apply STREAM encryption from the command line:\nbabel myapp.exe --string stream\nMSBuild Babel Task\nTo enable STREAM encryption using Babel's MSBuild task, set the StringEncryption property as follows:\n<PropertyGroup>\n  <StringEncryption>stream</StringEncryption>\n</PropertyGroup>\n\n<Babel StringEncryption=\"$(StringEncryption)\" />"},{"page":34,"heading":"STREAM Algorithm (Ultimate)","anchor":"stream-algorithm","text":"STREAM works together with the other protections. It can be combined with code (MSIL) encryption and anti-tampering on the same assembly.\nAnti-tampering and post-build rewriting. Anti-tampering stamps an integrity hash of the obfuscated image. Any step that rewrites the assembly after Babel — most notably a trimmed or NativeAOT publish, which re-emits the managed assembly — changes those bytes and makes the check fail fast at start-up. This is inherent to anti-tampering and independent of the string algorithm (it affects XOR, HASH and STREAM alike): enable anti-tampering on builds that are not further trimmed/AOT-rewritten, and rely on string encryption (plus code encryption) for trimmed/AOT outputs."},{"page":34,"heading":"Comparing the Algorithms","anchor":"comparing-the-algorithms","text":"All three built-in algorithms are self-contained — they decrypt without any external input — so choosing between them is a trade-off between load time, output size, and how hard the strings are to recover.\n| XOR | HASH | STREAM\nCipher | Inline XOR with a per-string integer key | Compressed table encrypted with the platform cipher | Authenticated, industry-standard per-string cipher\nStrings kept as literals | Yes (scrambled in place) | No | No\nDecryption model | Per string, on each access | Eager — the whole table is decrypted at first use | Lazy — each string on first use, then cached\nClear text held in memory | One string at a time | The entire table, for the whole run | Only the strings actually used\nPer-string integrity tag | — | — | Yes\nIdentical strings encrypt differently | No | No | Yes\nRefuses out-of-context (delegate-invoke) decryption | — | — | Yes\nDecryption key | Inline, next to the call | Stored in the blob header | Never inline — rebuilt at runtime and woven into the control flow\nFully managed decryptor (no platform crypto provider; FIPS-safe) | No | No | Yes\nRelative output size | Largest (literals stay in the assembly) | Smallest (single compressed blob) | Between XOR and HASH\nRelative runtime cost | Lowest | Low, but paid up front for every string | Higher per string, paid only for strings that are used\nWhich to choose."},{"page":34,"heading":"Comparing the Algorithms","anchor":"comparing-the-algorithms","text":"XOR — the fastest and lightest, but the weakest: the encrypted strings remain as literals in the assembly and a per-string key sits next to every call, so an automated tool can recover them in a single pass. Choose it when load time matters more than protection.\nHASH — removes the literals and packs the whole set into one compressed, encrypted blob (the smallest output), with tamper protection on the table. The cost is that the entire table is decrypted eagerly on first use — so every string sits in memory in clear text for the rest of the run — and its decryptor relies on the platform crypto provider (see the FIPS note).\nSTREAM — the strongest of the three against both static and dynamic analysis: authenticated per-string encryption, no eager global decrypt, no inline key, and a single fully managed decryptor that publishes unchanged under NativeAOT and trimming and is unaffected by FIPS. You pay a higher per-string decryption cost, but only for the strings the application actually touches, and no point in time ever holds the full set of strings in clear text. Prefer STREAM for modern .NET, AOT/trimmed or FIPS deployments, and wherever resistance to bulk string extraction matters most."},{"page":35,"heading":"","anchor":"","text":"Custom string encryption enables users to formulate their own methods for encrypting and decrypting strings, allowing for personalized obfuscation of strings. To leverage custom string encryption, users are required to define two specific methods within the target assembly: EncryptString and DecryptString. Both methods must have identical signatures, accepting a string as a parameter and returning a string, which represents either the encrypted or decrypted string, respectively. By establishing these methods, users have the flexibility to implement any custom encryption algorithm of their choice to encrypt strings in their code, granting enhanced adaptability and command over the obfuscation process.\n/// <summary>\n/// Encrypt a string.\n/// </summary>\n/// <param name=\"text\">The string to encrypt.</param>\n/// <returns>The encrypted string.</returns>\n[Obfuscation(Feature = \"string encryption encrypt method\")]\ninternal static string EncryptString(string text)\n{\n   // Encrypt the text string and return the encrypted string object.\n   return ...;\n}\n/// <summary>\n/// Decrypt an encrypted string.\n/// </summary>\n/// <param name=\"text\">The encrypted string.</param>\n/// <returns>The decrypted string.</returns>\n[Obfuscation(Feature = \"string encryption decrypt method\")]\ninternal static string DecryptString(string text)\n{\n   // Decrypt the text string and return the decrypted string object.\n   return ...;\n}"},{"page":35,"heading":"","anchor":"","text":"The EncryptString and DecryptString methods are addressed by the Obfuscation attribute with a proper Feature string, which allows Babel to identify the code entry points for encrypting and decrypting strings.\nOnce you have defined the EncryptString and DecryptString methods and addressed them with the proper Obfuscation attribute, you can then enable custom string encryption with Babel.\nYou can turn on custom string encryption in Babel Desktop, from the command line, or with the MSBuild task.\nBabel Desktop\nIn Babel Desktop, select the assembly and set StringEncryption to custom in the Code encryption group of the properties panel.\nAdditionally, for further customization and extension of the encryption capabilities, Babel supports the integration of external plugins. This feature allows for a more flexible and robust encryption mechanism, tailored to the specific needs and security requirements of your application.\nCommand Line\nTo enable Babel custom string encryption using the command line, you can enter the command:\nbabel myapp.exe --strings custom\nMSBuild Babel Task\nIf you are using the Babel task, you can enable custom string encryption by adding the following to your project file:\n<PropertyGroup>\n  <StringEncryption>custom</StringEncryption>\n</PropertyGroup>\n\n<Babel StringEncryption=\"$(StringEncryption)\" ... />\nIn addition, users can also implement custom string encryption using external plugins (see Babel Obfuscator Plugins)."},{"page":36,"heading":"","anchor":"","text":"Control flow obfuscation makes a method hard to follow by rewriting the way its instructions branch, while leaving what the method computes unchanged. Babel can make if statements harder to read, insert branches that never affect the result, and rebuild a method around a dispatcher so its blocks no longer run in source order. The goal is to raise the cost of decompiling and understanding the code, making it harder to reverse engineer or tamper with.\nBabel groups its control-flow work into a set of algorithms you enable individually. They fall into two families:\nLightweight transforms — if and goto — add branches and extra conditions with almost no runtime cost.\nFlattening transforms — switch, case, call, value, and the Ultimate Chained State algorithm — rebuild a method around a dispatcher. These are much stronger, at a higher runtime cost.\nTwo further options, token and underflow, deliberately produce non-verifiable IL and are disabled automatically when targeting .NET and .NET Core. See Algorithms for the full catalog."},{"page":36,"heading":"Configuring Control Flow Obfuscation","anchor":"configuring-control-flow-obfuscation","text":"Control flow obfuscation can be configured from the Command Line, the MSBuild Babel task, or Babel Desktop. With XML rules you can tune the algorithms for specific sets of methods, for example to change the number of iterations or to enable or disable individual algorithms per method.\nCommand Line\nbabel myapp.exe --controlflow goto=on --controlflow if=on --controlflow switch=on --controlflow case=on --iterations 3\nThe --controlflow option enables the specified algorithms — here goto, if, switch and case — and --iterations sets how many times each algorithm is applied to a method.\nMSBuild Babel Task\n<PropertyGroup>\n  <ControlFlowObfuscation>goto=true;if=true;switch=true;case=false;call=true;\n     value=false;token=false;underflow=false;true</ControlFlowObfuscation>\n  <ILIterations>5</ILIterations>\n</PropertyGroup>\n\n<Babel ControlFlowObfuscation=\"$(ControlFlowObfuscation)\"\n       ILIterations=\"$(ILIterations)\" />\nThe ILIterations property sets the number of iterations for the control flow algorithms.\nBabel Desktop\nOpen the project in Babel Desktop and select the assembly on the project canvas.\nIn the Control flow group of the properties panel, enable ControlFlowObfuscation and select the algorithms you want to use.\nSet ILIterations to the number of iterations each algorithm should perform.\nPress Run to start the obfuscation."},{"page":36,"heading":"Configuring Control Flow Obfuscation","anchor":"configuring-control-flow-obfuscation","text":"When obfuscation completes, the Results view shows the control flow statistics: the methods transformed and the iterations performed by each algorithm and, when full statistics are collected, the cyclomatic complexity before and after the transformation."},{"page":36,"heading":"In This Section","anchor":"in-this-section","text":"Algorithms — every control-flow algorithm, what it does, and when to use it.\nChained State  (Ultimate) — an advanced flattening algorithm hardened against automated control-flow deobfuscation.\nPerformance & Tuning — how each algorithm affects runtime, a side-by-side comparison, iterations, and how to keep hot methods fast."},{"page":37,"heading":"","anchor":"","text":"Babel Obfuscator provides several control flow algorithms that you enable individually. Most produce verifiable IL and run on every supported runtime; two (token and underflow) do not and are covered at the end of this page."},{"page":37,"heading":"Verifiable Algorithms","anchor":"verifiable-algorithms","text":"Algorithm | What it does\ngoto | Inserts irrelevant branches, making the control flow longer and less linear.\nif | Rewrites if statements into more complex forms by introducing additional conditions.\nswitch | Rebuilds a method around one or more switch dispatchers, so its blocks no longer run in source order (this is known as flattening).\ncase | Hides the constant values that drive the switch dispatcher, so they are no longer plain numbers in the code.\ncall | Adds variables that determine the next jump inside the switch body and are produced by calls to other methods.\nvalue | Further protects the switch selectors using the Value Encryption feature.\nchain | Chained State — an advanced flattening algorithm hardened against automated deobfuscation. Available from the Ultimate edition. See Chained State.\ngoto and if are inexpensive and can be applied broadly. The switch family (switch, case, call, value) and chain flatten a method and are the strongest transforms, at a higher runtime cost — see Performance & Tuning.\nChained State (Ultimate)\nchain is a flattening algorithm, like switch, but it is specifically engineered to resist the automated tools that can rebuild an ordinary flattened method. It produces verifiable IL and runs on every supported runtime. Enable it with --controlflow chain=on. It has its own page: Chained State."},{"page":37,"heading":"Non-Verifiable Options","anchor":"non-verifiable-options","text":"The token algorithm inserts invalid metadata tokens into the control flow, and the underflow algorithm adds points to the method body where the managed stack can underflow. Both make the IL non-verifiable.\nInfo: The token and underflow algorithms are not compatible with the verifiable nature of .NET and .NET Core assemblies and can cause runtime errors. Babel Obfuscator automatically disables them when targeting .NET or .NET Core assemblies.\nInvalid Opcodes\nThe Emit Invalid Opcodes option adds invalid MSIL instructions alongside the instructions inserted by each algorithm, which can make it harder for decompilers to reconstruct the original code. Enabling it makes the assembly non-verifiable and forces the CLR to run the application as a 32-bit process.\nImportant: Do not enable Emit Invalid Opcodes if the application must run as a 64-bit process, or if it targets .NET Core or .NET Framework where the assembly needs to be IL-verifiable to execute. In those cases, leave this option off."},{"page":38,"heading":"","anchor":"","text":"Chained State (chain) is the strongest control flow transform in Babel Obfuscator. Like the switch algorithm it flattens a method — it rebuilds the method around a dispatcher so its blocks no longer run in source order — but it is specifically engineered to resist the automated tools that can undo ordinary flattening."},{"page":38,"heading":"Why Chained State","anchor":"why-chained-state","text":"Ordinary switch flattening is effective against a human reader, but a well-known class of automated deobfuscators can often reconstruct the original method: they statically analyze the dispatcher, recover the order in which the blocks were meant to run, and rewrite the method back to something close to the source. Against these tools, plain flattening can be undone in a single automated pass.\nChained State closes that gap. The dispatcher is built so that the original order cannot be recovered by static analysis alone — an attacker has to actually run the method to follow its flow. In internal testing against a standard automated control-flow deobfuscator, code flattened with switch was rebuilt back to the original method, while the same code flattened with chain was left intact. The result is a flattened method that resists both manual reading and automated recovery.\nInfo: Chained State is a hardening of flattening, not a replacement for it. You can enable it on its own, or alongside the other control flow algorithms."},{"page":38,"heading":"Compatibility","anchor":"compatibility","text":"Chained State emits only ordinary, verifiable IL and adds no helper types, no reflection, and no runtime dependencies. As a result it runs unchanged across the whole .NET range:\n.NET Framework 4.x through .NET 10, .NET Core, and Mono / Xamarin.\nTrimmed (ILLink) and NativeAOT applications — there is no dynamic code to break under ahead-of-time compilation.\n.NET MAUI, including Android and iOS.\nBecause the transform stays within verifiable IL, it does not force the assembly into a 32-bit process and is safe to combine with the rest of your obfuscation configuration."},{"page":38,"heading":"Performance","anchor":"performance","text":"Chained State carries the same kind of runtime cost as switch flattening — a flattened method runs a dispatcher on every call — and in practice its per-call overhead is within a few percent of ordinary switch. As with any flattening, reserve it for the methods that actually protect your intellectual property, and keep it off hot, performance-critical paths. See Performance & Tuning for the full comparison and how to limit it with rules."},{"page":38,"heading":"Enabling Chained State","anchor":"enabling-chained-state","text":"Command Line\nbabel myapp.exe --controlflow chain=on\nYou can combine it with the other algorithms, for example:\nbabel myapp.exe --controlflow switch=on --controlflow case=on --controlflow chain=on\nMSBuild Babel Task\n<PropertyGroup>\n  <ControlFlowObfuscation>chain=true;true</ControlFlowObfuscation>\n</PropertyGroup>\n\n<Babel ControlFlowObfuscation=\"$(ControlFlowObfuscation)\" />\nBabel Desktop\nIn the Control flow group of the properties panel, enable control flow obfuscation (ControlFlowObfuscation) and select chain among the algorithms.\nInfo: Chained State is available from the Ultimate edition (and Server / Data Center). With the Enterprise edition the engine does not apply the chain algorithm."},{"page":39,"heading":"","anchor":"","text":"Control flow obfuscation trades a little runtime for protection. The lightweight algorithms are essentially free; the flattening algorithms add a dispatcher that runs on every call and therefore cost more. This page compares the algorithms, explains the iterations setting, and shows how to keep hot methods fast."},{"page":39,"heading":"Comparing the Algorithms","anchor":"comparing-the-algorithms","text":"Algorithm | Family | Relative runtime cost | Verifiable IL | Edition\nif | Lightweight | Negligible | Yes | All\ngoto | Lightweight | Negligible | Yes | All\nswitch | Flattening | High | Yes | All\ncase | Flattening (with switch) | High | Yes | All\ncall | Flattening (with switch) | High | Yes | All\nvalue | Flattening (with switch) | High | Yes | All\nchain (Chained State) | Flattening | High (≈ switch) | Yes | Ultimate\ntoken | — | Low | No | All\nunderflow | — | Low | No | All\nReading the table.\nif and goto add branches and conditions but no dispatcher, so their runtime cost is negligible — you can apply them broadly.\nThe flattening family (switch, case, call, value) and chain rebuild a method around a dispatcher. On a small method called in a tight loop tens of millions of times, a single flattening pass adds roughly an order of magnitude to that method's per-call time. Chained State stays within a few percent of switch despite being much harder to deobfuscate — the extra protection is essentially free relative to flattening itself.\ntoken and underflow are cheap at runtime but produce non-verifiable IL, so Babel disables them on .NET and .NET Core.\nInfo: These are worst-case figures from a micro-benchmark that does nothing but call one tiny flattened method in a loop. Most methods are not invoked in such hot loops, so the real-world impact of flattening is usually small — but it is still worth reserving flattening for the methods that matter and keeping it off hot paths."},{"page":39,"heading":"Control Flow Iterations","anchor":"control-flow-iterations","text":"The obfuscation impact of any control flow algorithm is primarily governed by the number of iterations applied to a method: the higher the count, the more complex the result — and, for the flattening algorithms, the higher the runtime cost, because each pass adds another layer of dispatch.\nBabel lets you set the iteration count with --iterations <n> (or ILIterations from MSBuild). Setting it to 0 disables control flow obfuscation. There is an upper limit beyond which a given method's flow can no longer be altered — it depends on the method's structure — so increasing the count does not always add more instructions."},{"page":39,"heading":"Limiting Control Flow Obfuscation","anchor":"limiting-control-flow-obfuscation","text":"Because flattening adds branches to every method it touches, applying it indiscriminately can slow down performance-critical code. Use XML rules to limit control flow obfuscation to the methods that need it and exclude the rest — for example, compiler-generated methods, which rarely contain intellectual property worth protecting:\n<Rules>\n  <Rule name=\"rule\" feature=\"control flow\" exclude=\"true\" applyToMembers=\"true\">\n    <Target>Classes</Target>\n    <Pattern>*</Pattern>\n    <HasAttribute onEnclosingType=\"false\">System.Runtime.CompilerServices.CompilerGeneratedAttribute</HasAttribute>\n  </Rule>\n</Rules>\nThis rule targets the control flow feature with exclude=\"true\", and applyToMembers=\"true\" extends it to all members of the matching classes. The <Target> element selects the kind of element (here, Classes), <Pattern> matches their names (* = all), and <HasAttribute> restricts the match to classes carrying CompilerGeneratedAttribute.\nThe same approach lets you exclude any method you know to be performance-critical, so you can balance protection against speed: flatten the sensitive code, and leave the hot paths untouched."},{"page":40,"heading":"","anchor":"","text":"Babel Obfuscator's Code Encryption feature allows users to encrypt their entire code to protect it from reverse engineering.\nBabel Obfuscator transforms the original method IL instruction into a new set of custom instructions that can include various obfuscation techniques that it makes more difficult to reverse engineer or modify the code. Once the new representation of the code has been constructed, it is encrypted using the chosen encryption algorithm (such as AES) to make it even more difficult to understand or modify.\nAt runtime, when the protected assembly is loaded into memory, the Babel Virtual Machine (BVM) is used to decrypt and execute the protected code. The BVM is a lightweight runtime engine included with the obfuscated assembly and provides the necessary functionality to decrypt the code, execute it, and ensure it runs correctly.\nDeploying on FIPS-enabled hosts? Because Code Encryption decrypts method bodies at runtime through the platform crypto provider, a container running on a FIPS-enabled host without a certified OpenSSL FIPS provider can fail to start. See FIPS Compliance for the cause and the fix."},{"page":40,"heading":"","anchor":"","text":"Code Encryption offers a strong level of protection against reverse engineering and intellectual property theft, but they also come with trade-offs in terms of application performance and complexity, so it is not recommended to apply it to the entire codebase. Instead, it is better to selectively apply this obfuscation technique to the most sensitive parts of the code that require protection while using other obfuscation techniques for the rest of the code. This way, you can strike a balance between security and performance.\nBefore Code Encryption\nAfter Code Encryption\nThe Babel Code Encryption is a completely managed solution. This means that the encrypted methods are not replaced by native code targeting a specific platform. This managed method solution ensures that the cross-platform nature of the .NET Framework is not compromised and allows the Just-In-Time (JIT) compiler to optimize code for the target CPU."},{"page":40,"heading":"Code Encryption Limits","anchor":"code-encryption-limits","text":"The Babel Code Encryption feature is not supported on .NET MAUI and Blazor assemblies due to the following key reasons:\nPlatform Constraints\n• Ahead-of-Time (AOT) Compilation: Platforms like iOS, which are central to .NET MAUI, rely on AOT compilation. This process compiles code into native binaries ahead of time, eliminating the possibility of dynamic code generation or modification at runtime, which is essential for code encryption and decryption.\nLimited Support for System.Reflection.Emit Namespace\n• Restricted IL Generation: The System.Reflection.Emit namespace, which is used for generating IL dynamically, has limited or no support on key platforms like iOS and WebAssembly (used by Blazor). Since code encryption often relies on dynamic IL manipulation, this limitation further hinders the implementation of encryption features in MAUI and Blazor.\nSecurity Restrictions\n• Sandboxed Environments: Both MAUI and Blazor operate in environments where apps are sandboxed for security. Platforms like iOS impose strict security measures that prevent any form of runtime code modification to protect against malicious code execution, making dynamic encryption impractical.\n• Risk of Code Injection: The dynamic code generation required for encryption and decryption poses significant security risks, including potential code injection vulnerabilities. MAUI and Blazor frameworks prioritize security by avoiding such risks."},{"page":40,"heading":"Code Encryption Limits","anchor":"code-encryption-limits","text":"Due to these constraints, .NET MAUI and Blazor do not support the Code Encryption feature, focusing instead on secure, portable, and platform-consistent development practices.\nMethods That Cannot Be Encrypted\nWithin a supported target, Code Encryption is applied on a per-method basis, and a few methods are automatically left unencrypted:\n• Instance constructors (.ctor) are never encrypted. This is by design: an instance must be fully initialized through its base constructor chain before it is used, and that guarantee cannot be preserved if the constructor body is relocated by Code Encryption. Note that this applies to instance constructors only — static constructors (.cctor) are not affected and are encrypted like any other method.\n• Methods with an unsupported signature are skipped automatically. Code Encryption relocates a method body into the Babel Virtual Machine (BVM) and calls it back through a uniform argument marshaller, so a few signature shapes cannot be expressed and are left unencrypted:\nGeneric methods — reported as EM0003.\nUnsupported return types — a ref (by-reference) return, a pointer return, a function-pointer return, or a ref struct (by-reference-like) return such as Span<T>/ReadOnlySpan<T>. Reported as EM0001.\nPointer or function-pointer parameters — reported as EM0002.\nref struct (by-reference-like) parameters such as Span<T>/ReadOnlySpan<T> — reported as EM0013."},{"page":40,"heading":"Code Encryption Limits","anchor":"code-encryption-limits","text":"These limits are inherent to the .NET runtime: a pointer or a ref struct cannot be boxed, so the BVM's argument marshaller cannot carry it. Everything else is supported, including ref/out/in parameters (of every element type, including structs, enums and by-reference reference types), value-type and generic-instance returns, exception handling, iterators and async methods. See the Warnings and Errors appendix for the full EM list.\nMethods excluded for these reasons are reported during the build and do not cause the obfuscation to fail — they are simply emitted unencrypted.\nPerformance Considerations\nAn encrypted method's body still runs as JIT-compiled code, so its internal work runs at close to native speed. What Code Encryption adds is a small per-call dispatch cost each time an encrypted method is entered (the arguments are marshalled to the BVM and the result marshalled back). That overhead is negligible for methods that do real work, but it can dominate for very small methods called in extremely hot loops (millions of calls). For this reason — and to keep the assembly small and fast — apply Code Encryption selectively to the sensitive methods that need protection rather than to the whole codebase, and avoid encrypting tiny, hot helper methods on a critical path."},{"page":40,"heading":"Enabling Code Encryption","anchor":"enabling-code-encryption","text":"Babel Obfuscator allows the user to selectively apply code encryption to specific methods in the codebase instead of encrypting the entire codebase. This is done to avoid the performance issues that can arise from encrypting large amounts of code.\nTo indicate which methods should be encrypted, the user can either use an XML rule or the Obfuscation attribute. With an XML rule, the user can specify the names of the methods that should be encrypted.\n<Rule name=\"encrypt code\" feature=\"msil encryption\" exclude=\"false\">\n  <Target>Methods</Target>\n  <Pattern>ACME.Algorithms::*</Pattern>\n  <Description>Encrypt all methods of Algorithm class.</Description>\n</Rule>\nAlternatively, the Obfuscation attribute can be used to mark individual methods for encryption by setting the \"Feature\" parameter to \"msil encryption\".\n[Obfuscation(Feature = \"msil encryption\", Exclude = false)]\npublic void ProcessData()\n{\n   // Encrypted code\n}\nBy enabling Code Encryption, the selected methods will be encrypted during the obfuscation process.\nCommand Line\nbabel myapp.exe --msilencryption\nRather than using XML rules or attributes, the switch command --msilencryption can optionally accept regular expressions to select the methods or types where code encryption should be enabled. For example, the following command:\nbabel myapp.exe --msilencryption ACME.LicenseManager::.*\nWill configure Babel to encrypt all the methods belonging to LicenseManager class in the ACME namespace.\nMSBuild Babel Task"},{"page":40,"heading":"Enabling Code Encryption","anchor":"enabling-code-encryption","text":"<PropertyGroup>\n  <MsilEncryption>true</MsilEncryption>\n</PropertyGroup>\n​\n<Babel MsilEncryption=\"$(MsilEncryption)\" />\nBabel Desktop\nSelect the assembly on the project canvas and, in the properties panel, enable MsilEncryption in the Code encryption group. Optionally, add a list of regular expressions to filter the namespaces or classes where code encryption should be applied. Leave the list empty if you selected the methods to encrypt using XML rules or the Obfuscation attribute. See Obfuscation Projects for how to work with projects in Babel Desktop.\nAfter the run, the Results view lists the encrypted methods, so you can check that code encryption was applied.\nThe code encryption statistics also appear in the output log (the Activity panel in Babel Desktop), which records each phase of the obfuscation, code encryption included.\nEncrypt Msil phase, elapsed time 00.579s\nEmbedded resource: omJYi\n   size : 13170 bytes\n\nMethod statistics:\n   194/[  252]    resources: 76.98 %\n\n   194/[  252]      overall: 76.98 %\n\nNumber of encrypted methods: 194\nBy examining the code encryption statistics in the output log, you can easily verify if code encryption has been applied to your code and gain insights into the level of protection it provides. It allows you to confirm that your sensitive code has been successfully encrypted, ensuring that it remains secure and resistant to unauthorized access."},{"page":41,"heading":"","anchor":"","text":"Switching demo to retail code with code encryption.\nCode encryption allows for the encryption of specific source methods in an application, which can then be switched out depending on the features that a user has access to. For example, if an application has both basic and advanced features, the encrypted source methods for the advanced features could be stored separately from the main application executable and only loaded at runtime if the user has a license that grants them access to those features. This Dynamic Code selection allows developers to create demo or trial version of their application with limited features and unlock additional functionality by providing users with a license key. Using code encryption, developers can protect their intellectual property while providing flexible licensing options for their users.\nDynamic Code provided by code encryption allows different versions of a method to be switched at runtime based on external conditions. For example, an application may have a limited set of features in demo mode, but with the presence of a valid license file, more advanced features are enabled. This can be achieved by encrypting the code for both the limited and advanced versions of the features and using a dynamic code selection mechanism to switch between them based on the presence or absence of the license file."},{"page":41,"heading":"Demo Application","anchor":"demo-application","text":"In the classical way of implementing a demo application, the retail code is already present in the demo version, and the license file allows the execution of advanced features. However, this approach has a significant drawback - the code that runs when the license file is present is not protected, and an attacker could bypass the license validation to unlock the licensed features.\nOn the other hand, with dynamic code selection, the code that unlocks advanced features is encrypted and cannot be executed in any way without the license file, which carries the encryption key to decrypt and execute the code. This provides better protection against reverse engineering and unauthorized access to advanced features. The license file serves as a unique key to unlock specific code sections, which makes it difficult for attackers to bypass the licensing mechanism and gain access to advanced features.\nConsider the following example project available on GitHub. The example source code can be obtained using Git from the command line by executing the following command:\ngit clone https://github.com/babelfornet/dynamic-code-example.git\nThe example shows how to use Dynamic Code to change the application behaviour based on the presence of specific files."},{"page":41,"heading":"Demo Application","anchor":"demo-application","text":"[Obfuscation(Feature = \"msil encryption:id=feature1;source=demo;internal=true;password=1234\", Exclude = false)]\npublic void Feature1Demo()\n{\n    Console.WriteLine(\"Feature1 Demo\");\n    Feature2Demo();\n}\n\n[Obfuscation(Feature = \"msil encryption:id=feature2;source=demo;internal=true;password=1234\", Exclude = false)]\npublic static void Feature2Demo()\n{\n    Console.WriteLine(\"Feature2 Demo\");\n}\nThese are two demo methods that have been tagged for replacement at runtime with different versions of the methods using dynamic code selection. The Feature1Demo()  and Feature2Demo() methods are encrypted using the Code Encryption feature with ID \"feature1\" and \"feature2\", respectively. The source of the encrypted code is specified as \"demo\", and the internal property is set to true to keep the encrypted code inside the assembly. The password for the encryption is set to \"1234\".\nWhen an application is executed without a valid license file, it is considered in demo mode. In such a case, the assembly will call the above two methods tagged to be replaced at runtime by Dynamic Code. These methods implement the basic functionality of the application, which may be limited compared to the fully licensed version.\nstatic void Main(string[] args)\n{\n    var app = new App();\n    app.Feature1Demo();\n}"},{"page":41,"heading":"Demo Application","anchor":"demo-application","text":"Now consider the following two methods, which will be the replacements for demo methods when the application is licensed. Note that the source is set to \"retail\" and the method with ID \"feature1\" Feature1Retail() will replace the Feature1Demo() while the one with the ID \"feature2\" Feature2Retail() will replace the Feature2Demo() in case a license file is found.\n[Obfuscation(Feature = \"msil encryption:id=feature1;source=retail;internal=true;password=4567\", Exclude = false)]\npublic static void Feature1Retail()\n{\n    Console.WriteLine(\"Feature1 Retail\");\n    Feature2Retail();\n}\n\n[Obfuscation(Feature = \"msil encryption:id=feature2;source=retail;internal=true;password=4567\", Exclude = false)]\npublic static void Feature2Retail()\n{\n    Console.WriteLine(\"Feature2 Retail\");\n}\nThe above two methods are not called at runtime by the assembly, which runs in demo mode, and are encrypted with a password different from the one used for the demo methods. This password is unavailable to the application code because Babel will remove the information during the obfuscation process after encrypting the methods.\nWe need a way to dynamically switch between \"demo\" and \"retail\" with code encryption. As the above methods were encrypted with a password, we must define the Babel code encryption entry point to retrieve the password at runtime."},{"page":41,"heading":"Demo Application","anchor":"demo-application","text":"[Obfuscation(Feature = \"msil encryption get password\", Exclude = false)]\ninternal static string GetPassword(string source)\n{\n    Console.WriteLine($\"> Get {source} password\");\n\n    if (source == \"demo\")\n        return \"1234\";\n\n    string pwd = File.ReadAllText(source + \".txt\");\n\n    Console.WriteLine($\">> {source} password: {pwd}\");\n    return pwd;\n}\nThe GetPassword() method is used by the BVM (Bytecode Virtual Machine) to retrieve the password needed to decrypt an encrypted method when it is called during program execution.\nIf the source name is \"demo,\" the method returns a hardcoded password of \"1234\", which is the password used to encrypt \"demo\" methods Feature1Demo() and Feature2Demo(). Otherwise, it reads the password from a text file with the same name as the source and a \".txt\" extension. The password is then returned to the caller. Note that the demo password is stored inside the code as the application can always run in demo mode, and there is no need to hide this password.\nThe switch between \"demo\" and \"retail\" sources is made by the GetSourceStream() method called by BVM when a call to one of the encrypted methods gets called."},{"page":41,"heading":"Demo Application","anchor":"demo-application","text":"[Obfuscation(Feature = \"msil encryption get stream\", Exclude = false)]\ninternal static object GetSourceStream(string source)\n{\n    Console.WriteLine($\"> Get {source} stream\");\n\n    if (source == \"demo\")\n    {\n        string[] sources = { \"retail\", \"special\" };\n        foreach (var src in sources)\n        {\n            if (File.Exists($\"{src}.txt\"))\n            {\n                Console.WriteLine($\">> Switch to {src}\");\n                return src;\n            }\n        }\n\n        return null;\n    }\n    \n    // External sources\n    if (File.Exists(source + \".eil\"))\n    {\n        Console.WriteLine($\">>> Read {source} stream\");\n        return File.OpenRead(source + \".eil\");\n    }\n\n    return null;\n}\nThis method plays a crucial role in dynamically selecting the appropriate encrypted methods source based on external conditions, such as the presence of a license file. In fact, when the application starts, it calls demo methods which can be decrypted by the password returned by the GetPassword() method."},{"page":41,"heading":"Demo Application","anchor":"demo-application","text":"In the context of dynamic code selection, the BVM (Binary Virtual Machine) is responsible for executing the encrypted code and switching between different versions of a method based on external conditions. Before running any \"demo\" method, the BVM calls the GetSourceStream() method, passing \"demo\" as a parameter. Since the \"demo\" methods are internal to the assembly, we do not need to return any demo source stream. However, if the \"retail.txt\" file is found, we want to switch to the \"retail\" source code, so we need to inform the BVM that we want to execute the \"retail\" source by returning the string \"retail\" from the GetSourceStream() method.\nOnce the BVM receives the string \"retail\" from GetSourceStream(), it knows that it needs to execute the \"retail\" code. The BVM then makes a call to GetPassword() with the argument \"retail\". GetPassword() reads the password for the \"retail\" version from the retail.txt file and returns it to the BVM, which uses it to decrypt the \"retail\" code. Once the \"retail\" code is decrypted, it is executed instead of the \"demo\" code. In this way, the application is able to switch between different versions of encrypted code at runtime based on the presence or absence of a license file without requiring the code to be recompiled or redeployed."},{"page":41,"heading":"Demo Application","anchor":"demo-application","text":"Dynamic Code allows the definition of multiple internal and external sources. For example, you can declare another external source \"special\" that can be loaded instead of the \"retail\" code when the file special.txt containing the password for decrypting code is present.\n[Obfuscation(Feature = \"msil encryption:id=feature1;source=special;internal=false;password=0000\", Exclude = false)]\npublic static void Feature1Special()\n{\n    Console.WriteLine(\"Feature1 Special\");\n    Feature2Special();\n}\n\n[Obfuscation(Feature = \"msil encryption:id=feature2;source=special;internal=false;password=0000\", Exclude = false)]\npublic static void Feature2Special()\n{\n    Console.WriteLine(\"Feature2 Special\");\n}\nThe given code shows two methods, Feature1Special() and Feature2Special(), that are tagged with Obfuscation attributes, where the \"internal\" property is set to \"false\". This means that the obfuscated code for these methods will be generated in an external file with the extension \".eil\" and not included within the assembly itself. The encrypted code external \".eil\" file can be loaded and decrypted at runtime using the appropriate password specified in the Obfuscation attributes."},{"page":41,"heading":"Demo Application","anchor":"demo-application","text":"To run the example provided, first compile the solution in debug configuration. Then open the obfuscate.babel project in Babel Desktop and run it. The project does not set an output path, so Babel Desktop writes the obfuscated assembly to a BabelOut folder beside the input assembly. After that, copy the files DynamicCode.exe, DynamicCode.runtimeconfig.json, and DynamicCode.deps.json into the BabelOut folder. Next, from a PowerShell window, run the DynamicCode.exe in the BabelOut folder, and you should see the output:\n> Get demo stream\n> Get demo password\nFeature1 Demo\nFeature2 Demo\nTo test the \"retail\" source, copy the retail.txt file inside the BabelOut folder and run the DynamicCode.exe. The output should be:\n> Get demo stream\n>> Switch to retail\n> Get retail password\n>> retail password: 4567\nFeature1 Retail\nFeature2 Retail\nTo test the \"special\" source, copy the special.txt file inside the BabelOut folder and run the DynamicCode.exe. The output should be:\n> Get demo stream\n>> Switch to special\n> Get special stream\n>>> Read special stream\n> Get special password\n>> special password: 0000\nFeature1 Special\nFeature2 Special"},{"page":42,"heading":"","anchor":"","text":"When code encryption is applied to a method, Babel Obfuscator can extract the encrypted code of that method and store it as a separate binary file outside of the target assembly. This binary file will contain the encrypted MSIL code of the method, and it can be loaded into memory at runtime by the BVM when the method is called.\nInfo: Since the encrypted code is not present in the main executable, it can be deployed separately from the application. This allows for various scenarios, including creating feature-based licenses where the external file containing the encrypted code can be deployed alongside the license.\nTo generate encrypted files for specific methods, we need to tag the encrypted methods using the Source property of the \"msil encryption\" feature. This tells Babel which methods to encrypt and strip out to a separate file. The Source property is one of the XML properties available for the \"msil encryption\" feature, along with Cache, MinInstructionCount, and MaxInstructionCount (see XML Rules). By setting a unique name for the Source property, we can associate it with all the methods captured by the rule and generate a separate file containing the encrypted data for those methods.\n<Rule name=\"encrypt algorithms\" feature=\"msil encryption\" exclude=\"false\">\n  <Target>Methods</Target>\n  <Pattern>ACME.Algorithms::*</Pattern>\n  <Properties>\n     <Source>algorithms</Source>\n  </Properties>\n  <Description>Encrypt code in Algorithms class.</Description>\n</Rule>"},{"page":42,"heading":"","anchor":"","text":"This rule for the msil encryption feature, tells Babel Obfuscator to encrypt all the methods inside the Algorithm. It also sets the Source property to \"algorithms\", which will make Babel store the encrypted byte code in an external file named \"algorithms.eil\".\nWhen a call is made to any method in the Algorithms class at runtime, the BVM needs to retrieve the encrypted bytecode stored in the external file algorithms.eil. To do this, the BVM will look for a method with the following signature:\n[Obfuscation(Feature=\"msil encryption get stream\")]\ninternal static Stream GetSourceStream(string source)\nThis method should be decorated with the System.Reflection.ObfuscationAttribute attribute and the feature \"msil encryption get stream\". Once the BVM finds this method, it will call it with the name of the encrypted data source associated with the encrypted methods (in this case, \"algorithms\"). The GetSourceStream method should then return a Stream object containing the encrypted bytecode for the requested data source. The BVM can then decrypt and execute the requested method."},{"page":43,"heading":"","anchor":"","text":"Bind a .NET application to a hardware licensing dongle so that swapped or\nstubbed dongle DLLs cannot bypass Code Encryption.\nVendors of hardware licensing dongles — KEYLOK, SafeNet Sentinel, Wibu CodeMeter, Marx CrypToken, and similar — ship a native DLL that their customers P/Invoke from .NET to authenticate against the physical device. The headline threat against such integrations is DLL replacement: an attacker substitutes the vendor's DLL with a stub that returns \"license valid\" for every call, and the protected application happily proceeds.\nThis article describes a pattern that closes that attack by combining Babel Obfuscator's Code Encryption with three additional defensive layers. A runnable reference PoC is available for download at the end of the page."},{"page":43,"heading":"The wrong mental model","anchor":"the-wrong-mental-model","text":"The naive approach is to use the dongle as a Boolean licence gate:\nif (!Keylok.IsAuthenticated()) Environment.Exit(1);\nRunBusinessLogic();\nThis collapses under a one-line DLL swap. A fake Keylok.dll that returns true for every call defeats the check entirely. Encrypting just the IsAuthenticated wrapper does not help either, because that wrapper has to call the native DLL one way or another — if the DLL is faked, the wrapper has nothing to verify against."},{"page":43,"heading":"The right mental model","anchor":"the-right-mental-model","text":"The dongle is not a licence checker. It is a decryption oracle.\nCode Encryption transforms IL method bodies into Babel-VM bytecode and encrypts them with an AES key derived from a password. The password is provided at run time by a password callback method. In a hardware-bound integration, that callback queries the dongle for the password rather than reading it from a license file:\nmanaged business code  --(encrypted with password K)\n  native dongle DLL      --(plain, talks to the dongle hardware)\n  dongle hardware        --(stores K behind tamper-resistant crypto)\nA swapped DLL is no longer a problem. It can lie about anything it likes, but it cannot fabricate the password — without it, the Babel Virtual Machine has nothing to decrypt and the application becomes inert.\nInfo: The native DLL cannot be encrypted by Babel — it is unmanaged code and the dongle vendor controls it. The trick is that the native DLL does not need to be encrypted: encrypting the managed business logic that uses the dongle achieves the same goal, because a fake DLL is unable to release the decryption password."},{"page":43,"heading":"Glossary","anchor":"glossary","text":"The rest of this article refers to a small set of symbols and operations. Skim the table once before reading the layers below; everything else builds on it."},{"page":43,"heading":"Glossary","anchor":"glossary","text":"Symbol | Name | Where it lives | Who creates it | What it is\nK | Babel password (core) | On the dongle (wrapped), released at runtime | The developer, at packaging time | The password Babel uses to encrypt and decrypt the business methods. Per-customer in production.\nHK | Hardware key | Inside the dongle silicon, never readable | The dongle vendor, at provisioning time | The dongle's tamper-resistant key. Used by the dongle to wrap and unwrap data on the device itself.\ntoken | Wrapped password | Embedded resource in the obfuscated assembly | The developer, at packaging time | token = wrap(K, HK). Useless without the dongle, which is the only entity that can recover K.\nB | Bootstrap password | Consumed at obfuscation; [Obfuscation] attribute stripped from the output | The developer, once per product | Fixed password that encrypts the password-fetch code (the chained-encryption layer).\nL | Liveness password | Consumed at obfuscation; [Obfuscation] attribute stripped from the output | The developer, once per product | Fixed password that encrypts the challenge/response verifier code.\nI | Integrity password | Consumed at obfuscation; [Obfuscation] attribute stripped from the output | The developer, once per product | Fixed password that encrypts the native-DLL signature-pinning code.\nnonce | Fresh random bytes | Generated in memory at every call | The application, at runtime | A 16-byte random challenge sent to the dongle. Different every call, so responses cannot be replayed."},{"page":43,"heading":"Glossary","anchor":"glossary","text":"K_i / HK_i | Per-customer variants | One pair per shipped license | The developer at delivery time | Each customer gets a unique K_i in their build and a unique HK_i provisioned on their dongle.\nA few terms about the operations themselves:\nwrap / unwrap — the dongle's pair of cryptographic operations. wrap(K, HK) produces the token at packaging time (typically AES encryption using HK as key); the dongle performs the matching unwrap(token, HK) at runtime and returns K. The vendor's native DLL is the courier; the actual crypto runs inside the dongle.\nsource — a Babel concept: a named group of encrypted methods that share a password. Each [Obfuscation(Feature=\"msil encryption:source=<name>;...\")] attribute assigns its method to a source. This article uses four sources: core (business code, password K), bootstrap (password fetch, password B), liveness (verifier, password L), and integrity (DLL check, password I).\npassword callback — the static method Babel calls at runtime to obtain the password for a given source. Marked with [Obfuscation(Feature=\"msil encryption get password\")]. See Password Protected Code for the base mechanism."},{"page":43,"heading":"Four defensive layers","anchor":"four-defensive-layers","text":"A production-quality integration combines four layers.\n1. Code Encryption with a dongle-supplied password\nApply msil encryption to the business-critical methods using a per-product password, then implement Babel's password callback so that it asks the dongle to unwrap a stored token into K:\n[Obfuscation(\n    Feature = \"msil encryption:source=core;password=<K>;internal=true\",\n    Exclude = false)]\npublic static decimal ComputeQuote(decimal basePrice, int quantity)\n{\n    // real business logic\n}\n\n[Obfuscation(Feature = \"msil encryption get password\", Exclude = false)]\ninternal static string GetEncryptionPassword(string source)\n{\n    return Inner(source);\n}\nInner reads a ciphertext (the token) from an embedded resource, passes it to the dongle, and returns the plaintext password. At packaging time the developer computes token = wrap(K, HK) once, where HK is the hardware-protected key already provisioned on the customer's dongle.\n2. Chained encryption of the callback itself\nThe callback Inner is itself a juicy target for an attacker who wants to short-circuit the dongle. Encrypt it under a second, fixed password:"},{"page":43,"heading":"Four defensive layers","anchor":"four-defensive-layers","text":"[Obfuscation(\n    Feature = \"msil encryption:source=bootstrap;password=<B>;internal=true\",\n    Exclude = false)]\nprivate static string Inner(string source)\n{\n    byte[] token = LoadToken(source);\n    byte[] plain = new byte[token.Length];\n    int rc = KeylokInterop.DongleUnwrap(\n        token, token.Length, plain, plain.Length, out int written);\n    if (rc != 0) throw new InvalidOperationException(\"Dongle unwrap failed\");\n    return Encoding.ASCII.GetString(plain, 0, written);\n}\nB is supplied to Babel at obfuscation time and consumed there: Babel strips the [Obfuscation] attribute from the output assembly entirely. The password does not appear in the shipped binary as metadata, as a custom-attribute blob, or as a plain-text string a decompiler could surface. Recovering it requires defeating Babel's own internal protection of the encrypted method body — a meaningfully harder task than reading a constant out of a .dll. Its only job is to protect the dongle-query algorithm from static analysis: combined with control-flow obfuscation and string encryption, this is enough to deter all but the most determined reverse engineer.\n3. Per-call liveness check inside encrypted code\nThis is the layer that closes the sniff-and-replay attack:\nAn attacker borrows a real dongle, hooks the managed code, captures the unwrapped K, and ships a fake DLL that returns K directly. Babel's decryption succeeds with the captured K and the business methods appear to run."},{"page":43,"heading":"Four defensive layers","anchor":"four-defensive-layers","text":"The fix is to have the business methods themselves (already encrypted under source=core) perform a fresh challenge/response with the dongle on every invocation:\n[Obfuscation(Feature = \"msil encryption:source=core;password=<K>;internal=true\",\n             Exclude = false)]\npublic static decimal ComputeQuote(decimal basePrice, int quantity)\n{\n    if (!DongleLiveness.Verify()) return -1m;   // silent sabotage\n    // real business logic\n}\n\n[Obfuscation(Feature = \"msil encryption:source=liveness;password=<L>;internal=true\",\n             Exclude = false)]\ninternal static bool Verify()\n{\n    byte[] nonce = RandomNumberGenerator.GetBytes(16);\n    byte[] resp  = new byte[16];\n    int rc = KeylokInterop.DongleChallenge(nonce, resp);\n    if (rc != 0) return false;\n\n    byte[] expected = ComputeExpectedMac(nonce);   // uses a public verifier\n    return CryptographicOperations.FixedTimeEquals(resp, expected);\n}\nThe captured K lets Babel decrypt Verify itself, but does not contain the dongle's challenge-response secret — the fresh nonce cannot be answered without the dongle. Asymmetric dongles (ECDSA, RSA) make this airtight; symmetric dongles still raise the bar significantly, because the verifier key only lives in encrypted code.\nTwo important tactics inside Verify:"},{"page":43,"heading":"Four defensive layers","anchor":"four-defensive-layers","text":"Fresh nonce per call. No memoisation, no caching.\nSilent sabotage on failure (return a wrong value, an empty result, a corrupted byte), not throw. An exception betrays the location of the check; a wrong number does not. The attacker discovers the check only by comparing many runs against a reference.\n4. Native DLL integrity pinning\nIndependent of the dongle's correctness, the application can verify the identity of the DLL it is about to call:\n[Obfuscation(Feature = \"msil encryption:source=integrity;password=<I>;internal=true\",\n             Exclude = false)]\ninternal static bool VerifyNativeDll(string path)\n{\n    var cert = X509Certificate.CreateFromSignedFile(path);\n    const string EXPECTED_THUMBPRINT = \"AABBCC...\";   // pinned at build time\n    return WinTrust.VerifyAuthenticode(path)\n        && cert.GetCertHashString().Equals(EXPECTED_THUMBPRINT,\n            StringComparison.OrdinalIgnoreCase);\n}\nThe certificate thumbprint of the vendor's publisher (KEYLOK Inc., Thales-SafeNet, Wibu-Systems, …) is pinned inside an encrypted integrity source. This blocks substitution with any DLL not signed by the legitimate vendor — including DLLs that pass the liveness check because they secretly forward to a real dongle.\nTogether with Babel's Tampering Detection, which injects post-obfuscation integrity checks into the assembly itself, this gives five active defences against the modify-and-redistribute attack."},{"page":43,"heading":"Per-customer keying","anchor":"per-customer-keying","text":"A single shared K across all customers creates a class-break risk: a successful crack of one installation releases the whole product family. The recommended deployment is per-customer Babel builds:\nProvision the dongle\nProvision the customer's dongle with a uniquely generated hardware key HK_i and a uniquely generated Babel password K_i.\nRebuild with the customer's password\nAt delivery time, re-run Babel against that customer's source tree with K_i substituted into the [Obfuscation] attributes (or supplied via XML rules).\nEmbed the wrapped token\nCompute token_i = wrap(K_i, HK_i) and embed it in the build.\nCracking customer i requires extracting K_i from their installation and HK_i from their dongle. Neither helps with customer j. The operational cost is one Babel build per delivery, which is automatable in CI in a few minutes per customer."},{"page":43,"heading":"Threat model summary","anchor":"threat-model-summary","text":"Threat | Closed by\nStatic decompilation of the business logic | Code Encryption (core)\nReplacement with a return success stub DLL | Code Encryption + Liveness\nHooking the managed password callback | Chained encryption + Tampering Detection\nCapture of K followed by a fake DLL with hardcoded K | Liveness check\nPatching the IL to remove Verify() calls | Tampering Detection\nReplacement with a differently-signed DLL | Authenticode pinning\nCompromise spreading across customers | Per-customer keying\nSkipping the Babel Virtual Machine entirely | Methods do real work, not gating"},{"page":43,"heading":"Practical checklist","anchor":"practical-checklist","text":"Apply msil encryption with source=core to business methods.\nApply msil encryption with source=bootstrap to the password fetch.\nApply msil encryption with source=liveness to the verifier.\nApply msil encryption with source=integrity to the DLL check.\nImplement [Obfuscation(Feature=\"msil encryption get password\")].\nEmbed the wrapped token as a resource.\nBuild with --tamperingdetection --antidebugging --controlflow --stringencryption.\nSign the assembly (SignAssembly=true).\nPin the native DLL's Authenticode thumbprint.\nIssue per-customer builds with unique K_i."},{"page":43,"heading":"Reference implementation","anchor":"reference-implementation","text":"Note: Download: HardwareDongleBinding.zip (20 KB)\nThe zip contains a self-contained runnable proof of concept. It uses a mock native DLL with XOR primitives so that it builds without any external dependencies; the structure is identical to a production integration that replaces the mock with the vendor's real native library.\nPrerequisites\nThe PoC builds and runs on Windows, macOS and Linux. Pick the row for your platform:\nPlatform | C toolchain | PowerShell | .NET | Babel\nWindows | Visual Studio 2022 Developer Command Prompt | built-in powershell.exe | .NET 8 SDK | babel.exe on PATH\nmacOS | Xcode Command Line Tools (xcode-select --install) | pwsh (brew install powershell) | .NET 8 SDK | babel from a babel_net80/babel_net90/babel_net100 zip package, or the Babel.Obfuscator.Tool dotnet tool, on PATH\nLinux | cc / clang (apt install build-essential) | pwsh | .NET 8 SDK | babel on PATH\nBuild\n# 1. Extract the zip\nExpand-Archive HardwareDongleBinding.zip -DestinationPath .   # Windows\n# or:  unzip HardwareDongleBinding.zip                         # macOS / Linux\ncd HardwareDongleBinding\n\n# 2. End-to-end build: tokens, managed app, obfuscation, native libs\n./Scripts/build.ps1\nOn Windows open a Visual Studio Developer Command Prompt first so that cl.exe is on PATH; on macOS / Linux run from any shell.  build.ps1 performs five steps:"},{"page":43,"heading":"Reference implementation","anchor":"reference-implementation","text":"Wrap each per-source Babel password with the mock dongle's HK and write the resulting token files into DongleBindingDemo/Tokens/*.bin.\nBuild the managed project with dotnet build -c Release.\nObfuscate the resulting assembly with Babel: --tamperingdetection --antidebugging --controlflow --stringencryption.\nCompile the three native variants with the platform's C compiler:\nWindows: DongleMock.dll, DongleMock_Fake.dll, DongleMock_Sniff.dll via cl.exe.\nmacOS: libDongleMock.dylib, libDongleMock_Fake.dylib, libDongleMock_Sniff.dylib via clang.\nLinux: libDongleMock.so, libDongleMock_Fake.so, libDongleMock_Sniff.so via cc.\nStage the genuine library next to the obfuscated assembly.\nThe C# [DllImport(\"DongleMock\")] resolves to the platform-appropriate filename automatically.\nThree scenarios\n./Scripts/run-legit.ps1           # OK\n./Scripts/run-swap-attack.ps1     # BLOCKED: Babel cannot decrypt\n./Scripts/run-sniff-attack.ps1    # BLOCKED: liveness check fails\nLegitimate run — the genuine mock dongle is in place; business methods decrypt and execute:\nComputeQuote(120, 250, 0.15) = 24225.00\n  GenerateReportToken(ACME)    = REPORT-ACME CORP-XXXXXXXX\n  Result: OK\nSwap attack — replaces DongleMock.dll with a stub that returns zeros for every call. Babel derives the wrong password from those zero bytes and cannot decrypt the method bodies:\n[EXCEPTION] ...: BVM decryption failed\n  Result: BLOCKED"},{"page":43,"heading":"Reference implementation","anchor":"reference-implementation","text":"Sniff/replay attack — the more interesting attack: the fake DLL returns the captured Babel password directly, so decryption succeeds. The per-call liveness check inside each business method nevertheless detects the missing dongle (the fake cannot answer a fresh challenge) and each method short-circuits into its silent sabotage branch:\nComputeQuote(120, 250, 0.15) = -1\n  GenerateReportToken(ACME)    = REPORT-UNAVAILABLE\n  Result: BLOCKED\nEach scenario corresponds to a row in the threat model table above.\nAdapting to a real dongle\nTo turn the PoC into a production integration, change four files:\nFile | What to change\nDongleBindingDemo/KeylokInterop.cs | Replace DongleMock with the vendor's DLL name; align signatures with the vendor's API.\nDongleBindingDemo/DongleAuth.cs | Replace the XOR-style unwrap with the vendor's AES read-protection call.\nDongleBindingDemo/DongleLiveness.cs | Replace the XOR challenge with the vendor's challenge/response API (HMAC, ECDSA, …).\nDongleBindingDemo/ProtectedLogic.cs | Move your real business methods under source=core; keep the DongleLiveness.Verify() guard.\nThe Babel [Obfuscation] attributes, the tampering hook, and the build scripts require no changes."},{"page":43,"heading":"Related reading","anchor":"related-reading","text":"Code Encryption\nPassword Protected Code\nExternal Code Files\nTampering Detection\nAnti-Debugging"},{"page":44,"heading":"","anchor":"","text":"License-bound code encryption is a variation of Password Protected Code in which the password that unlocks an encrypted method is not a fixed constant baked into the build, but a value read from the customer's license at runtime.\nThe protected method still ships inside the obfuscated assembly, but its code stays encrypted until a valid license supplies the correct password. This means a sensitive or premium feature only runs for users whose license authorizes it, while the rest of the application keeps working normally for everyone else.\nInfo: This is the pattern Babel Obfuscator uses internally to gate its own licensed features. It layers on top of the regular code encryption you already know — there is nothing new to install, only a rule and a small hook to write."},{"page":44,"heading":"How it works","anchor":"how-it-works","text":"Mark the code to protect. An XML rule (or the Obfuscation attribute) selects the methods or types to encrypt and assigns them a source name and a password, keeping the encrypted code inside the assembly (Internal = true).\nProvide a get-password hook. A method marked [Obfuscation(Feature = \"msil encryption get password\")] receives the source name and returns the password for that source by reading a field of the loaded license.\nRun. When the protected method is first called, the Babel Virtual Machine (BVM) invokes the hook to obtain the password for the source. If the license carries the expected field, the method is decrypted and executed; if the field is missing or the value is wrong, decryption fails and the method cannot run — so the feature is effectively locked.\nOnly the methods matched by a rule with a <Source> are license-bound. Methods encrypted with plain --msilencryption (no source) are unlocked from the assembly itself and keep running without a license, so the unlicensed application continues to work — only the license-gated features are withheld."},{"page":44,"heading":"Encrypting the code","anchor":"encrypting-the-code","text":"Add a rule that encrypts the sensitive code and binds it to a named source and password:\n<Rule name=\"encrypt premium\" feature=\"msil encryption\" exclude=\"false\">\n  <Target>Methods</Target>\n  <Pattern>ACME.Premium::*</Pattern>\n  <Properties>\n     <Source>premium</Source>\n     <Password>Xa9!k2$LpQ7r</Password>\n     <Internal>true</Internal>\n  </Properties>\n  <Description>Encrypt the premium feature, unlocked by the license.</Description>\n</Rule>\nThe same can be expressed inline with the Obfuscation attribute:\n[Obfuscation(Feature = \"msil encryption:internal=true;source=premium;password=Xa9!k2$LpQ7r\", Exclude = false)]\ninternal class Premium\n{\n   public string Run() => \"premium result\";\n}\nWarning: The <Password> you set at build time must match the value the get-password hook returns for that source at runtime. In a license-bound design the hook reads that value from the license, so store the same value in the license field you issue to your customers."},{"page":44,"heading":"Reading the password from the license","anchor":"reading-the-password-from-the-license","text":"Declare a single hook that maps a source name to the password held in the license. The example below uses Babel Licensing to look up a licensed feature and return its value:\n[Obfuscation(Feature = \"msil encryption get password\")]\ninternal static string GetSourcePassword(string source)\n{\n   var license = LicenseManager.Instance.License;\n\n   var feature = license.Features.FirstOrDefault(f => f.Name == source);\n   if (feature == null)\n      throw new ApplicationException($\"feature '{source}' is not licensed\");\n\n   return Encoding.UTF8.GetString(feature.Data);\n}\nAt runtime the BVM calls GetSourcePassword(\"premium\"); the hook returns the password stored in the customer's license, and the premium method decrypts and runs.\nInfo: The hook must be reachable by the code Babel injects, so declare it public or internal. If you leave it private or protected, Babel widens it to internal automatically during obfuscation (it is never made public), so the injected code can call it.\nFor a complete, runnable implementation — including the LicenseManager class and how to issue per-edition licenses — see the Feature Based Licenses example."},{"page":44,"heading":"Works with every license delivery method","anchor":"works-with-every-license-delivery-method","text":"Because the hook simply reads from the loaded license object, license-bound code encryption is independent of how that license reaches the application. It works unchanged with all of Babel Licensing's delivery methods:\nLicense File — a signed license file shipped or downloaded to the client.\nFloating License — seats leased from a Babel Licensing Service.\nLicense Activation — a license activated and bound to the machine.\nWhichever mode you choose, once your licensing code has validated and loaded the license, the get-password hook can read the field it needs and the protected feature unlocks.\nInfo: Prefer to keep the encrypted code out of the main assembly entirely? Combine this pattern with External Code Files to deploy the encrypted method alongside the license."},{"page":45,"heading":"","anchor":"","text":"In some cases, keeping the encrypted code inside the obfuscated assembly may be preferred rather than storing it in external files. In this case, access to the encrypted code is protected by a password, which significantly reduces the amount of information needed to reconstruct the method while maintaining the same level of security. Without the password, the Babel Virtual Machine (BVM) cannot reconstruct the original method, rendering the encrypted code useless. This approach provides a balance between security and performance, as the encrypted code is stored within the assembly and can be accessed quickly when needed.\nTo define which code will be encrypted with a password, we need an XML rule specifying the method or type to be encrypted, the source name, and the password used. Here's an example of such a rule:\n<Rule name=\"encrypt algorithms\" feature=\"msil encryption\" exclude=\"false\">\n  <Target>Methods</Target>\n  <Pattern>ACME.Algorithms::*</Pattern>\n  <Properties>\n     <Source>algorithms</Source>\n     <Password>mySecretPassword</Password>\n     <Internal>true</Internal>\n  </Properties>\n  <Description>Encrypt code in the Algorithms class using a password.</Description>\n</Rule>\nNote that the rules contain the property Internal set to true to instruct Babel to store the encrypted code inside the obfuscated assembly rather than in an external file."},{"page":45,"heading":"","anchor":"","text":"As the encrypted code is stored inside the obfuscated assembly, there is no need to define the GetSourceStream method to retrieve the encrypted stream. Instead, we need to declare another method that will be called by the BVM to retrieve the password needed to decrypt and execute the method.\n[Obfuscation(Feature=\"msil encryption get password\")]\ninternal static string GetSourcePassword(string source)\nAt runtime, the BVM will call the GetSourcePassword with the name of the encrypted data source associated with the encrypted methods (in this case, \"algorithms\"). The GetSourcePassword method should return the password to decrypt the bytecode for the requested data source. The BVM can then execute the requested method.\nInstead of returning a fixed password, the hook can return a value read from the customer's license, so that a protected feature only unlocks for licensed users. See License-Bound Code Encryption."},{"page":46,"heading":"","anchor":"","text":"Dynamic Proxy protection is a powerful feature offered by Babel Obfuscator that enhances the obfuscation and protection of your application's code. It allows you to hide method calls to both external and internal code by generating dynamic proxy classes.\nWhen dynamic proxy protection is enabled, Babel Obfuscator creates delegate types or proxy classes that act as intermediaries for method calls. These proxy classes are dynamically built during the obfuscation process and are used to replace the original method calls in your code.\nThe main advantage of dynamic proxies is that they effectively obscure the actual method calls, making it much more difficult for attackers or reverse engineers to understand and analyze the code flow. By utilizing dynamic proxies, you can prevent direct access to sensitive methods and obscure the application logic.\nThis section covers:\nHow Dynamic Proxy Works and platform limitations\nInternal and External Calls — the proxy modes and what they protect\nCoverage — which calls are proxied and which stay direct\nFilters — proxy only the calls you choose\nConfiguration — CLI, MSBuild and Babel Desktop\nPerformance and Deobfuscation Resistance"},{"page":46,"heading":"How Dynamic Proxy Works","anchor":"how-dynamic-proxy-works","text":"At build time, for each protected call Babel Obfuscator generates a small proxy delegate type and rewrites the original call, callvirt or newobj instruction so that it is routed through that proxy. The real target — its declaring type, the method, and the field that will hold the resolved call — is no longer referenced directly by the rewritten code. Instead it is recovered by a tiny injected resolver the first time each proxied call executes, and then cached so that subsequent calls go straight through.\nTwo properties follow from this design:\nStatic analysis is disrupted. The rewritten call sites no longer carry a direct metadata reference to the target, so decompilers and automated deobfuscators cannot reconstruct the original call graph from metadata alone. The way targets are encoded is also varied from build to build, so tools cannot rely on fixed patterns — see Deobfuscation Resistance.\nResolution is lazy and cached. The first call to a given proxied member pays a small one-time cost to resolve the target and wire up the delegate; every later call runs through the cached delegate with negligible overhead — see Performance.\nProxying is purely a managed, build-time transformation: it does not require the .NET Framework, works on .NET and .NET Framework, and does not change the observable behavior of your program (subject to the small set of calls listed under Coverage that are intentionally left direct)."},{"page":46,"heading":"AOT and Platform Compatibility Limitations","anchor":"aot-and-platform-compatibility-limitations","text":"Dynamic Proxy is currently not supported on .NET MAUI and Blazor assemblies due to a combination of platform limitations and runtime restrictions that prevent safe or consistent proxy generation and execution in these environments.\nPlatform Constraints\nAhead-of-Time (AOT) Compilation: Platforms such as iOS (used by .NET MAUI) and WebAssembly (used by Blazor WebAssembly) enforce AOT compilation. This eliminates the use of runtime features like reflection-based code emission or runtime type generation. While Babel’s DynamicProxy does not use runtime code generation, its generated proxy logic can depend on metadata and IL constructs that are either stripped or unsupported in AOT-compiled environments.\nIL Compatibility Limitations\nUnsupported Metadata Tokens: The dynamic proxy mechanism injects intermediate call layers through generated proxy types and delegate stubs. These rely on metadata tokens and indirection mechanisms that may not be verifiable or are outright unsupported in certain AOT targets, leading to runtime validation failures or application crashes.\nBlazor/WebAssembly Limitations\nRestricted Reflection Capabilities: In Blazor WebAssembly, reflection is severely limited. Since DynamicProxy often wraps or intercepts method calls, it may result in indirect invocation paths that are incompatible with the linking and tree-shaking process used in WebAssembly publishing workflows.\nRecommendation"},{"page":46,"heading":"AOT and Platform Compatibility Limitations","anchor":"aot-and-platform-compatibility-limitations","text":"For full compatibility with AOT environments like .NET MAUI and Blazor, it is recommended to set DynamicProxy=false. This ensures the generated assemblies remain fully verifiable, platform-compliant, and free of features that may fail during native linking or runtime startup."},{"page":47,"heading":"","anchor":"","text":"Dynamic Proxy can be applied to two categories of calls, selected by the proxy mode:\nMode | Proxies calls to…\nexternal | methods and constructors defined outside the assembly being obfuscated — the .NET base class library and referenced assemblies\ninternal | methods and constructors defined inside the assembly being obfuscated\nall | both internal and external calls\nSee Configuration to select a mode from the command line, MSBuild or Babel Desktop."},{"page":47,"heading":"Internal Proxy Calls","anchor":"internal-proxy-calls","text":"Using Dynamic Proxy for internal method calls offers several advantages in terms of code obfuscation and protection. Here are some key benefits:\nConcealing Implementation Details: By generating dynamic proxies for internal types, the actual implementation details of those types are hidden from external code and potential attackers. The dynamic proxies act as intermediaries, shielding the internal logic and structure of the types, making it harder for malicious actors to understand and manipulate your code.\nShield over Method Calls: When using dynamic proxies for internal types, decompilers face challenges in reconstructing the call flow for a method. Decompilers analyze compiled code to generate a high-level representation of the original source code. However, dynamic proxies introduce an additional layer of indirection, making it difficult for decompilers to accurately trace the sequence of method calls.\nEnhanced Obfuscation: The use of dynamic proxies for internal types adds an extra layer of obfuscation to your codebase. The proxies introduce complexity and indirection, making it more difficult for reverse engineers to understand the underlying structure and relationships of your code. This can deter reverse engineering attempts and protect your intellectual property."},{"page":47,"heading":"Internal Proxy Calls","anchor":"internal-proxy-calls","text":"By using Dynamic Proxy for internal calls, you create a barrier that hinders decompilers from accurately reconstructing the call flow within your code. This adds an additional layer of protection and makes it more challenging for attackers or reverse engineers to understand the underlying logic and behaviour of your application."},{"page":47,"heading":"External Proxy Calls","anchor":"external-proxy-calls","text":"External proxy calls in Babel Obfuscator provide an effective defense mechanism against decompilers that attempt to reconstruct local variable names based on their inferred types. Decompilers often rely on the available metadata, such as the variable types, to reconstruct the original names of variables.\nFor instance, in the reflected code below, the tool inferred the list1 and count variable names from the call to the instance constructor for List<string> type and the get_Count() method, respectively.\nvar list1 = new List<string>();\nint count = list1.Count;\nWhen external proxy calls are enabled, Babel Obfuscator replaces direct method calls to external code with calls to dynamically generated proxy classes. These proxy classes act as intermediaries, intercepting and redirecting the method calls. As a result, the original method calls, and their associated local variable names are hidden and obfuscated.\nAnd the above code with Dynamic Proxy enabled will become the following:\nvar local1 = new a();\nint local2 = local1.b();\nDecompilers that rely solely on metadata to reconstruct variable names will encounter difficulties when faced with external proxy calls. Since the original method calls are replaced with proxy calls, the inferred variable types alone will not provide any meaningful information about the original variable names. This effectively disrupts the decompiler's ability to reconstruct the original names based on type inference alone."},{"page":48,"heading":"","anchor":"","text":"Dynamic Proxy replaces direct call, callvirt and newobj instructions, covering static, instance, virtual and interface calls, property and event accessors, object construction, calls on generic types (for example List<int>.Add), and generic method calls — including LINQ operators such as Where, Select and OrderBy.\nTo keep the obfuscated program behaving exactly like the original, a few calls are deliberately not proxied and are left as direct calls:\nCaller-sensitive methods whose result depends on the calling method or assembly — Assembly.GetExecutingAssembly, Assembly.GetCallingAssembly and MethodBase.GetCurrentMethod. Routing these through a proxy would change the observed caller and return a wrong result.\nBy-reference (ref) returns, which a delegate cannot return.\nValue-type constructors and delegate constructors.\nGeneric methods on generic types, and generic calls whose type arguments are open, by-reference or pointer types.\nThese calls run unchanged; every other eligible call is proxied."},{"page":49,"heading":"","anchor":"","text":"Babel Obfuscator provides the flexibility to specify a list of filters to restrict the generation of dynamic proxies to specific methods. This feature gives you fine-grained control over the dynamic proxy generation, allowing you to selectively apply proxies to specific method calls based on their names or other patterns defined by the regular expressions. It provides flexibility in determining which parts of your code should have their call flow obscured and protected.\nThe primary benefit of Dynamic Proxy Filters is improved performance. By selectively applying proxies only to the necessary methods, you can significantly reduce the overhead associated with dynamic proxy generation. Unnecessary method calls are excluded from proxying, resulting in faster execution and improved overall performance of your obfuscated application.\nBy leveraging Dynamic Proxy Filters effectively, you can strike a balance between obfuscation and performance. By carefully choosing the methods that require proxying, you can achieve a high level of security while minimizing any potential performance impact.\nDynamic Proxy Filters provide a valuable optimization tool within Babel Obfuscator, enabling you to fine-tune the proxy generation process to achieve the desired level of obfuscation while maintaining optimal performance."},{"page":49,"heading":"","anchor":"","text":"Filters are regular expressions matched against the full name of the called method. You can set them on the command line by repeating the --proxy switch, through the DynamicProxyCallFilters MSBuild property, or with an XML rule — see Configuration.\nbabel myapp.exe --proxy ICollection.* --proxy IEnumerator.*"},{"page":50,"heading":"","anchor":"","text":"You can configure Dynamic Proxy from the command-line interface (CLI), the MSBuild Babel task, or Babel Desktop."},{"page":50,"heading":"Command Line","anchor":"command-line","text":"Babel Obfuscator provides the option to enable dynamic proxy protection through the use of the --proxy switch in the command-line interface. This switch allows you to configure Babel to generate proxies for external and internal method calls. You can also specify the list of dynamic proxy filters, depending on your specific requirements.\nThe following command line configures Babel Obfuscator to generate dynamic proxies only for external method calls.\nbabel myapp.exe --proxy external\nThe example below will make Babel Obfuscator generate dynamic proxies for external and internal method calls.\nbabel myapp.exe --proxy all\nThis command line sets some dynamic proxy filter expressions (see Filters).\nbabel myapp.exe --proxy ICollection.* --proxy IEnumerator.*"},{"page":50,"heading":"MSBuild Babel Task","anchor":"msbuild-babel-task","text":"<PropertyGroup>\n   <DynamicProxy>external=true;internal=true;true</DynamicProxy>\n   <DynamicProxyCallFilters>ICollection.*;IEnumerator.*</DynamicProxyCallFilters>\n</PropertyGroup>\n\n<Babel DynamicProxy=\"$(DynamicProxy)\" \n       DynamicProxyCallFilters=\"$(DynamicProxyCallFilters)\" />"},{"page":50,"heading":"Babel Desktop","anchor":"babel-desktop","text":"Select the assembly on the project canvas and, in the properties panel, set DynamicProxy in the Code encryption group to the type of dynamic proxy to generate. The DynamicProxyCallFilters option in the same group takes the list of call filters. See Obfuscation Projects for how to work with projects in Babel Desktop.\nYou can also define the call filters per rule: open the XML rules view for the assembly in Babel Desktop and create a new rule or modify an existing one to include the desired filters. Within the XML rule properties, specify the regular expressions that correspond to the method calls you want to proxy.\n<Rules>\n  <Rule name=\"rule1\" feature=\"dynamic proxy\" exclude=\"false\" applyToMembers=\"true\">\n    <Pattern>*</Pattern>\n    <Description>Set Dynamic Proxy Call Filters</Description>\n    <Properties>\n      <DynamicProxyCallFilters>IEnumerator.*</DynamicProxyCallFilters>\n    </Properties>\n  </Rule>\n</Rules>"},{"page":51,"heading":"","anchor":"","text":"Dynamic Proxy adds two kinds of cost, both small:\nA one-time cost per proxied call site. The first time a proxied member is invoked, the injected resolver resolves the target and wires up the delegate. This happens lazily (only for call sites actually reached) and once per call site. In applications that proxy a very large number of distinct calls this can add a small, measurable amount to startup or first-use time.\nA negligible steady-state cost. After the first call, invocations go through the cached delegate. The added per-call overhead is on the order of a few nanoseconds and is irrelevant for the vast majority of code.\nBecause the body of the called method itself is unchanged, methods that do real work are unaffected in practice. The overhead only becomes noticeable for extremely small methods invoked in very hot loops (millions of calls). For those cases — and to keep startup fast when only part of the code is sensitive — use Filters to proxy just the calls that need protection rather than the whole assembly.\nIt's important to note that while dynamic proxy protection provides an additional layer of obfuscation, it may have a slight impact on the startup time of your application due to the generation and initialization of the proxy classes. However, the trade-off between improved security and a small performance impact is generally considered worthwhile in most cases."},{"page":52,"heading":"","anchor":"","text":"Because the rewritten call sites no longer reference their targets directly and the encoding is varied from build to build, automated deobfuscation tools cannot recover the original call graph by static analysis. Babel's Dynamic Proxy is regularly verified against leading open-source .NET deobfuscation tools: their proxy-call resolvers recover none of the proxied calls, and the cleaned output does not reconstruct the original direct calls.\nCombining Dynamic Proxy with Symbols Renaming, Control Flow Obfuscation and Anti Tampering further increases the effort required to reverse engineer a protected assembly."},{"page":52,"heading":"Best Practices","anchor":"best-practices","text":"Protect what matters. Use Filters to target the sensitive call flow (licensing, security checks, proprietary algorithms) instead of proxying every call — this maximizes protection while minimizing size and startup impact.\nChoose the right mode. external is a lightweight option that mainly defeats variable-name and type-inference recovery in decompilers; all gives the strongest call-flow obfuscation for internal logic (see Internal and External Calls).\nCombine features. Dynamic Proxy is most effective alongside renaming, control flow obfuscation and anti-tampering.\nDisable on AOT targets. Set DynamicProxy=false for .NET MAUI and Blazor assemblies (see AOT and Platform Compatibility Limitations).\nVerify after building. Run your test suite against the obfuscated assembly, as you would for any protection setting.\nBy leveraging dynamic proxy protection in Babel Obfuscator, you can significantly enhance the security of your application by obscuring method calls and complicating the reverse engineering process."},{"page":53,"heading":"","anchor":"","text":"Babel Obfuscator offers the capability to compress and encrypt embedded resources, providing both resource protection and reducing the overall size of the assembly. When resources are encrypted, they remain securely stored within the assembly and are loaded dynamically at runtime when required.\nEncrypting embedded resources can safeguard sensitive information and valuable assets from unauthorized access. This is particularly useful when dealing with resources in WPF applications, as it prevents tools like .NET Reflector from inspecting and extracting these resources.\nDeploying on FIPS-enabled hosts? Encrypted resources are decrypted at runtime through the platform crypto provider, so a container running on a FIPS-enabled host without a certified OpenSSL FIPS provider can fail to load them. See FIPS Compliance for the cause and the fix.\nCommand Line\nEnabling resource compression can be achieved through the command line by using the following option:\nbabel MyApp.exe --resource compress=on --resource encrypt=on\nIt's important to note that while resource compression can help save disk space, it may result in a slight increase in the application's startup time due to the need for resource decompression.\nMSBuild Babel Task\n<PropertyGroup>\n   <ResourceEncryption>compress=true;encrypt=true;true</ResourceEncryption>\n</PropertyGroup>\n\n<Babel ResourceEncryption=\"$(ResourceEncryption)\" />\nBabel Desktop"},{"page":53,"heading":"","anchor":"","text":"Select the assembly on the project canvas and, in the properties panel, set ResourceEncryption in the Code encryption group. Turn on its compress and/or encrypt entries to choose whether managed resources are compressed, encrypted or both. See Obfuscation Projects for how to work with projects in Babel Desktop.\nIt is possible to disable resource encryption and compression for some managed resources using XML rules.\nThe following XML rule will disable resource encryption for a specific cursor resource that does not need to be protected.\n<Rules>\n  <Rule name=\"rule1\" feature=\"resource encryption\" exclude=\"true\">\n    <Target>Resources</Target>\n    <Pattern>Babel.HexEdit.Resources.Cursor.RightArrow.cur</Pattern>\n    <Description>Disable Resource Encryption</Description>\n  </Rule>\n</Rules>\nBy utilizing resource compression and encryption, you can protect your valuable resources, maintain the integrity of your application, and deter reverse-engineering attempts."},{"page":54,"heading":"","anchor":"","text":"Constant values and arrays declared inline in your code can often contain sensitive information, such as data encryption keys or other critical data that you want to keep hidden from disassemblers or reverse engineering attempts. Babel Obfuscator provides a feature to encrypt these constant values and arrays, adding an extra layer of protection to your sensitive information.\nBabel Obfuscator provides configuration options that allow you to encrypt inline values of various data types, including int32, int64, single, double, and arrays. By leveraging these options, you can enhance the security of your code by encrypting these specific types of values.\nThe encryption of int32 and int64 values ensures that numeric data of these types, such as integers or long integers, are protected from unauthorized access. Similarly, the encryption of single and double values offers protection for floating-point numbers, such as decimals or real numbers. By encrypting these inline values, you can safeguard sensitive numeric data within your code from being easily deciphered or modified.\nFurthermore, Babel Obfuscator allows you to encrypt arrays declared inline in your code. Arrays are collections of elements, and encrypting them helps ensure the confidentiality and integrity of the data they contain. This added layer of encryption prevents attackers from gaining insights into the contents of your arrays, even if they manage to analyze or decompile your code.\nThis section covers:"},{"page":54,"heading":"","anchor":"","text":"How It Works\nSupported Values — which constants and arrays are encrypted, and which are left as-is\nConfiguration — CLI, MSBuild and Babel Desktop\nPerformance and Deobfuscation Resistance"},{"page":54,"heading":"How It Works","anchor":"how-it-works","text":"At build time Babel removes the constant from the method body and replaces it with a lookup: the literal ldc instruction is rewritten so that the value is fetched from an encrypted table embedded in the assembly and decrypted on demand at runtime. Numeric constants (int32, int64, single, double) are collected per type, encrypted into that table, and each original load becomes a small call that returns the decrypted value. Inline arrays are handled similarly: the array's initialization data — normally stored as a plaintext blob in the assembly — is encrypted and rebuilt at runtime.\nThe result is that a decompiler no longer sees the real numbers or array contents in the IL; it only sees indexes into an opaque, encrypted table. Values are decrypted lazily as your code runs, so behavior is unchanged.\nWarning: Deploying on FIPS-enabled hosts? Encrypted values and arrays are\ndecrypted at runtime through the platform crypto provider, so a container\nrunning on a FIPS-enabled host without a certified OpenSSL FIPS provider\ncan fail to start. See FIPS Compliance for\nthe cause and the fix.\nInfo: Please note that enabling value and array encryption may introduce a slight performance overhead due to the encryption and decryption operations during runtime. Therefore, it's important to carefully evaluate the trade-off between security and performance based on your application's specific needs — see Performance."},{"page":55,"heading":"","anchor":"","text":"Value and Array Encryption can be enabled independently for each data type, so you can protect only what matters and keep the rest untouched. See Configuration for how to select them."},{"page":55,"heading":"Encrypted","anchor":"encrypted","text":"Type | What is protected\nint32 | 32-bit integer constants — every ldc.i4 form, including small values, -1, and int.MinValue/int.MaxValue. Because C# byte, sbyte, short, ushort, char, bool and enum constants compile to int32 loads, they are protected under this option as well.\nint64 | 64-bit integer (long/ulong) constants.\nsingle | 32-bit floating-point (float) constants.\ndouble | 64-bit floating-point (double) constants, and decimal literals (whose components are stored as integer constants).\narray | Inline arrays of primitive elements initialized from a data blob — int, byte, sbyte, short, long, double, float, char, bool and enum arrays such as int[] a = { 1, 2, 3 };."},{"page":55,"heading":"Left unchanged","anchor":"left-unchanged","text":"To keep the obfuscated program behaving exactly like the original, some inline data is deliberately not transformed and is emitted as-is:\nArrays that are not initialized from a single primitive data blob — multi-dimensional arrays (int[,]), jagged arrays (int[][]), and arrays of structs or other reference types. These are built element by element by the compiler rather than from an encryptable blob, so their individual elements are still subject to numeric value encryption where applicable.\nString constants — these are covered by the dedicated String Encryption feature, not by value encryption.\nEnabling every type gives the broadest protection; use a subset when you only need to hide specific kinds of data or want to minimize the runtime overhead described in Performance."},{"page":56,"heading":"","anchor":"","text":"There are multiple ways to configure Values and Array Encryption in Babel Obfuscator. You can choose one of the following three methods based on your preference and project setup. See Supported Values for the meaning of each data type."},{"page":56,"heading":"Command Line","anchor":"command-line","text":"Babel Obfuscator offers a command-line interface (CLI) that allows you to specify the desired encryption settings. Using the CLI, you can provide command-line arguments or options to enable encryption for values and arrays.\nbabel myapp.exe --values int32=on --values double=on\nEnable every data type — integers, floating-point values and arrays — like this:\nbabel myapp.exe --values int32=on --values int64=on --values single=on --values double=on --values array=on"},{"page":56,"heading":"MSBuild Babel Task","anchor":"msbuild-babel-task","text":"If you're using Microsoft Build (MSBuild) as your build system, Babel Obfuscator provides an MSBuild task that can be integrated into your project file. With this approach, you can configure the encryption settings within your project file using specific XML elements and attributes. This method simplifies the configuration process, especially for projects already utilizing MSBuild.\n<PropertyGroup>\n  <ValueEncryption>\n    int32=true;int64=true;single=true;double=true;array=true;true\n  </ValueEncryption>\n</PropertyGroup>\n\n<Babel ValueEncryption=\"$(ValueEncryption)\" />\nThe <ValueEncryption> property is defined within the <PropertyGroup> element, allowing you to configure the encryption settings for values and arrays. The last occurrence of true within the <ValueEncryption> property acts as a global switch for the Values and Array Encryption feature. By setting it to true, you are indicating that the encryption should be enabled for all the specified data types. If you were to set it to false, it would disable encryption for all the specified data types."},{"page":56,"heading":"Babel Desktop","anchor":"babel-desktop","text":"Select the assembly on the project canvas and, in the properties panel, set ValueEncryption in the Code encryption group. Turn on the int32, int64, single, double and array entries for the value and array types you want to encrypt. See Obfuscation Projects for how to work with projects in Babel Desktop.\nBy encrypting the constant values and arrays, Babel Obfuscator ensures that even if the code is decompiled, the sensitive data remains encrypted and unreadable, making it significantly harder for attackers to extract the original values."},{"page":57,"heading":"","anchor":"","text":"Value and Array Encryption trades a small amount of runtime cost for keeping your constants and array data out of the decompiled code.\nPer-access decryption. Each encrypted constant is fetched through a decryption call instead of being loaded directly, so a value read costs more than a plain ldc. For the overwhelming majority of code this is imperceptible, but it can add up when a hot loop repeatedly reads encrypted constants millions of times.\nArray rebuild on first use. An encrypted inline array is reconstructed from its decrypted data the first time it is initialized.\nBecause the cost is proportional to how often encrypted values are read, apply encryption where it protects something worth protecting rather than to every literal in the assembly. If a specific tight loop shows measurable overhead, consider hoisting the constant into a variable outside the loop, or enabling encryption only for the data types that actually carry sensitive data (see Configuration).\nAs with any protection setting, run your test suite and, if relevant, your performance benchmarks against the obfuscated assembly to confirm the trade-off is acceptable for your application."},{"page":58,"heading":"","anchor":"","text":"Once a constant is encrypted, the real value is no longer present in the method body: the IL only carries an index into an encrypted table that is decrypted at runtime. A decompiler therefore shows opaque indexes instead of the original numbers or array contents.\nBabel's Value and Array Encryption is verified against leading open-source .NET deobfuscation tools. Running them against a protected assembly does not recover the encrypted values: the original constants do not appear as literals in the cleaned output, the decryption indirection is left in place, and the encrypted data table remains required. The protection holds.\nFor the strongest result, combine Value and Array Encryption with the other protection layers — Symbols Renaming, String Encryption, Control Flow Obfuscation and Code Encryption — so that no single layer, if analyzed, exposes the whole picture."},{"page":59,"heading":"","anchor":"","text":"Tampering detection is a critical aspect of ensuring the integrity and security of software applications. In the context of the .NET, Babel Obfuscator is one powerful tool for detecting tampering. By leveraging Babel's tampering detection feature, developers can add an extra layer of protection to their applications and execute custom logic in response to tampering attempts.\nWhen an assembly is signed, the .NET Framework can already detect if an application has been tampered with. However, Babel Obfuscator takes this a step further by providing an additional safeguard. By activating the tampering detection feature in Babel, the obfuscated assembly becomes capable of verifying whether it has been tampered with or not. In the event of tampering, the application can be terminated, or custom methods within the assembly can be invoked to handle the tampering in a more controlled manner.\nInfo: On mobile .NET MAUI targets, tampering detection is provided starting with version 12 by a package‑integrity check instead of the desktop image hash: an APK‑signature check on Android (see Android (MAUI) Package Integrity) and a bundle‑identifier / provisioning‑profile check on iOS (see iOS (MAUI) Package Integrity). On desktop targets the check hashes the loaded image in memory, so it is inert for single‑file, trimmed, or AOT‑published apps; Babel emits a warning when tampering detection is requested for such a publish."},{"page":59,"heading":"Configuring Tampering Detection","anchor":"configuring-tampering-detection","text":"Enabling tampering detection in Babel is straightforward. It can be achieved either through the command line by adding the appropriate switch or through the Babel task by including the TamperingDetection attribute in the project file.\nCommand Line\nbabel myapp.exe --tamperingdetection\nMSBuild Babel Task\n<PropertyGroup>\n  <TamperingDetection>true</TamperingDetection>\n</PropertyGroup>\n\n<Babel TamperingDetection=\"$(TamperingDetection)\" />\nOnce tampering detection is activated, the obfuscated assembly will automatically check for tampering during runtime. If the assembly has been tampered with, the application will be terminated.\nOn desktop targets (.NET Framework and .NET running on the CoreCLR) the check works by computing a hash of the loaded image in memory and comparing it with a hash stamped into the assembly at obfuscation time. This technique requires the assembly to be present as a memory‑mapped image, so it does not apply to single‑file, trimmed, or AOT‑published applications; when you request tampering detection for such a publish, Babel warns that the check would be inert."},{"page":59,"heading":"Android (MAUI) Package Integrity (Ultimate)","anchor":"android-maui-package-integrity","text":"The in‑memory image hash described above cannot be used on Android: the application runs on MonoVM and the managed assemblies are packaged inside the APK rather than loaded as a Windows PE image. Starting with version 12, Babel provides an equivalent protection for .NET for Android (MAUI) targets, based on the integrity of the APK signature.\nWhen you enable tampering detection for a net*-android assembly, Babel injects a runtime check that reads the certificate the running APK was signed with and compares it against one or more trusted signer fingerprints that you pin at obfuscation time. If the application is re‑signed or repackaged with a different key — the classic way to redistribute a modified app — the fingerprints no longer match and the tampering reaction is triggered: the application is terminated, or your custom handler is invoked (see Custom Action on Tampering Detection). Because the check inspects the operating‑system package signature rather than the managed image, it keeps working with trimming and ahead‑of‑time (AOT) compilation.\nPinning the signing certificate\nThe signing certificate is not known to Babel from the assembly alone — it is applied later, when the APK is signed. You therefore pin the expected certificate's SHA‑256 fingerprint with the --trustedsigner option. The option is repeatable, so you can pin more than one certificate (for example an upload key and a Google Play app‑signing key):"},{"page":59,"heading":"Android (MAUI) Package Integrity (Ultimate)","anchor":"android-maui-package-integrity","text":"babel MyApp.dll --tamperingdetection --trustedsigner 2924C53EE9C511E9F26E0720FD8151064F7621681667D7AB1899E551CDB25104\nThrough the MSBuild task:\n<PropertyGroup>\n  <TamperingDetection>true</TamperingDetection>\n  <TrustedSigner>2924C53EE9C511E9F26E0720FD8151064F7621681667D7AB1899E551CDB25104</TrustedSigner>\n</PropertyGroup>\n\n<Babel TamperingDetection=\"$(TamperingDetection)\" TrustedSigner=\"$(TrustedSigner)\" />\nYou can obtain the SHA‑256 fingerprint of your signing certificate with keytool (from the keystore) or apksigner (from a built, signed APK):\nkeytool -list -v -keystore my-release.keystore -alias my-alias | grep -i SHA256\n# or, from a signed APK:\napksigner verify --print-certs MyApp.apk | grep -i 'SHA-256'\nStrip the colon separators; the value passed to --trustedsigner is a 64‑character hexadecimal string.\nWarning: If you enable tampering detection on an Android target without pinning a trusted signer, Babel emits a warning and falls back to a weaker check that only verifies that the package is signed. Always pass --trustedsigner (TrustedSigner) with your release certificate fingerprint for real protection."},{"page":59,"heading":"iOS (MAUI) Package Integrity (Ultimate)","anchor":"ios-maui-package-integrity","text":"On .NET for iOS (MAUI) the managed code is fully ahead‑of‑time compiled and there is no memory‑mapped PE image to hash, so the desktop technique cannot be used. Starting with version 12, Babel provides a package‑identity check for net*-ios targets: at runtime the obfuscated app verifies its own bundle identifier and, when running from a provisioned build, the Apple Team identifier, against values you pin at obfuscation time. If either no longer matches — for example after the app has been repackaged or re‑signed with a different developer identity — the tampering reaction is triggered (the application is terminated, or your custom handler is invoked). The check runs from a module initializer at process start and works under full AOT.\nPinning the bundle and team identifiers\nPin the expected values with the --trustedbundle and --trustedteam options:\nbabel MyApp.dll --tamperingdetection --trustedbundle com.mycompany.myapp --trustedteam ABCDE12345\nThrough the MSBuild task:\n<PropertyGroup>\n  <TamperingDetection>true</TamperingDetection>\n  <TrustedBundle>com.mycompany.myapp</TrustedBundle>\n  <TrustedTeam>ABCDE12345</TrustedTeam>\n</PropertyGroup>\n\n<Babel TamperingDetection=\"$(TamperingDetection)\"\n       TrustedBundle=\"$(TrustedBundle)\"\n       TrustedTeam=\"$(TrustedTeam)\" />"},{"page":59,"heading":"iOS (MAUI) Package Integrity (Ultimate)","anchor":"ios-maui-package-integrity","text":"--trustedbundle is your app's CFBundleIdentifier (from Info.plist).\n--trustedteam is your 10‑character Apple Team ID (visible in the Apple Developer portal under Membership, and in the identity name of your signing certificate, e.g. Apple Development: You (ABCDE12345)).\nEach pin is optional and checked independently: pin the bundle id, the team id, or both.\nWarning: The team‑identifier check reads the app's embedded provisioning profile (embedded.mobileprovision), which is present in development, ad‑hoc and enterprise builds. It is not available in the iOS Simulator (where the check is skipped) and is stripped from App Store builds (which Apple re‑signs), so for App Store distribution rely on the bundle‑identifier pin. If you enable tampering detection on an iOS target without pinning either value, Babel emits a warning and performs no integrity check."},{"page":59,"heading":"Custom Action on Tampering Detection","anchor":"custom-action-on-tampering-detection","text":"To customize the response to tampering attempts, developers can define a specific method within their assembly. By applying the \"on tampering detected method\" feature using the [Obfuscation] attribute, a custom method can be designated to handle the tampering event. This allows developers to implement their own logic and take appropriate actions when tampering is detected. For example, they can set a hidden flag, generate incorrect results, or trigger specific countermeasures to mitigate the impact of the tampering. The same handler is used for the desktop image check and for the Android and iOS package‑integrity checks, so a single method covers every target.\nclass CustomTampering\n{\n    public static bool HasBeenTampered { get; internal set; }\n    \n    [Obfuscation(Feature = \"on tampering detected method\")]\n    static void OnTamperingDetected()\n    {\n        HasBeenTampered = true;\n    }\n}\nThe code provides a basic implementation for handling tampering detection.\nIf HasBeenTampered is set to true, it implies that tampering has been detected. The suggested usage is to perform certain actions or execute specific code when tampering is detected:\nif (CustomTampering.HasBeenTampered)\n{\n    // Tampering detected: Implement appropriate security measures or handle the \n    // situation accordingly.\n    // Examples include logging the incident, notifying system administrators, \n    // disabling critical functionality or terminating the application.\n}"},{"page":59,"heading":"Custom Action on Tampering Detection","anchor":"custom-action-on-tampering-detection","text":"In summary, by leveraging the tampering detection feature of Babel Obfuscator, developers can significantly enhance the security of their .NET applications. With the ability to detect and respond to tampering attempts, developers can safeguard their software from unauthorized modifications, maintain data integrity, and protect sensitive information."},{"page":60,"heading":"","anchor":"","text":"By injecting anti-debugging code into your assembly, Babel Obfuscator can take proactive measures when a debugger is attached, such as terminating the application or executing custom logic. This capability serves as a crucial defense against reverse engineering and unauthorized access to your code, safeguarding the integrity and confidentiality of your software."},{"page":60,"heading":"Configuring Anti Debugging","anchor":"configuring-anti-debugging","text":"To enable anti-debugging protection and configure a custom action when a debugger is detected using Babel Obfuscator, follow these steps.\nCommand Line\nAdd the --antidebugging switch to the Babel command line when obfuscating your assembly. For example:\nbabel myapp.exe --antidebugging\nMSBuild Babel Task\nIf you are using the Babel task, add the DebuggingProtection=\"true\" attribute to your configuration. For example:\n<Babel InputFile=\"$(AppName).exe\" DebuggingProtection=\"true\" ... />"},{"page":60,"heading":"Custom Action on Debugger Detected","anchor":"custom-action-on-debugger-detected","text":"To customize the response when a debugger is detected inside your assembly, add the following method to an existing class to define the custom action that will be executed when a debugger is detected:\n[Obfuscation(Feature = \"on debugger detected method\")]\nstatic void OnDebuggerDetected()\n{\n    // Custom logic to be executed when a debugger is detected\n    // This code must be thread-safe as it can be called by different running threads\n}\nWhen the application is executed, and a debugger is detected, the OnDebuggerDetected() method will be called. You can place your desired custom logic within this method. It is important to ensure that the code inside OnDebuggerDetected() is thread-safe since it can be called multiple times and by different threads when a debugger is detected.\nHere's an example of how the code might look in a C# application:\nusing System;\nusing System.Reflection;\n\npublic class Program\n{\n    [Obfuscation(Feature = \"on debugger detected method\")]\n    static void OnDebuggerDetected()\n    {\n        // Custom action to be executed when a debugger is detected\n        Console.WriteLine(\"Debugger detected! Terminating application...\");\n        Environment.Exit(0);\n    }\n\n    static void Main()\n    {\n        // Your application's main logic\n        // ...\n    }\n}"},{"page":60,"heading":"Custom Action on Debugger Detected","anchor":"custom-action-on-debugger-detected","text":"In the above example, when a debugger is detected, the application will terminate with an exit code of 0, displaying the message \"Debugger detected! Terminating application...\" to the console. You can replace this custom action with any behaviour you desire, such as logging, displaying an error message, or taking other defensive measures."},{"page":61,"heading":"","anchor":"","text":"Best practices for enhanced code security.\nBabel Obfuscator is a powerful tool that offers robust protection for your code. While delving into all the intricacies of obfuscation may be time-consuming, we have compiled a set of tips that will help you achieve optimal obfuscation results with minimal effort. By following these recommendations, you can significantly enhance the security of your code without getting lost in the details.\nStrong protection comes from defense in depth: no single transformation is meant to stop an attacker on its own. Renaming hides intent, encryption hides data, control flow and dynamic proxies hide logic, and runtime checks deter tampering and debugging. Combine several layers so that defeating one still leaves the others in place. The tips below are grouped by what each layer protects."},{"page":61,"heading":"Rename and Restructure Your Symbols","anchor":"rename-and-restructure-your-symbols","text":"Consider Internalizing Types in C# or Marking Them as Friend In VB\nDeclaring types as internal or Friend (in VB terminology) ensures they are not visible to external assemblies and can be safely renamed during obfuscation. This step effectively shields your code from prying eyes.\nInfo: Babel Obfuscator allows the renaming of public types or symbols externally visible to the assembly by using XML Rules. However, this must be carefully reviewed because if the symbol is consumed by external assemblies, this will break the application. Therefore, while internalizing or marking types as Friend is a straightforward way to enhance security, forcing renaming of public symbols requires thorough consideration and testing.\nStrengthen Renaming\nBeyond the default symbol renaming, a few options make the renamed metadata considerably harder to read:\nOverloaded renaming reuses a single obfuscated name for many unrelated members, so the metadata no longer maps one-to-one to your members.\nFlatten namespaces collapses your namespace hierarchy, erasing the structural hints a decompiler relies on.\nVirtual member renaming renames virtual and interface members consistently across the type hierarchy.\nBabel CLI\nbabel.exe myapp.dll --overloaded --flatns --virtualmembers\nMerge Dependencies Whenever Possible"},{"page":61,"heading":"Rename and Restructure Your Symbols","anchor":"rename-and-restructure-your-symbols","text":"Babel Obfuscator allows you to merge referenced assemblies into the target assembly. By internalizing all merged types, you increase the number of renamed symbols, making it harder for potential attackers to decipher your code."},{"page":61,"heading":"Hide Constant Data","anchor":"hide-constant-data","text":"Utilize Hash Algorithm for String Encryption\nEmploying the hash string encryption algorithm provides strong protection while reducing the size of the obfuscated assembly on the disk. You can enable this feature using the following command:\nBabel CLI\nbabel.exe myapp.exe --stringencryption hash\nMSBuild Babel Task\n<PropertyGroup>\n  <StringEncryption>hash</StringEncryption>\n</PropertyGroup>\nEncrypt Inline Values and Arrays\nNumeric constants and inline arrays frequently carry sensitive data — thresholds, keys, magic numbers, lookup tables. Value and Array Encryption removes those literals from the IL and decrypts them at runtime, so a decompiler no longer sees the real numbers or array contents.\nBabel CLI\nbabel.exe myapp.exe --values int32=on --values int64=on --values single=on --values double=on --values array=on\nEncrypt Managed Resources\nResource Encryption hides embedded resources within your assembly while compressing them, providing an additional layer of protection. Carefully consider the performance impact before enabling this feature."},{"page":61,"heading":"Obscure Program Logic","anchor":"obscure-program-logic","text":"Enable Control Flow Obfuscation\nControl Flow Obfuscation adds complexity to if statements, inserts irrelevant branches and introduces multiple switch instructions without altering the method's behaviour. Enabling specific control flow algorithms like goto, if, switch, case, and call ensures the best code scramble. The following recommended settings will help you achieve effective control flow obfuscation:\nBabel CLI\nbabel.exe myapp.exe --controlflow goto=on --controlflow if=on --controlflow switch=on --controlflow case=on --controlflow call=on\nMSBuild Babel Task\n<PropertyGroup>\n  <ControlFlowObfuscation>goto=true;if=true;switch=true;case=true;call=true;true</ControlFlowObfuscation>\n  <ControlFlowIterations>3</ControlFlowIterations>\n</PropertyGroup>\nBy enabling the above control flow obfuscation settings, you ensure a robust and effective obfuscation of your code. The different algorithms (goto, if, switch, case, and call) contribute to making the control flow more convoluted and challenging to analyze, enhancing the security of your application.\nUse Dynamic Proxy Generation for External Method Calls\nDynamic Proxies effectively hide calls to external and internal methods. Enabling dynamic proxy generation for external calls is often sufficient to achieve a high level of obfuscation.\nbabel.exe myapp.exe --proxy external\nEncrypt Code"},{"page":61,"heading":"Obscure Program Logic","anchor":"obscure-program-logic","text":"Code Encryption provides robust protection for methods that handle sensitive data, such as license key verification. However, be mindful of performance implications, as code encryption can have an impact on application speed — apply it selectively to the methods that need it.\nWith the integration of Babel Licensing Service, you have the flexibility to utilize Activation or Floating Licenses to enable feature-based licensing. This means that you can securely deliver encryption keys through the licensing service, unlocking specific features of your application for authorized users.\nBy leveraging Babel Licensing Service in combination with Code Encryption, you ensure that only licensed users have access to the encrypted code segments. The encryption key is securely delivered through the licensing service, preventing unauthorized usage and ensuring the integrity of your application's features."},{"page":61,"heading":"Detect and Deter Runtime Attacks","anchor":"detect-and-deter-runtime-attacks","text":"Enable Anti Tampering Protection\nAnti Tampering Protection detects any unauthorized modification to your assembly. Choose appropriate actions, such as stopping execution or reporting an error to the user, to deter attackers. Opting for silent actions makes it more challenging to bypass the anti-tampering mechanism.\nbabel.exe myapp.exe --tamperingdetection\nEnable Anti Debugging Protection\nAnti-Debugging detects when your application is run under a debugger or profiler — the tools an attacker uses to observe secrets as they are decrypted at runtime. Combined with the encryption layers above, it closes the gap left by static analysis.\nbabel.exe myapp.exe --antidebugging\nBlock Disassembly and Reflection Tools\nTwo lightweight switches make casual inspection harder: --ildasm marks the assembly so the MSIL Disassembler (ildasm.exe) refuses to open it, and --reflection stops reflection-based tools from listing the assembly's metadata.\nbabel.exe myapp.exe --ildasm --reflection"},{"page":61,"heading":"Strip What You Don't Need to Ship","anchor":"strip-what-you-dont-need-to-ship","text":"Every piece of metadata you leave behind is a hint. Remove what the running application does not need:\nClean attributes — --cleanattrs removes custom attributes that only served the compiler or your tooling.\nRemove dead code — --deadcode drops unreachable methods and members.\nRemove enums — --enumremoval replaces enum types with their underlying constants.\nSeal internal classes — --seal seals internal types that are never inherited.\nDo not ship debug symbols — deploy without the .pdb file (avoid --debug) so line numbers and local names are not available to an attacker."},{"page":61,"heading":"A Recommended Baseline","anchor":"a-recommended-baseline","text":"The following command combines the layers above into a strong, general-purpose configuration. Add --msilencryption for the specific sensitive methods that warrant it.\nbabel.exe myapp.dll `\n  --overloaded --flatns --virtualmembers `\n  --stringencryption hash `\n  --values int32=on --values int64=on --values single=on --values double=on --values array=on `\n  --controlflow if=on --controlflow switch=on --controlflow case=on --controlflow chain=on `\n  --proxy external `\n  --resourceencryption `\n  --tamperingdetection --antidebugging --ildasm `\n  --cleanattrs --seal\nThe equivalent MSBuild task properties:\n<PropertyGroup>\n  <OverloadedRenaming>true</OverloadedRenaming>\n  <FlattenNamespaces>true</FlattenNamespaces>\n  <VirtualFunctions>true</VirtualFunctions>\n  <StringEncryption>hash</StringEncryption>\n  <ValueEncryption>int32=true;int64=true;single=true;double=true;array=true;true</ValueEncryption>\n  <ControlFlowObfuscation>if=true;switch=true;case=true;chain=true;true</ControlFlowObfuscation>\n  <DynamicProxy>external=true;true</DynamicProxy>\n  <ResourceEncryption>true</ResourceEncryption>\n  <TamperingDetection>true</TamperingDetection>\n  <DebuggingProtection>true</DebuggingProtection>\n  <SuppressIldasm>true</SuppressIldasm>\n  <CleanAttributes>true</CleanAttributes>\n  <SealClasses>true</SealClasses>\n</PropertyGroup>"},{"page":61,"heading":"Keep a Map File for Support","anchor":"keep-a-map-file-for-support","text":"Aggressive obfuscation makes production stack traces unreadable. Keep the obfuscation map file produced for each build so you can decode stack traces back to the original names when diagnosing customer issues — without weakening the shipped assembly.\nWarning: Test the Obfuscated Application: It is crucial to thoroughly test your obfuscated application to identify and address any potential issues introduced by the obfuscation process. Testing ensures the stability and proper functioning of your code. When deploying on FIPS-enabled hosts, also review FIPS Compliance, since several encryption layers decrypt through the platform crypto provider at runtime.\nBy following these obfuscation tips, you can leverage Babel Obfuscator effectively and bolster the security of your code. For more detailed information and comprehensive guidance, we recommend consulting the Babel Obfuscator user's guide."},{"page":62,"heading":"","anchor":"","text":"Assemblies protected with Babel Obfuscator run on FIPS-enabled hosts.\nThis page explains how the protection features that rely on runtime\ndecryption — Code Encryption (MSIL), String Encryption,\nResource Encryption and Value and Array Encryption —\nbehave on such hosts, a startup issue you may encounter in containers,\nand how to resolve it — either at obfuscation time, by\nprotecting with Babel's self-contained managed AES, or at the\nenvironment level."},{"page":62,"heading":"Background","anchor":"background","text":"Many customers deploy on hosts where the operating system runs in FIPS\nmode — on Linux this is exposed as\n/proc/sys/crypto/fips_enabled = 1. In this mode the platform crypto\nprovider (OpenSSL on Linux) is expected to service every cryptographic\noperation through a certified FIPS module.\nA common problem arises when a container inherits the host's FIPS\nflag but its base image does not ship a certified OpenSSL FIPS\nprovider. OpenSSL 3 then tries to enter FIPS mode, fails to load the FIPS\nprovider module, and ends up in a broken state where every digest\nand cipher operation fails — not only the ones FIPS would normally\ndisallow.\nInfo: This is an environment condition, not a defect in the obfuscated\nassembly or in Babel Obfuscator. It is documented independently of Babel\n— see\ndotnet/dotnet-docker#5849\nand dotnet/runtime#87884.\nIt affects any OpenSSL-backed .NET cryptography in the process,\nincluding TLS (HttpClient, gRPC), not just obfuscated code."},{"page":62,"heading":"How it can surface in obfuscated assemblies","anchor":"how-it-can-surface-in-obfuscated-assemblies","text":"When an assembly is protected with a feature that decrypts content at\nruntime — most notably Code Encryption and String\nEncryption — Babel injects a small runtime that uses the\nplatform's cryptographic provider to decrypt method bodies and strings.\nOn a broken-FIPS host that provider is unusable, so the decryption runs\ninside a type initializer and the assembly fails to start before any\nof your code runs:\nSystem.TypeInitializationException: The type initializer for '...' threw an exception.\n ---> Interop+Crypto+OpenSslCryptographicException:\n        error:0308010C:digital envelope routines::unsupported\n   at System.Security.Cryptography.AesImplementation.CreateTransform(...)\nInfo: You can prevent this startup failure at obfuscation time by\nprotecting the assembly with Babel's managed AES algorithm: the\ninjected runtime then decrypts without the platform cryptographic\nprovider — see Starting on a broken-FIPS host with managed\nAES below. Fixing the\nOpenSSL environment (also described below) is still recommended when you\ncontrol the container, because it additionally resolves other\nOpenSSL-backed operations in the process, such as TLS."},{"page":62,"heading":"Starting on a broken-FIPS host with managed AES","anchor":"starting-on-a-broken-fips-host-with-managed-aes","text":"Babel Obfuscator can carry a self-contained managed AES decryptor\ninside the protected assembly, so the injected runtime no longer depends\non the platform cryptographic provider. Protect the assembly with the\nencryption=aesmanaged value of the\n--use\nswitch:\nbabel MyApp.dll --msilencryption --use encryption=aesmanaged\nor, in an MSBuild / .babel project:\n<Use>encryption=aesmanaged</Use>\nThe obfuscator still encrypts with the platform provider on the build\nhost (which is healthy) and produces the same ciphertext; only the\ndecryptor carried inside the protected assembly changes. This lets the\nassembly start on a broken-FIPS host without any environment change.\nAssemblies protected with an earlier Babel release must be re-obfuscated\nto pick up the managed decryptor.\nInfo: Performance. The managed decryptor runs at roughly 40 MB/s, versus\nseveral GB/s for the hardware-accelerated platform AES. For string,\nresource and the common (cached) code encryption this is a one-time cost\nat startup and is not noticeable. The exception is Code Encryption on\na method marked cache=false, whose body is decrypted on every call:\navoid combining cache=false with encryption=aesmanaged on hot-path\nmethods, and keep the method cache enabled (the default) so decryption\nhappens once."},{"page":62,"heading":"Resolving it in containers","anchor":"resolving-it-in-containers","text":"Make OpenSSL usable inside the container. Either option resolves the\nobfuscation-runtime symptom and every other OpenSSL-backed operation\nin your process (for example, if the same assembly also uses Babel\nLicensing or TLS).\nOption 1 — Do not auto-enter FIPS in the container\nOn Ubuntu-based .NET images, OpenSSL honors the\nOPENSSL_FORCE_FIPS_MODE environment variable. Set it to 0 so OpenSSL\ndoes not try to enter FIPS mode with a provider the image does not ship.\nIn a Dockerfile:\nENV OPENSSL_FORCE_FIPS_MODE=0\nor in docker-compose.yml:\nenvironment:\n      OPENSSL_FORCE_FIPS_MODE: 0\nUse this when the container itself does not need to be FIPS-validated:\nthe host stays FIPS-enabled and only this container's OpenSSL opts out of\nthe broken auto-FIPS path.\nOption 2 — Use a base image with a certified FIPS provider\nIf FIPS compliance is required inside the container, run on a base\nimage that ships a validated FIPS provider so the crypto layer\ninitializes correctly instead of failing:\nAzure Linux 3.0 .NET images\n(mcr.microsoft.com/dotnet/aspnet:8.0-azurelinux3.0 and similar),\nwhich ship Microsoft's FIPS-certified SymCrypt provider,\nRed Hat UBI 9 based .NET images\n(registry.access.redhat.com/ubi9/dotnet-90 and similar), or\nUbuntu Pro with the FIPS-certified OpenSSL packages."},{"page":62,"heading":"Verifying the environment","anchor":"verifying-the-environment","text":"A quick check from inside the container tells you whether OpenSSL is\nhealthy:\n# Fails on a broken-FIPS host, succeeds once fixed\necho test | openssl dgst -sha1\nFailure with error:03000086 (or a message about fips.so not being\nloadable) — OpenSSL is in the broken state; apply Option 1 or 2.\nA normal SHA1(stdin)= ... line — OpenSSL is healthy and\nobfuscated assemblies start normally."},{"page":62,"heading":"If you cannot change the environment","anchor":"if-you-cannot-change-the-environment","text":"If you have no control over the base image or environment variables and\nthe target must remain strictly FIPS constrained, protect the assembly\nwith the managed AES algorithm described above\n(--use encryption=aesmanaged) so the injected decryptor does not need\nthe platform provider. This lets a protected assembly start even on a\nbroken-OpenSSL host without touching the environment, and keeps all the\nruntime-decryption features — Code Encryption, String\nEncryption, Resource Encryption and Value and Array Encryption\n— available. Note that other OpenSSL-backed operations in the same\nprocess (such as TLS) will still fail until the environment is fixed.\nContact support if you need guidance for a\nspecific deployment."},{"page":63,"heading":"","anchor":"","text":"Babel Obfuscator can perform a series of optimizations related to both code and metadata. These optimizations encompass various techniques to improve the efficiency, size, and security of the obfuscated code. By optimizing the code, Babel aims to enhance its performance and reduce its footprint, making it faster and more compact. Simultaneously, metadata optimizations are applied to make the code harder to understand, reducing the likelihood of successful reverse engineering. Through a combination of code and metadata optimizations, Babel Obfuscator provides a comprehensive approach to enhancing the obfuscated code's quality and protection.\nBabel Obfuscator offers a wide range of optimizations to enhance the obfuscated code. These optimizations include:"},{"page":63,"heading":"","anchor":"","text":"Dead Code Removal\nBabel identifies and removes code that will never be executed at runtime, including unused methods, properties, fields, and types.\nMetadata Optimizations\na) Automatic Class Sealing: Babel automatically seals classes to improve performance due to the optimizations made by the CLR when calling not virtual members. Moreover, class sealing prevents inheritance and modifications, adding an extra layer of protection.\nb) Custom Attributes Removal: Babel eliminates unnecessary custom attributes, reducing metadata size. \nc) System.EnumTypes Removal: Babel removes System.Enum types that could potentially reveal information.\nd) Disgregate Removal: Babel removes properties and events constructs streamlining the code and reducing its complexity.\nCode Optimizations\na) Inline Expansion: Babel inlines small methods or properties into the calling code, reducing function call overhead and improving performance. \nb) Const Fields Removal: Babel removes const fields from the code, reducing its size and improving security.\nThese optimizations collectively aim to enhance the performance, size, and security of the obfuscated code. By removing dead code, optimizing metadata, and improving the code itself, Babel Obfuscator creates a more streamlined, efficient, and harder-to-understand version of the codebase."},{"page":63,"heading":"Babel Desktop","anchor":"babel-desktop","text":"Select the assembly on the project canvas and, in the properties panel, enable the optimizations you need in the Optimization group: DeadCodeElimination, InlineExpansion, SealClasses, and the attribute and metadata removal options. After you run the project, the Results view shows the optimization statistics. See Obfuscation Projects for how to work with projects in Babel Desktop."},{"page":64,"heading":"","anchor":"","text":"Code Optimizations refer to a set of techniques employed by Babel Obfuscator to improve the efficiency and performance of the code during the obfuscation process. These optimizations focus on refining the generated code to make it faster and harder to understand when decompiled. In this section, we will explore the code optimization strategies utilized by Babel and understand how they impact code readability and execution speed."},{"page":64,"heading":"Inline Expansion","anchor":"inline-expansion","text":"Inline Expansion is an optimization technique employed by Babel Obfuscator to substitute method calls with the actual instructions contained within the method's body. This process eliminates the overhead of function invocation, resulting in improved performance.\nTo enable inline expansion, you have to target specific methods that should be expanded inline. There are two ways to achieve this.\nFirstly, you can apply theSystem.Reflection.ObfuscationAttribute directly to the method you want to inline. This attribute should include the Feature = \"inline\" parameter to indicate that the method should undergo inline expansion.\n[Obfuscation(Feature = \"inline\", Exclude = false)]\npublic void Info(string message)\n{\n  // Method body\n}\nBy specifying the Feature = \"inline\" attribute parameter, Babel recognizes that the method should be subject to inline expansion during the obfuscation process.\nAlternatively, you can define an obfuscation rule that includes the method or type you want to inline in your configuration file:\n<Rule name=\"inline1\" feature=\"optimizations\" exclude=\"false\">\n  <Pattern>AcmeDataMining.Logger::Info(String) : Void</Pattern>\n  <Properties>\n    <Inline>True</Inline>\n  </Properties>\n</Rule>\nIn this example, the rule specifies that the Info method within the AcmeDataMining.Logger type should be expanded inline, as indicated by the <Inline>True</Inline> property."},{"page":64,"heading":"Inline Expansion","anchor":"inline-expansion","text":"Then to initiate the inline expansion process, you need to enable InlineExpansion in the Optimization group of Babel Desktop, or use the --inlineexpansion switch when executing Babel via the command line:\nbabel myapp.exe --inlineexpansion\nMSBuild Babel Task\nTo enable inline expansion in Babel Obfuscator using MSBuild Babel Task, you can set the <InlineExpansion> property within the <PropertyGroup> section of your MSBuild project file.\nHere's an example of how to enable inline expansion using the <InlineExpansion> property:\n<PropertyGroup>\n  <InlineExpansion>true</InlineExpansion>\n</PropertyGroup>\n\n<Babel InlineExpansion=\"$(InlineExpansion)\" />\nIn the above code snippet, the <PropertyGroup> element is used to define the property <InlineExpansion> and set its value to true. This indicates that inline expansion should be enabled for the obfuscation process.\nReviewing the optimization statistics, you can observe the number of inline methods and the number of expansions that occurred during the optimization phase.\nOptimization phase, elapsed time 00.270s\nInlined methods (expanded): 266 (736)\nBy enabling inline expansion, Babel Obfuscator will identify the marked methods and substitute their calls with the actual instructions contained within their bodies. This optimization technique eliminates the overhead associated with method invocation, resulting in improved performance and potentially smaller code size."},{"page":64,"heading":"Const Fields Removal","anchor":"const-fields-removal","text":"Babel Obfuscator employs a code optimization technique known as Const Fields Removal, which involves replacing references to const field declarations directly with their corresponding values. By doing so, Babel eliminates the presence of const fields in the code, effectively removing any information that could potentially reveal details about the underlying algorithm or logic.\nThe process of replacing const field references with their values serves two main purposes. First, it helps reduce the size of the code by eliminating the need for explicit field declarations. This, in turn, enhances the overall efficiency and performance of the obfuscated application.\nSecondly, and more importantly, the removal of const fields aids in safeguarding the code against reverse engineering attempts. By replacing the references with actual values, Babel removes any trace of the original field names, making it harder for malicious actors to decipher the logic or deduce insights about the application's functionality.\nCommand Line\nTo enable const field removal at the command line interface (CLI) when using Babel Obfuscator, you can use the --constremoval switch. By including this switch in your command, Babel will perform the optimization to remove const fields from the code.\nHere's an example of how you can enable const field removal using the CLI:\nbabel myapp.exe --constremoval\nMSBuild Babel Task"},{"page":64,"heading":"Const Fields Removal","anchor":"const-fields-removal","text":"To enable const field removal in Babel Obfuscator using MSBuild, you can utilize the <ConstRemoval> property. By setting this property to true, you instruct Babel to perform the optimization and remove const fields from the code during the obfuscation process.\nHere's an example of how you can enable const field removal in MSBuild:\n<PropertyGroup> \n  <ConstRemoval>true</ConstRemoval> \n</PropertyGroup> \n\n<Babel ConstRemoval=\"$(ConstRemoval)\" />\nIn the above code snippet, the <PropertyGroup> element is used to define the <ConstRemoval> property and set its value to true. This indicates that const field removal should be enabled. Then, the <Babel> task is invoked with the ConstRemoval property passed as an argument, ensuring that Babel performs the const field removal optimization.\nXML Rules\nTo configure const field removal using XML rules in Babel Obfuscator, you can leverage the <Rule> element and the <Properties> sub-element to specify the <ConstRemoval> property. This allows you to selectively enable or disable const field removal for specific types or members within your codebase.\nHere's an example of XML configuration for const removal:\n<Rule name=\"const removal\" feature=\"optimizations\" exclude=\"false\">\n  <Pattern>Utilities.*</Pattern>\n  <Properties>\n    <ConstRemoval>false</ConstRemoval>\n  </Properties>\n</Rule>\nThe exclude attribute is set to false, indicating that the rule should be applied to the specified members identified by the pattern expression."},{"page":64,"heading":"Const Fields Removal","anchor":"const-fields-removal","text":"Within the <Properties> element, the <ConstRemoval> property is set to true, indicating that const field removal should be disabled for the matched types or members defined in the pattern.\nBy using XML rules, you have fine-grained control over the const field removal optimization in Babel Obfuscator. You can specify different rules for different parts of your codebase, allowing you to customize the obfuscation process according to your specific requirements and desired level of optimization."},{"page":65,"heading":"","anchor":"","text":"Dead Code Removal is a crucial optimization technique offered by Babel Obfuscator. It involves the identification and elimination of code that will never be executed during runtime. This includes methods, properties, fields, and even entire types that are determined to be unused. By removing dead code, Babel reduces the size and complexity of the obfuscated assembly, resulting in several benefits.\nDead code removal improves the loading time of the application. By eliminating unnecessary code, the obfuscated assembly becomes smaller, allowing for faster loading and initialization. This optimization is particularly beneficial for applications with large codebases or resource-intensive initialization processes.\nAdditionally, dead code removal enhances the overall performance of the obfuscated application. By eliminating unused methods, properties, and fields, the runtime execution becomes more efficient. The absence of dead code reduces unnecessary function calls and memory allocations, leading to improved runtime performance and responsiveness.\nFurthermore, dead code removal strengthens the security of the obfuscated code. By removing unused code, potential entry points or vulnerabilities are minimized, reducing the attack surface for malicious actors. Removing unused code also eliminates any accidental exposure of sensitive information or functionality that could be exploited.\nCommand Line"},{"page":65,"heading":"","anchor":"","text":"To enable dead code removal using the command line, you can use the --deadcode switch when running Babel.\nbabel myapp.exe --deadcode\nMSBuild Babel Task\n<PropertyGroup>\n  <DeadCodeElimination>true</DeadCodeElimination>\n</PropertyGroup>\n\n<Babel DeadCodeElimination=\"$(DeadCodeElimination)\" />\nXML Rules\nYou can control the removal of unused symbols by using XML rules that target the \"dead code\" feature. The following XML rule example prevents the removal of all symbols in the Utilities namespace:\n<Rule name=\"remove1\" feature=\"dead code\" exclude=\"true\">\n  <Pattern isRegEx=\"true\">\n    <![CDATA[\n      (Utilities.*)\n    ]]>\n  </Pattern>\n  <Description>Do not remove symbols in Utilities namespace</Description>\n</Rule>\nOverall, Dead Code Removal optimization offered by Babel Obfuscator significantly benefits the obfuscated codebase by reducing its size, improving loading time, enhancing runtime performance and strengthening security."},{"page":65,"heading":"Additional Entry Points","anchor":"additional-entry-points","text":"Babel Obfuscator employs a comprehensive analysis of the codebase, starting from the assembly's public interface and entry point. The primary objective of this analysis is to identify and determine all the portions of code that are reachable during runtime execution. By examining the entry point and traversing through the public interface, Babel is able to establish the execution flow, identifying methods that are not reachable, meaning they are not invoked or accessed during the program's execution. These methods are considered \"dead code\" as they do not contribute to the overall functionality of the application.\nIn addition to analyzing the code from the assembly's public interface and entry point, Babel Obfuscator offers the flexibility to consider other entry points that may be necessary for proper code execution. These additional entry points include methods that might be accessed through reflection or internally by other components using the InternalVisibleTo Attribute.\nYou specify these additional entry points as regular expressions passed to the dead code removal option, as shown in Specifying Entry Points below. In Babel Desktop, enable DeadCodeElimination in the Optimization group of the selected assembly and add the entry point expressions to its list."},{"page":65,"heading":"Additional Entry Points","anchor":"additional-entry-points","text":"By providing these entry points, Babel Obfuscator ensures that the reachable code is accurately determined and that any methods required for reflection or internal usage are preserved during the optimization process. This allows for a comprehensive analysis of the codebase and the removal of dead code that is not reachable from any of the specified entry points.\nSpecifying Entry Points\nTo specify additional entry points to dead code removal at the command line, you can use regular expressions as arguments for the --deadcode option. Regular expressions provide a powerful and flexible way to define patterns for matching method names. You can specify specific methods, target entire namespaces, match patterns within method names, or even combine multiple expressions to include multiple entry points.\nHere are a few examples of how entry points can be specified using regular expressions as arguments of the --deadcode option:\nTo specify a specific method:\nbabel myapp.exe --deadcode MyNamespace.MyClass.MyMethod\nTo specify all methods within a namespace:\nbabel myapp.exe --deadcode MyNamespace.*\nTo specify all methods within a specific class:\nbabel myapp.exe --deadcode MyNamespace.MyClass.*\nTo specify methods that match a certain pattern using regular expressions:\nbabel myapp.exe --deadcode MyNamespace.*[Gg]et.*\nTo specify multiple entry points using multiple regular expressions:\nbabel myapp.exe --deadcode MyNamespace.* --deadcode AnotherNamespace.*"},{"page":65,"heading":"Additional Entry Points","anchor":"additional-entry-points","text":"To specify entry points for the Babel task in your MSBuild project using regular expressions, you can utilize the <DeadCodeElimination> property. This property allows you to define a list of regular expressions separated by semicolons (;) that match the entry point methods.\nHere's an example of how you can specify entry points using regular expressions in the Babel task:\n<PropertyGroup>\n  <DeadCodeElimination>MyNamespace.*;true</DeadCodeElimination>\n</PropertyGroup>\n\n<Babel DeadCodeElimination=\"$(DeadCodeElimination)\" />\nThese examples demonstrate how regular expressions can be used to define entry points for Babel's dead code removal analysis. By providing specific patterns or using wildcards, you can precisely target the desired methods or groups of methods that should be considered during the analysis."},{"page":66,"heading":"","anchor":"","text":"Metadata optimizations in Babel Obfuscator involve a series of techniques to enhance the obfuscated code's metadata, which contains information about types, members, attributes, and other crucial aspects of the codebase. These optimizations focus on improving the code's security, reducing its size, and making it more resistant to reverse engineering attempts."},{"page":66,"heading":"Automatic Class Sealing","anchor":"automatic-class-sealing","text":"Automatic Class Sealing is an optimization technique offered by Babel Obfuscator that aims to improve the performance of code execution by sealing classes that are not used as base classes in an inheritance chain. When a class is sealed, the Just-In-Time (JIT) compiler can generate more efficient code by calling virtual methods non-virtually, eliminating the overhead associated with virtual method resolution.\nCommand Line\nEnabling automatic class sealing can be done through the command line using the --seal switch, which applies optimization to all non-public types within the target assembly. For example, the following command seals the classes in the \"myapp.exe\" assembly:\nbabel myapp.exe --seal\nHowever, if there is a need to selectively exclude certain types from automatic class sealing, an XML rule can be defined. By specifying a regular expression pattern, it is possible to exclude specific types from being sealed. In the example XML rule provided, classes within the \"Utilities\" namespace will not be automatically sealed:\n<Rule name=\"seal classes\" feature=\"optimizations\" exclude=\"false\">\n  <Pattern>Utilities.*</Pattern>\n  <Properties>\n    <ClassSealing>false</ClassSealing>\n  </Properties>\n</Rule>"},{"page":66,"heading":"Automatic Class Sealing","anchor":"automatic-class-sealing","text":"It's important to note that the \"exclude\" attribute is set to \"false\" in this example to prevent disabling all optimizations. By using automatic class sealing selectively, developers can fine-tune the optimization process to suit their specific requirements and strike a balance between performance improvements and preserving certain class behaviours.\nMsBuild Babel Task\nTo enable the automatic sealing of classes using the MSBuild Babel Task, you can set the <SealClasses> property within a <PropertyGroup> element:\n<PropertyGroup>\n  <SealClasses>true</SealClasses>\n</PropertyGroup>\n\n<Babel SealClasses=\"$(SealClasses)\" />\nIn this example, the <SealClasses> property is set to true, indicating that the automatic sealing of classes should be enabled during the obfuscation process."},{"page":66,"heading":"Unwanted Attributes Removal","anchor":"unwanted-attributes-removal","text":"The attribute removal optimization in Babel Obfuscator focuses on removing unnecessary attributes from the compiler-generated code. Often, the code generated by the compiler includes attributes that do not affect the application's behaviour during execution. Babel can identify and remove such attributes applied to defined symbols, resulting in a more concise and efficient obfuscated codebase.\nFor example, attributes like CompilerGeneratedAttribute or DebuggerDisplayAttribute, which are not essential to the application itself, can be safely removed. By eliminating these unwanted attributes, Babel reduces the size of the obfuscated target and eliminates any distinction between compiler-generated code and user code.\nCommand Line\nTo enable the \"Unwanted Attributes Removal\" optimization, the --cleanattrs switch can be used at the command line when running Babel.\nbabel myapp.exe --cleanattrs\nThe list of attributes that will be removed can be found in the babel.exe.config file. To view the configured attributes for removal, the following command can be used:\nbabel --help cleanattrs\nThe output will display the unwanted attributes along with their full type names.\nBabel also allows for specifying a regular expression to match unwanted attribute type full names. For example:\nbabel myapp.exe --cleanattrs System.Diagnostics.*Attribute\nThis command will remove all custom attribute types defined in the System.Diagnostics namespace."},{"page":66,"heading":"Unwanted Attributes Removal","anchor":"unwanted-attributes-removal","text":"The configuration section of babel.exe.config includes a predefined list of unwanted attributes stored under the \"UnwantedAttributes\" element. Each item in the collection represents a qualified attribute type name.\nMsBuild Babel Task\nTo enable the removal of unwanted attributes using the MSBuild Babel Task, you can set the <CleanAttributes> property within a <PropertyGroup> element:\n<PropertyGroup>\n  <CleanAttributes>System.Diagnostics.*Attribute;true</CleanAttributes>\n</PropertyGroup>\n\n<Babel CleanAttributes=\"$(CleanAttributes)\" />\nIn this example, the <CleanAttributes> property specifies the list of regular expressions matching the unwanted attribute's full type name to be removed. The true at the end is the global switch for this feature.\nXML Rules\nAn XML rule property called \"UnwantedAttributes\" is available to finely configure attribute removal for all members matching a given regular expression. By defining rules, developers have the flexibility to exclude specific subsets of code from the removal of unwanted attributes.\nHere's an example XML rule for excluding the \"Utilities\" namespace from attribute removal:\n<Rule name=\"unwanted attributes\" feature=\"optimizations\" exclude=\"false\">\n  <Pattern>Utilities.*</Pattern>\n  <Properties>\n    <UnwantedAttributes>false</UnwantedAttributes>\n  </Properties>\n</Rule>"},{"page":66,"heading":"Unwanted Attributes Removal","anchor":"unwanted-attributes-removal","text":"By utilizing the \"Removing of Unwanted Attributes\" optimization, Babel Obfuscator helps optimize the obfuscated code by eliminating unnecessary attributes, reducing code size, and ensuring that only relevant and essential information remains within the obfuscated assembly."},{"page":66,"heading":"System Enum Types Removal","anchor":"system-enum-types-removal","text":"Enum Types Removal is an optimization capability offered by Babel Obfuscator that focuses on removing System.Enum types defined within the target assembly. This optimization technique replaces the fields of these enumeration types with their corresponding values, resulting in a more compact codebase and making the disassembled code harder to comprehend, as constant values are used instead of field names.\nCommand Line\nEnabling the removal of enumeration types can be done by using the --enumremoval option at the command line when running Babel. For example:\nbabel myapp.exe --enumremoval\nThis command activates the optimization to remove System.Enum types from the obfuscated assembly.\nMSBuild Babel Task\nTo enable Enum Types Removal using the MSBuild Babel Task, you can set the <EnumRemoval> property to true within a <PropertyGroup> element:\n<PropertyGroup>\n  <EnumRemoval>true</EnumRemoval>\n</PropertyGroup>\n\n<Babel EnumRemoval=\"$(EnumRemoval)\" />\nXML Rules\nBabel provides the EnumRemoval rule property in XML Rules, which allows developers to selectively include or exclude specific enumeration types. This can be achieved by defining XML rules that specify the desired behaviour for certain patterns or namespaces. Here is an example XML rule that excludes the \"Utilities\" namespace from the removal of enumeration types:"},{"page":66,"heading":"System Enum Types Removal","anchor":"system-enum-types-removal","text":"<Rule name=\"enum removal\" feature=\"optimizations\" exclude=\"false\">\n  <Pattern>Utilities.*</Pattern>\n  <Properties>\n    <EnumRemoval>false</EnumRemoval>\n  </Properties>\n</Rule>\nBy using this rule, the enumeration types within the \"Utilities\" namespace will not be removed during the optimization process.\nThe System Enum Types Removal optimization offers several benefits. Firstly, it helps save disk space by reducing the size of the obfuscated assembly. Secondly, by replacing the enumeration fields with their corresponding values, it adds an additional layer of obfuscation and complexity to the disassembled code, making it more challenging for potential adversaries to understand the underlying logic and behaviour.\nBy leveraging the System Enum Types Removal optimization in Babel Obfuscator, developers can enhance the security and protect the integrity of their codebase while also optimizing the size and readability of the obfuscated assembly."},{"page":66,"heading":"Disgregate Removal","anchor":"disgregate-removal","text":"Disgregate Removal is an optimization feature offered by Babel Obfuscator that focuses on removing properties and events information from the respective metadata tables. This optimization technique involves converting the get_ and set_ methods of properties, as well as the add_ and remove_ methods of events, into standard methods. By removing this metadata and converting the methods, the size of the metadata is reduced, and when combined with renaming, it enhances obfuscation, making it more challenging to reconstruct the original property or event.\nCommand Line\nTo enable the removal of properties and event metadata, the --disgregateremoval option can be used at the command line when running Babel. For example:\nbabel.exe myapp.exe --disgregateremoval\nThis command activates the optimization to remove properties and events metadata from the obfuscated assembly.\nMSBuild Babel Task\nTo enable Disgregate Removal using the MSBuild Babel Task, you can set the <DisgregateRemoval> property to true within a <PropertyGroup> element:\n<PropertyGroup>\n  <DisgregateRemoval>true</DisgregateRemoval>\n</PropertyGroup>\n\n<Babel DisgregateRemoval=\"$(DisgregateRemoval)\" />\nXML Rules\nAdditionally, Babel allows for selective enabling or disabling of properties and events disgregation through XML rules. By defining XML rules, developers can specify the desired behavior for specific patterns or namespaces. Here is an example XML rule that disables disgregate removal for the \"Utilities\" namespace:"},{"page":66,"heading":"Disgregate Removal","anchor":"disgregate-removal","text":"<Rule name=\"disgregate removal\" feature=\"optimizations\" exclude=\"false\">\n  <Pattern>Utilities.*</Pattern>\n  <Properties>\n    <DisgregateRemoval>false</DisgregateRemoval>\n  </Properties>\n</Rule>\nWith this rule, the properties and events within the \"Utilities\" namespace will not undergo the disgregate removal optimization during the obfuscation process.\nDisgregate Removal optimization provides several benefits. Firstly, it reduces the size of the metadata tables, resulting in a more compact, obfuscated assembly. Secondly, when combined with renaming, it improves the overall obfuscation of the codebase, making it more difficult for attackers to understand and reconstruct the original properties and events.\nBy utilizing the Disgregate Removal optimization in Babel Obfuscator, developers can enhance the security and protection of their code, optimize the size of the obfuscated assembly, and add an additional layer of complexity to the code structure, thereby increasing the difficulty of reverse engineering."},{"page":67,"heading":"Warning Codes","anchor":"warning-codes","text":"The following table shows the list of warning codes and messages."},{"page":67,"heading":"Warning Codes","anchor":"warning-codes","text":"CF0001 | Unknown invalid op-code mode.\nCF0002 | Invalid opcodes will cause the application to run on 32-bit.\nEI0001 | Missing key information, the target assembly will not be resigned.\nEI0002 | Could not sign assembly.\nEM0001 | Return type <typename> not supported...\nEM0002 | Methods with pointer parameters are not supported...\nEM0003 | Generic methods are not supported...\nEM0004 | Generic instance method inline tokens are not supported...\nEM0005 | Inline metadata tokens are not supported...\nEM0006 | Bad inline token type.\nEM0007 | Unknown metadata signature calling convention.\nEM0008 | Generic parameter owner not set.\nEM0009 | Could not resolve generic parameter type.\nEM0010 | Type <typename> not supported.\nEM0011 | Generic instance types field are not supported.\nEM0012 | A duplicated encryption source <name> has been found with different properties.\nEM0013 | Methods with by-reference-like (ref struct) parameters are not supported...\nMG0001 | Found duplicated type <typename> in merged assembly <assembly>.\nMG0002 | Referenced assembly <assembly> has a reference to the merged assembly <assembly>.\nMG0003 | Resource data <name> into <name> has already been added.\nMG0004 | Could not resolve...\nMG0005 | Merging referenced assembly <assembly> of different version <version>. The expected assembly version is <version>. The merged assembly might not be working properly.\nMG0006 | The assembly <assembly> has already been merged."},{"page":67,"heading":"Warning Codes","anchor":"warning-codes","text":"MG0007 | The type <type> defined in <assembly> was not found in merged scope <name>.\nMG0008 | Merge of mixed mode assembly is not supported: <assembly>.\nMG0009 | The demo version of <assembly> assembly cannot be merged. Please use the retail component.\nOB0001 | Missing key information, could not sign resource assembly <assembly>.\nOB0002 | The <name> named <name> defined into referenced assembly <assembly> should not be obfuscated.\nOB0003 | The following virtual members: <name list> cannot be obfuscated cause...\nOB0004 | The Unicode character set provided is not valid to rename <name> symbols. The ASCII character set will be used instead.\nOB0005 | Obfuscation rules are preventing renaming of the following public members: <name list>\nOB0006 | Found rule conflict for the following symbols: <name list>. The <name> prevents symbol renaming, while <name> requires to rename. The symbols will not be renamed.\nOB0007 | Name conflict for referenced member <name>.\nOP0001 | Could not remove enum(s) <name list>. Method <name> has a duplicate.\nOP0002 | Method <name> cannot be inlined.\nPR0001 | The target assembly has already been obfuscated, some issues might happen during obfuscation or at runtime.\nPR0002 | Warning: missing <name> string method.\nPR0003 | Suppressing MSIL disassembler option is not supported on .NET Framework assemblies.\nPR0004 | Suppress MSIL disassembler (ildasm.exe) option is not supported."},{"page":67,"heading":"Warning Codes","anchor":"warning-codes","text":"PR0005 | The target assembly has already been obfuscated, babel will exit now without performing any further processing.\nPR0007 | String algorithm <name> is not supported. Algorithm <name> will be used instead.\nPR0008 | Emit invalid op-codes option is not supported on {0} assemblies.\nPR0009 | The reference <assembly> has a higher version <verrsion> than the version <version> in the current target.\nPR0010 | The assembly <assembly> is already present in the list of references.\nPR0011 | Dynamic proxy call option is not supported on <name> assemblies.\nPR0012 | Resource encryption is not supported on <name> assemblies.\nPR0013 | MSIL encryption is not supported on <name> assemblies.\nPR0014 | Assembly embedding is not supported on <name> assemblies.\nPR0015 | Suppress reflection option is not supported on <name> assemblies.\nPR0016 | Invalid ObfuscationAttribute at...\nRU0001 | Feature <name> has an unknown property name <name>\nRU0002 | Rules file unknown node <name> at line <n>, position <n>, node...\nRU0003 | Rules file unknown attribute at line <n>, position <n>, attribute <name>=<value>\nRU0004 | Unknown feature <name>\nSE0001 | Encryption string algorithm <name> could not encrypt string <value>\nW00000 | This is an evaluation version, the obfuscated assembly will no longer work after...\nW00001 | Could not find debug symbols for <assembly>\nW00002 | Cannot parse <name> resource stream <name>\nW00003 | XAML resource stream <name>. Cannot resolve the following members: <name list>."},{"page":67,"heading":"Warning Codes","anchor":"warning-codes","text":"W00004 | Obfuscation Agent is disabled.\nW00005 | Debug symbols not loaded: <assembly>.\nW00006 | The member name <name> defined by the assembly <assembly> has been renamed according to the information contained inside the XML map file. Please remove this member from the <name> resource.\nW00007 | Could not delete directory: <name>.\nW00008 | The assembly <assembly> was resolved to <assembly>.\nW00009 | Could not find method: <name>.\nW00010 | Could not use method <name> as module initializer. The method must be a static method without parameters.\nW00011 | The referenced assembly <assembly> full name differs from the loaded map file <name>.\nW00012 | Invalid map file assembly name <name>.\nW00013 | Could not resolve assembly <assembly>.\nW00014 | Error getting symbols from <name>.\nW00015 | Cannot find overridden methods of <name>: <name list>\nW00016 | Could not sign assembly <assembly>: ...\nW00017 | The debug symbol file <file> do not match assembly <assembly>\nW00018 | Assembly resolver failed to resolve assembly <assembly>: ..."},{"page":68,"heading":"","anchor":"","text":"Babel Obfuscator provides support for custom plug-ins that enable users to extend the functionality of the obfuscator beyond what is provided out of the box. With a custom plugin, you can:\nYou can create your string and value encryption algorithms\nRename Symbols like types, methods, properties, events and fields\nMerge custom code into your assembly\nDefine obfuscation rules by querying the assembly metadata\nChange assembly code\nAnd much more…\nCustom plugins can be developed using the .NET framework and integrated into Babel using the plugin management interface."},{"page":68,"heading":"Code Samples","anchor":"code-samples","text":"Several Babel plugins are available on GitHub, and their source code is included. Users interested in implementing a custom plugin can refer to these sample plugins as a starting point. To download the solution containing all the plugin projects, users can use the git command:\ngit clone https://github.com/babelfornet/BabelPlugins.git\nThis allows users to explore the code and modify the plugins to fit their specific needs."},{"page":68,"heading":"Using Plugin at Command Line","anchor":"using-plugin-at-command-line","text":"Babel can accept a list of plugin files at the command line. To specify one or more plugin files at the babel.exe command line, you can use the --plugin switch followed by the full path to the plugin file:\nbabel MyApp.exe --plugin CustomPlugin1.dll --plugin CustomPlugin2.dll\nIt is possible to pass arguments to plugins using the command line switch --argument\nbabel MyTarget.exe --plugin CustomPlugin1.dll --plugin CustomPlugin2.dll\n--argument arg1=value1 --argument arg2=value2\nThe arguments are defined as key-value pairs. Multiple --argument switches can be used to specify several arguments."},{"page":68,"heading":"Using Plugin in MSBuild Babel Task","anchor":"using-plugin-in-msbuild-babel-task","text":"If you are using the MSBuild Babel task, you can specify a list of plugins by adding the Plugins attribute to the Babel task as follow:\n<ItemGroup>\n   <BabelPlugin Include=\"DesEncrypt.dll\"/>\n   <BabelPlugin Include=\"LicenseInjector.dll\"/>\n </ItemGroup>\n <Babel\n   Plugins=\"@(BabelPlugin)\"\n   PluginsArguments=\"arg1=value1;arg2=value2\" />\nThe PluginsArguments property of the Babel task allows you to specify plugin arguments for all plugins. The list of plugin arguments is represented by a sequence of key-value pairs separated by a semicolon."},{"page":68,"heading":"Using Plugins From Babel Desktop","anchor":"using-plugins-from-babel-desktop","text":"To use a plugin for a target assembly in Babel Desktop:\nSelect the target assembly on the project canvas.\nIn the Files & dependencies group of the properties panel, add the plugin DLL to Plugins. The command palette entry Engine plugins: Configure DLL paths jumps to the same option.\nRun Engine plugins: Discover argument names from the command palette to list the arguments the plugin accepts, then enter their values in PluginsArguments.\nPlugins run inside the obfuscation engine with your account permissions, so only load plugin DLLs you trust."},{"page":69,"heading":"","anchor":"","text":"The Babel Encrypt plugin is a powerful Babel Obfuscator extension for enhancing the security of encrypted strings. It is designed to work with Babel Obfuscator and provides advanced encryption features for your assemblies.\nThis plugin employs multi-pass encryption algorithms, such as XOR and HASH, on each inline string based on the encrypted string's length. Short strings can be decrypted fast by the XOR algorithm, while the HASH algorithm best handles long strings. The XOR algorithm has the advantage to inline encrypted strings, so there is no need to decrypt the string when the application starts. The HASH algorithm stores the strings inside an encrypted hash table that is decrypted when the application starts.\nThe purpose of using two different encryption algorithms is to increase the difficulty of reverse engineering the code. Encrypting the strings in multiple passes makes it more challenging for a deobfuscator to determine the correct method call sequence for decrypting the strings. The multiple-pass encryption feature supported by the encryption plugin adds an extra layer of security by combining hashing and XOR encryption methods, making it even harder for a deobfuscator to decrypt the strings."},{"page":69,"heading":"Full Feature Set","anchor":"full-feature-set","text":"Double encryption algorithm XOR HASH.\nIterates through the assembly strings several times to provide multiple levels of encryption.\nThe decryption algorithm can be protected with extra control flow and code encryption (not available with standard HASH and XOR algorithms).\nDefeat most common deobfuscators.\nProvides tamper-proof against calling method signature changes.\nString encryption exclusion based on string dictionary or string length.\nFully configurable using external arguments (see --argument babel command line switch)\nSupports all versions of .NET Framework from 2.0 to 4.8\nSupports .NET Core 3.1 and .NET 5 through .NET 10.\nPlugin source code available."},{"page":69,"heading":"License","anchor":"license","text":"Please refer to the general babelfor.NET product EULA.\nThe source code and binaries of the Babel Encrypt Plugin are already available to all owners of a Babel Obfuscator Ultimate license or as a separate purchase for all the owners of a Babel Obfuscator Enterprise license. You can modify the plugin source code to extend or change the plugin functionalities to your needs. You cannot distribute or sell this plugin, or a modified version, to third parties.\nTHIS SOFTWARE IS PROVIDED \"AS IS\", WITHOUT A WARRANTY OF ANY KIND. THE AUTHOR OF THIS PLUGIN (\"BABELFOR.NET\") DON'T TAKE ANY RESPONSE FOR ANY DAMAGES SUFFERED AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE PLUGIN."},{"page":70,"heading":"","anchor":"","text":"The \"Babel Encrypt\" plugin is a component included in the Babel Obfuscator Ultimate edition. However, for those with the Enterprise edition, it requires a separate purchase. This plugin comes as an assembly file called \"BabelEncrypt.dll\" and works seamlessly with the Babel command line tool. To utilize it, simply specify the plugin file's path in the command line as follows:\nbabel myapp.exe --plugin BabelEncrypt.dll --stringencryption custom\nWhere myapp.exe is the target assembly you want to obfuscate. The string encryption argument [custom] is needed to let babel use the algorithm provided by the plugin instead of the built-in string encryption algorithms."},{"page":70,"heading":"Plugin Arguments","anchor":"plugin-arguments","text":"The Babel Encrypt Plugin accepts the following optional arguments:\npassword <string>\nSet a password used to encrypt string data. The encryption is performed with the Triple DES algorithm. If not specified, a random password is generated.\niterations <number>\nThe number of encryption passes to be performed (default: 1).\nminStringLength <number>\nIf a string's length is less than the specified value, it will not be encrypted. When this option is set to 0, all strings, regardless of length, will be encrypted, which is the default behaviour. By setting a value greater than 0, you can exclude short strings from being encrypted, which may improve performance or have other benefits depending on your specific use case. It's important to note that the value you set for the minimum string length will directly impact the level of obfuscation applied to your assembly.\nminHashStringLength <number>\nSet the minimum string length to encrypt with the HASH algorithm (default: 15).\nuseLocalVars <true|false>"},{"page":70,"heading":"Plugin Arguments","anchor":"plugin-arguments","text":"Whether to create local variables to call the decryption method (default: false). By default, this option is set to \"false,\" meaning that the decryption method is not called using local method variables. However, if set to \"true,\" the decryption method will be called using local method variables. This can help to further scramble the code and add extra protection to the obfuscated assembly. Utilizing local method variables during decryption can make the code more difficult to understand and reverse engineer, as the execution path will be more complex and less predictable. However, it may also affect the performance of the obfuscated assembly, as local method variables can increase the memory usage and processing time required to execute the code.\nextraControlFlow <true|false>\nThis option aims to increase the level of security and protect the encrypted strings from being easily reverse-engineered or decompiled. When enabled, additional control flow obfuscation is applied to the method containing encrypted strings, making the code more scrambled and harder to understand. The default setting is typically \"false\" but can be changed based on the desired level of obfuscation and protection.\ncheckDeobfuscators <true|false>\nThe option to check for a deobfuscator tool is a security feature in Babel Obfuscator that helps prevent reverse engineering of the obfuscated code."},{"page":70,"heading":"Plugin Arguments","anchor":"plugin-arguments","text":"Whether to check the presence of a deobfuscator tool. If a deobfuscator is detected, the decryption of the strings will not occur, and the program will silently fail (default: false).\nuseCodeEncryption <true|false>\nWhether to use Babel Obfuscator code encryption feature to encrypt the code of the string decryption methods. This option can work only when code encryption is enabled. (default: false).\ndictionary <path|expression>\nThe specified text file contains a list of strings or regular expressions that determine which strings should not be encrypted by the obfuscation tool. The file should be structured so that each line represents an exact string or a regular expression pattern. The obfuscation tool will use this information to exclude the listed strings from the encryption process. Regular expressions allow for a more flexible and comprehensive approach to excluding strings while providing the exact strings ensures that specific strings are not encrypted regardless of the broader pattern."},{"page":70,"heading":"Examples","anchor":"examples","text":"Here are some examples of using the plugin from the Babel Obfuscator command line.\nMedium protection\nEnable deobfuscator detection besides using the default plugin configuration.\nbabel myapp.exe --plugin BabelEncrypt.dll --stringencryption custom --argument checkDeobfuscators=true\nFull protection\nThis example shows how to enable all plugin features with extra control flow for the decryption caller and use local variables to call the decryption method.\nbabel myapp.exe --plugin BabelEncrypt.dll --msilencryption --stringencryption custom --argument iterations=2 --argument extraControlFlow=true --argument useLocalVars=true --argument useCodeEncryption=true\nUsing an external dictionary\nYou can use a text file to set an exclusion word dictionary. Each line can be the exact string to exclude or a regular expression.\nbabel myapp.exe --plugin BabelEncrypt.dll --stringencryption custom --argument dictionary=exclusionlist.txt\nThe exclusionlist.txt text file content:\n.*@acme.com\nNo secret here to encrypt"},{"page":70,"heading":"Setup Babel Encrypt in DevOps","anchor":"setup-babel-encrypt-in-devops","text":"If you are utilizing the Babel.Obfuscator NuGet package within your DevOps environment or any other build system that supports NuGet packages, you can seamlessly incorporate the Babel Encrypt plugin into your build process.\nThis can be accomplished by adding the following MSBuild instructions to your project file:\n<ItemGroup>\n  <BabelPlugin Include=\"$(BabelTaskDir)BabelEncrypt.dll\" />\n</ItemGroup>\n<PropertyGroup>\n  <PluginsArguments>iterations=3</PluginsArguments>\n</PropertyGroup>\nWith these instructions in place, when you trigger a build in your DevOps environment or build system, the Babel Encrypt plugin will be invoked, incorporating additional encryption alongside the code obfuscation provided by Babel Obfuscator."},{"page":70,"heading":"Configure Babel Encrypt in Babel Desktop","anchor":"configure-babel-encrypt-in-babel-desktop","text":"You can set up the plugin for a target from the Babel Desktop interface instead of the command line:\nSelect the assembly on the canvas and open its Settings.\nUnder Files & dependencies, add the path of BabelEncrypt.dll to Plugins.\nRun Engine plugins: Discover argument names from the command palette. Babel reads the arguments the plugin declares and fills in the keys of PluginsArguments, where you enter their values.\nSet String Encryption to custom so the engine uses the plugin's algorithm instead of the built-in ones.\nTo use useCodeEncryption, also enable MSIL Encryption.\nThe plugin runs in the local engine process with your account permissions, so only add a plugin DLL you trust. Each setting applies to the selected assembly; repeat the steps for every target that needs the plugin."},{"page":71,"heading":"","anchor":"","text":"The plugin is distributed with full C# source code. To build the plugin from the source code, you need the following:\nVisual Studio 2022 or greater\nThe latest release of Babel Obfuscator Enterprise or Ultimate edition"},{"page":71,"heading":"Build Instructions","anchor":"build-instructions","text":"Open the Visual Studio solution file, Babel.BabelEncrypt.sln and build the project. The plugin project references babel.exe, the .NET Framework build of the command line tool, from the folder where you extracted the babel_net472 zip package. If the babel.exe reference is not found, remove the reference and add babel.exe from that folder."},{"page":71,"heading":"Changing the Code","anchor":"changing-the-code","text":"If you plan to modify the source code, this resource provides a quick reference and helpful tips to ease your entry and ensure a smooth start.\nSource Files\nThe Encrypt Plugin project contains the following files.\nEncryptPlugin.cs\nThis file contains the EncryptPlugin class that implements the Babel plugin interface. The plugin registers the string encryption service class used by Babel Obfuscator to encrypt strings. The arguments passed at the babel command line are processed here when the plugin is initialized.\nStringEncrypter.cs\nThe StringEncrypter class provides the string encryption service. It contains code for integrating the decrypter with the obfuscation target and implements the encryption methods for XOR and HASH algorithms. The Encrypt(...) method serves as the entry point, called by Babel Obfuscator during the string encryption phase, where the string is then processed by the XOR or HASH encrypter. Upon completion of the encryption phase, the Terminate() method is invoked to store the encrypted data within the target. The embedded decryption code will retrieve the encrypted data in the obfuscated target at runtime.\nStringDecrypter.cs\nThis file contains all the decryption logic that will be merged with the target assembly. As the classes inside this file are to be compiled and merged during the execution of the plugin, this file is compiled as an Embedded Resource of the DLL plugin."},{"page":71,"heading":"Changing the Code","anchor":"changing-the-code","text":"Info: To temporarily check the code syntax or make any code changes, you can switch the Build Action from Embedded Resource to Compile. After making all the changes, you can switch back to Embedded Resource and start debugging your changes."},{"page":71,"heading":"Debugging the Plugin","anchor":"debugging-the-plugin","text":"To debug the plugin, open Babel.BabelEncrypt project properties, select the Debug property page and create a new profile. Then set the following configuration:\nDebug Configuration\nExecutable\n<extraction folder>\\babel.exe, for example C:\\Tools\\Babel\\babel.exe (the folder where you extracted the zip package)\nCommand line arguments\nMyApp.exe @ -v5 --stringencrypt custom --plugin BabelEncrypt.dll\nWhere MyApp.exe is the target assembly that will be obfuscated using the plugin."},{"page":72,"heading":"","anchor":"","text":"A collection of practical use cases and examples that will guide you in\nstraightforwardly integrating Babel Obfuscator into your projects."},{"page":72,"heading":"General Samples","anchor":"general-samples","text":"The examples provided in this section cover various use cases and are not restricted to specific license editions. They can be used by all users regardless of which edition of Babel Obfuscator they have purchased.\nDecoding Stack Traces: Turn an obfuscated stack trace back into the original names, from Babel\nDesktop or the command line.\nClickOnce Deploy: Obfuscate a ClickOnce application from Visual Studio, so the published\nmanifests are signed over the protected assemblies.\nDetecting Babel Obfuscation: Check programmatically whether an assembly was obfuscated, and turn a\nsilently unprotected build into a failed one.\nObfuscate .NET MAUI: Configure Babel for a MAUI application and choose a linker mode that keeps\nAndroid and iOS builds working.\nBlazor Web App: Protect a Blazor application, using rules to reach the types generated from\nRazor pages.\nEnhancing Code Security: The settings that give the strongest protection for the least effort, and\nthe ones worth avoiding."},{"page":72,"heading":"Code Encryption","anchor":"code-encryption","text":"In this section, the examples presented are focused on demonstrating the code encryption feature of Babel Obfuscator.\nCode Encryption: Encrypt method bodies and execute them inside the managed Babel Virtual\nMachine, so the IL never appears in the assembly.\nFeature Based Licenses: Use code encryption passwords to gate features, so a license unlocks the\ncode itself rather than a runtime check."},{"page":72,"heading":"Cross Assembly Renaming","anchor":"cross-assembly-renaming","text":"The following examples demonstrate how to set up and configure cross-assembly renaming with Babel Obfuscator during the build process.\nPublish .NET App: Rename across assembly boundaries and keep the references consistent\nthrough dotnet publish."},{"page":72,"heading":"Build Servers (Ultimate)","anchor":"build-servers-","text":"These examples integrate Babel Obfuscator into a Continuous Integration pipeline, so every build produces protected assemblies without anyone having to remember a manual step. They all use the Babel Obfuscator NuGet package, which comes with the Ultimate edition and with the Babel Licensing site editions.\nThe pattern is the same on every build server: host the package on a private feed the agent can read, supply the license from a secret rather than from a file in the repository, and let dotnet build do the obfuscation. What changes is only how each platform names those two things.\nAzure DevOps: Host the package on an Azure Artifacts feed, authenticate with the pipeline\nidentity and pass the license as a secret variable.\nGitHub Actions: Install the package from GitHub Packages and hand Babel the license through\na repository secret.\nAppVeyor: Upload the package to the AppVeyor account feed and keep the feed password\nin an encrypted variable.\nUnit Tests: Run the test suite against obfuscated assemblies by feeding the map file\nback into the test project."},{"page":72,"heading":"Babel Obfuscator NuGet (Ultimate)","anchor":"babel-obfuscator-nuget-","text":"These samples specifically target the Babel Obfuscator integration using the Babel Obfuscator NuGet package. For the following projects using Babel Obfuscator NuGet packages, an Ultimate license is necessary.\nAndroid Application: Obfuscate a .NET for Android application with the package, and use rules to\nprotect the parts the platform does not resolve by name.\nNuGet Package: How the package inserts obfuscation into the SDK build pipeline, and every\nproperty that configures it."},{"page":73,"heading":"","anchor":"","text":"This section provides several code examples and projects to help developers understand how to use Babel Obfuscator effectively in their projects. From simple code snippets to full-fledged projects, these examples are designed to help developers quickly and easily get started with obfuscation. These examples can also be used as a reference when creating custom obfuscation rules and settings. Whether you're a beginner or an experienced developer, Babel Obfuscator's code examples are an excellent resource for anyone looking to implement obfuscation into their codebase.\nDecode Stack Trace\nClickOnce Deploy\nDetecting Babel Obfuscation\nObfuscate .NET MAUI\nBlazor Web App"},{"page":74,"heading":"","anchor":"","text":"Blazor applications can be protected using Babel Obfuscator, which provides several advantages. One of the main advantages of using Blazor's razor pages is the ability to combine HTML markup and C# code, allowing for more concise and readable code. This is particularly useful for developers who are more familiar with C# and prefer to work with it directly rather than relying on JavaScript or other front-end languages.\nObfuscation can rename classes, methods, and variables to obscure their original names, making it harder for potential attackers to understand and modify the code. In the case of a Blazor application, obfuscating the razor pages can also protect the HTML and C# code from being viewed or manipulated by end-users, providing an additional layer of security.\nThe GitHub repository at https://github.com/dotnet/blazor-samples contains several example applications that demonstrate various features and capabilities of Blazor technology. We will use one of these samples to show how to effectively integrate Babel Obfuscator to obfuscate a Blazor Web application.\ngit clone https://github.com/dotnet/blazor-samples\nTo get started with the Blazor app samples, you can clone the project repository available on GitHub. Once you have cloned the repository, navigate to the 7.0\\BlazorServerSignalRApp folder, and then open the project file named BlazorServerSignalRApp.csproj using Visual Studio."},{"page":74,"heading":"","anchor":"","text":"Info: If you have the Company license, you can obfuscate the application during the build process by adding a reference to the Babel.Obfuscator nuget. This can make the obfuscation process more straightforward and streamlined, allowing you to protect your application more effectively.\nOpen the project file by double-clicking on the BlazorServerSignalRApp project node in the Solution Explorer window and append the following MSBuild code snippet before the </Project> close tag.\n<UsingTask TaskName=\"Babel\" AssemblyName=\"Babel.Build, Version=10.0.0.0, Culture=neutral, PublicKeyToken=138d17b5bd621ab7\" />\n\n<Target Name=\"Obfuscate\" AfterTargets=\"Compile\">\n\n   <Babel InputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" OutputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" ObfuscateTypes=\"true\" ObfuscateEvents=\"true\" ObfuscateMethods=\"true\" ObfuscateProperties=\"true\"  ObfuscateFields=\"true\" VirtualFunctions=\"true\" UnicodeNormalization=\"false\" FlattenNamespaces=\"true\" StringEncryption=\"hash\" ResourceEncryption=\"true\" ControlFLowObfuscation=\"if=on;switch=on;case=on;call=on\" ControlFLowIterations=\"3\" />\n   \n</Target>\nSave the file and rebuild the solution. During the build process, Babel Obfuscator will automatically run and process the target assembly. You can test the obfuscated application by pressing F5 to launch the Visual Studio debugger.\nBlazor Server SignalR Application"},{"page":74,"heading":"","anchor":"","text":"In Blazor, each web page is a Razor component implemented as a .razor file which mixes HTML and C# code. When the component is compiled, Visual Studio generates a public class that corresponds to the Razor component, and this class is used to build the web page in the browser. Babel Obfuscator, by default, does not rename any externally visible symbol to avoid breaking the public interface of the assembly. Therefore, the public classes that correspond to the Blazor Web page will not be obfuscated.\nHowever, you can protect these web pages by configuring Babel Obfuscator using XML rules to obfuscate the classes explicitly. By doing so, you can prevent unauthorized access and modification of your code, making it more difficult for attackers to reverse-engineer or steal your application's logic.\nTo create an XML rule for protecting the code behind Razor pages with Babel Obfuscator, you first need to open the application assembly using any .NET inspection tool of your choice. This can be done using tools such as ILSpy, DotPeek, or dnSpy, which allow you to decompile the assembly and inspect its contents. Once you have opened the assembly, you can look for the class representing the code behind the Razor page you want to protect, which should have the same name as the Razor page and be located in the namespace name ending with Pages or Shared.\nBlazorServerSignalRApp Disassembled"},{"page":74,"heading":"","anchor":"","text":"Once you have located the class, you can create an XML rule for Babel Obfuscator that targets the classes you want to obfuscate. The XML rule should specify the name of the namespace you want to protect. In this case\nCreate a new XML project item named babelRules.xml and add the following rule:\n<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<Rules>\n  <Rule name=\"rule1\" feature=\"renaming\" exclude=\"false\">\n    <Target>Classes</Target>\n    <Pattern>*</Pattern>\n    <Namespace>BlazorServerSignalRApp.Pages,BlazorServerSignalRApp.Shared</Namespace>\n  </Rule>\n</Rules>\nThen add the babelRules.xml file to the Babel task as follow:\n<Babel RulesFiles=\"$(ProjectDir)babelRules.xml\" ... />\nRun the build and inspect the newly generated target assembly.\nBlazorServerSignalRApp Disassembled\nThe public classes corresponding to the web pages are no more visible.\nConfiguring Babel Obfuscator using XML rules allows for granular control over which classes to obfuscate and how they should be renamed, giving you greater flexibility and customization options.\nGenerally, you can use Visual Studio's Publish feature to deploy the application to a folder. Once you have published the app, you can execute the BlazorServerSignalRApp.exe executable to launch the application. This will allow you to test the obfuscated application and ensure that it is functioning as expected.\nThe sample application with Babel Obfuscator already integrated can be downloaded here."},{"page":75,"heading":"","anchor":"","text":"In ClickOnce deployment, the Babel task is configured to obfuscate the target assembly just after the Compile step.\nOpen the Visual Studio .csproj file and append the following MSBuild instructions before the Project close element.\n<UsingTask TaskName=\"Babel\" AssemblyName=\"Babel.Build, Version=10.0.0.0, Culture=neutral, PublicKeyToken=138d17b5bd621ab7\" />\n  \n<Target Name=\"Obfuscate\" AfterTargets=\"Compile\" Condition=\"'$(Configuration)|$(Platform)' == 'Release|AnyCPU'\">\n  \n<Babel InputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" OutputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" ObfuscateTypes=\"true\" ObfuscateEvents=\"true\" ObfuscateMethods=\"true\" ObfuscateProperties=\"true\" ObfuscateFields=\"true\" VirtualFunctions=\"true\" UnicodeNormalization=\"true\" FlattenNamespaces=\"true\" OverloadedRenaming=\"true\" StringEncryption=\"hash\" ControlFLowObfuscation=\"if=on;switch=on;case=on;call=on\" ControlFLowIterations=\"3\" />\n\n</Target>\nNote that the InputFile and OutputFile task attributes are set to intermediate build output. This will allow Visual Studio to create the ClickOnce deployable package using the obfuscated target assembly.\nWarning: Babel Obfuscator NuGet Package\n\nIf you have the Babel.Obfuscator NuGet package, there is no need to set up the Babel task in your project file. Just adds the NuGet package reference to your project.\nDownload the example source code."},{"page":76,"heading":"","anchor":"","text":"Babel Obfuscator is a tool that has gained prominence in the realm of .NET assemblies, primarily due to its ability to make them more resilient against reverse engineering. At its core, Babel doesn't merely obfuscate symbol names; it delves deeper, altering the assembly's code.\nThis transformation becomes a pivotal point of investigation for those trying to ascertain whether an assembly has been obfuscated by Babel. To aid in this investigative process, the Mono.Cecil library emerges as a powerful ally. This library facilitates the inspection and analysis of .NET assemblies, allowing one to probe into the assembly's metadata and search for modifications that bear the hallmark of Babel.\nBabel Obfuscator employs a unique renaming schema, often utilizing unreadable Unicode characters or ASCII strings to create obfuscated names. By examining these symbol names and identifying patterns characteristic of Babel's renaming strategy, one can determine whether the assembly has been obfuscated.\nFurthermore, in scenarios where Babel's encryption protection features are activated, a module initializer is added to the assembly. This initializer is responsible for setting up code and decrypting data that Babel Obfuscator has hidden. Its presence frequently acts as a beacon, indicating Babel's involvement."},{"page":76,"heading":"","anchor":"","text":"But perhaps the most direct indication of Babel's touch is the BabelObfuscationAttribute. When Babel is configured to include this attribute in an obfuscated assembly, its detection can almost conclusively confirm Babel's role in the obfuscation process.\nFor those who prefer a more hands-on approach, a sample project on GitHub elucidates this detection process.\ngit clone https://github.com/babelfornet/check-obfuscation-example.git\nOnce you navigate to the repository, open the .sln file in Visual Studio. With everything in place, you can compile and run the project.\nThis sample project compiles a CLI application designed to test if assemblies are obfuscated. The usage is straightforward:\nUsage: CheckObfuscation.exe <file|directory>\nWhere file refers to the assembly file you wish to check and directory denotes the directory you want to inspect for assemblies.\nWith these tools and knowledge at your disposal, you'll be adept at spotting the telltale signs of Babel's obfuscation in any .NET assembly."},{"page":77,"heading":"","anchor":"","text":"Babel Obfuscator can obfuscate a .NET MAUI (Multi-platform App UI) application by processing the compiled assembly file (e.g., a DLL or EXE) with its obfuscation engine. The obfuscation process will modify the compiled assembly to make the code harder to understand and reverse engineer while still preserving the functionality of the application.\nWhen obfuscating a .NET MAUI application with Babel Obfuscator, it is recommended to use the latest version of the obfuscator and to follow best practices for obfuscation, such as obfuscating all code and resources, keeping important names intact using exclusions, and testing the obfuscated application to ensure it still functions correctly.\nWe will use the TwoPaneView sample MAUI application available for download at GitHub https://github.com/dotnet/maui-samples.\ngit clone https://github.com/dotnet/maui-samples\nThese sample applications are designed to showcase various features of the MAUI framework and are a good starting point for building custom MAUI applications."},{"page":77,"heading":"Configure the Babel Task","anchor":"configure-the-babel-task","text":"Clone the sample repository\nClone the project's repository from GitHub and save it on your local machine.\nOpen the sample project\nNavigate to the folder named 7.0 in the repository, then to UserInterface/Views/TwoPaneView inside it. Open the solution TwoPaneViewSample.sln file in this folder.\nOpen the project file\nOnce the solution is opened in Visual Studio, double-click the solution project TwoPaneViewSample node, which can be found in the Solution Explorer window. This opens the project file inside the Visual Studio editor.\nAdd the Babel MSBuild instructions\nAppend the required MSBuild instructions to the project file. They tell Babel Obfuscator how to obfuscate the project's code.\n<UsingTask TaskName=\"Babel\" AssemblyName=\"Babel.Build, Version=10.0.0.0, Culture=neutral, PublicKeyToken=138d17b5bd621ab7\" />\n\n<Target Name=\"Obfuscate\" AfterTargets=\"Compile\">\n   <ItemGroup>\n      <_BabelSearchDirectories Include=\"@(ReferencePathWithRefAssemblies->'%(rootdir)%(directory)')\" Condition=\"'%(Extension)' == '.dll'\" />\n      <BabelSearchDirectories Include=\"@(_BabelSearchDirectories->Distinct())\" />\n   </ItemGroup>\n"},{"page":77,"heading":"Configure the Babel Task","anchor":"configure-the-babel-task","text":"   <Babel InputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" OutputFile=\"$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)\" SearchDirectories=\"@(BabelSearchDirectories)\" GenerateDebug=\"true\" ObfuscateTypes=\"true\" ObfuscateEvents=\"true\" ObfuscateMethods=\"true\" ObfuscateProperties=\"true\"  ObfuscateFields=\"true\" ObfuscateXaml=\"true\" VirtualFunctions=\"true\" UnicodeNormalization=\"false\" FlattenNamespaces=\"true\" StringEncryption=\"hash\"  ResourceEncryption=\"true\" ControlFLowObfuscation=\"if=on;switch=on;case=on;call=on\" ControlFLowIterations=\"3\" />\n   \n</Target>\nThe @BabelSearchDirectories item group in the context of Babel Obfuscator is used to define a list of directories that the obfuscation process will search in order to resolve any assembly references used in the project.\nThis list is generated by extracting search directories from the list of assemblies referenced by the project. The Babel Obfuscator looks at the metadata of the referenced assemblies to determine the location of their dependencies and then adds those directories to the @BabelSearchDirectories list. By doing this, the obfuscator can find all the necessary files it needs to obfuscate the project's code successfully.\nBuild and run the project\nNow you can compile and run the obfuscated .NET MAUI application.\n\nTwoPaneView MAUI Sample Application"},{"page":77,"heading":"Using NuGet Package","anchor":"using-nuget-package","text":"The Babel.Obfuscator NuGet package can be used on Windows, macOS and Linux for those who have the Ultimate, Server or Data Center edition. This provides a more straightforward configuration process, allowing users to add only Babel-related obfuscation settings without the burden of configuring other related build items. Using the NuGet package, users can avoid the Babel task and simplify the configuration process for their projects.\nAdd the Babel.Obfuscator.nupkg to TwoPaneViewSample project.\nSet the following properties inside the TwoPaneViewSample project file:\n<PropertyGroup>\n   <StringEncryption>hash</StringEncryption>\n   <ResourceEncryption>true</ResourceEncryption>\n   <ObfuscateXaml>true</ObfuscateXaml>\n   <ControlFlowObfuscation>if=on;switch=on;case=on;call=on</ControlFlowObfuscation>\n   <ControlFlowIterations>3</ControlFlowIterations>\n</PropertyGroup>\nThe sample project with Babel task instructions already included is available for download here."},{"page":77,"heading":"Linking Behavior for .NET MAUI iOS App","anchor":"linking-behavior-for-net-maui-ios-app","text":"When building .NET MAUI app, a linker (ILLink) is used to minimize app size by removing unused code. It keeps only essential methods, properties, fields, events, structs, and classes.\nThe ILLink supports three modes for .NET MAUI apps on iOS and Mac Catalyst:\nDon't link: All linker optimizations are disabled.\nLink SDK assemblies only: Only SDK assemblies are optimized by removing unused types and members, leaving your assemblies unaltered.\nLink all assemblies: This mode applies optimizations to minimize app size by modifying intermediate code.\nAn assembly obfuscated with Babel Obfuscator contains dynamic code and complex structures that ILLink fails to detect. As a result, aggressive optimizations like Link all assemblies can adversely affect the app’s functionality.\nTo avoid potential issues with ILLink when using obfuscated assemblies, it’s recommended to configure the ILLink mode to “Link SDK assemblies only”."},{"page":78,"heading":"","anchor":"","text":"The Babel Obfuscator nuget package provides an easy way to integrate the Babel MSBuild task in any .NET project. Once the package is installed, the Babel task is automatically added to the project file, and the necessary references are added to the project. This simplifies the process of integrating Babel Obfuscator into a project and ensures that all the required components are properly set up.\nUsing the Babel Obfuscator nuget package also provides some advantages compared to manually adding the Babel task to the project. Firstly, the package ensures that the correct version of the Babel task is used. Secondly, the package provides a more streamlined way of configuring the Babel task. The Babel Obfuscator NuGet package includes various configurations tested for the specific project type and is easily customizable to achieve the desired obfuscation result.\nThese code samples are specifically designed to demonstrate the integration of Babel Obfuscator using the Babel Obfuscator NuGet package. The samples showcase the flexibility and customization options available with the package, allowing developers to fine-tune obfuscation settings to achieve optimal results for their applications. Using the NuGet package, integrating Babel Obfuscator becomes easier and more streamlined, which helps save development time."},{"page":78,"heading":"","anchor":"","text":"Protecting Secrets with String and Value Encryption — hide API keys, connection strings and constants.\nHiding the Call Graph with Dynamic Proxy — make method calls opaque to a decompiler.\nOne Obfuscated File: Merging Dependencies — merge and internalize a dependency into a single protected assembly.\nDefense in Depth: Every Layer in One Build — the full Ultimate configuration on one project.\nAndroid Application — obfuscate a .NET Android app.\nThe package itself, its setup and every property it accepts are documented in the NuGet Package section of the manual."},{"page":79,"heading":"","anchor":"","text":"Almost every application ships secrets in its code — API keys, endpoints, connection strings,\nlicense parameters, \"magic\" numbers and lookup tables. A decompiler reads them in seconds. This\nexample uses the Babel Obfuscator NuGet package to remove those literals from the shipped assembly\nwith String Encryption and Value and Array Encryption, without changing a line of code.\nTo use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center\neditions). The source code is available on GitHub:\ngit clone https://github.com/babelfornet/secret-protection-nuget-example.git\nThe SecretApp console project references the Babel Obfuscator NuGet package (build-only) and\nturns on the two encryption layers in Release:\n<ItemGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <PackageReference Include=\"Babel.Obfuscator\" Version=\"12.0.0\">\n    <PrivateAssets>all</PrivateAssets>\n    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n  </PackageReference>\n</ItemGroup>\n\n<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <StringEncryption>stream</StringEncryption>\n  <ValueEncryption>int32=true;int64=true;single=true;double=true;array=true;true</ValueEncryption>\n  <ControlFlowObfuscation>if=true;switch=true;case=true;chain=true;true</ControlFlowObfuscation>\n  <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>\n</PropertyGroup>"},{"page":79,"heading":"","anchor":"","text":"The stream string algorithm\nmoves every string literal into an encrypted table, while\nValue and Array Encryption removes numeric constants and\ninline arrays from the IL. Both are decrypted on demand at runtime, so the program behaves exactly\nas before while the constants disappear from the binary. Setting BabelWarningsAsErrors to W00000\nturns an evaluation-mode build into an error, so an unprotected binary can never ship by accident.\nThe secrets themselves live in src/SecretApp/Secrets.cs:\ninternal static class Secrets\n{\n    // Strings -> removed by String Encryption (stream)\n    public static readonly string ApiKey           = \"DEMO-API-KEY-0000-1111-2222-3333-4444-5555\";\n    public static readonly string ServiceEndpoint  = \"https://api.internal.example.com/v3/ingest\";\n    public static readonly string ConnectionString = \"Server=db.internal;Database=Orders;User Id=svc;Password=__DEMO_PLACEHOLDER__;\";\n\n    // Numbers -> removed by Value Encryption\n    public static readonly int    ApiPort       = 8443;\n    public static readonly double RiskThreshold = 0.8734;\n\n    // Lookup table -> removed by Array Encryption\n    public static readonly int[] RolloutBuckets = { 12, 47, 63, 88, 91, 128, /* … */ 8192, 9001 };\n}"},{"page":79,"heading":"","anchor":"","text":"The example also highlights an important detail: the secrets are declared static readonly, not\nconst. A const value is baked into the assembly metadata and inlined at every use site, so it\nsurvives obfuscation and stays readable; a static readonly field is assigned with an ldstr/ldc\ninstruction that String and Value encryption rewrite. Building the sample in Release and searching\nthe two assemblies confirms the difference — the API key, endpoint and connection string are present\nin the Debug build and gone from the Release one, with identical program output."},{"page":80,"heading":"","anchor":"","text":"A decompiler reconstructs a lot from method calls: which framework APIs you use, how your own\nmethods chain together, and even the original names of local variables (inferred from the types you\ncall). This example uses the Babel Obfuscator NuGet package to enable Dynamic Proxy, which\nreplaces direct calls with calls routed through generated proxy delegates so the call graph is no\nlonger readable from the metadata.\nTo use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center\neditions). The source code is available on GitHub:\ngit clone https://github.com/babelfornet/dynamic-proxy-nuget-example.git\nThe business logic to hide is an ordinary set of methods that call each other and the .NET library\n(src/PricingEngine/Pricing.cs):\ninternal static class Pricing\n{\n    public static decimal Quote(string sku, int quantity, string tier)\n    {\n        decimal unit       = BasePrice(sku);              // internal call\n        decimal discounted = ApplyTierDiscount(unit, tier);\n        decimal volume     = ApplyVolumeBreak(discounted, quantity);\n        return Math.Round(volume * quantity, 2);          // external (BCL) call\n    }\n    // BasePrice / ApplyTierDiscount / ApplyVolumeBreak …\n}\nAfter obfuscation none of these calls is direct any more — each jumps through a generated proxy.\nThe PricingEngine console project enables Dynamic Proxy in Release with a single property:"},{"page":80,"heading":"","anchor":"","text":"<ItemGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <PackageReference Include=\"Babel.Obfuscator\" Version=\"12.0.0\">\n    <PrivateAssets>all</PrivateAssets>\n    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n  </PackageReference>\n</ItemGroup>\n\n<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <DynamicProxy>external=true;internal=true;true</DynamicProxy>\n  <FlattenNamespaces>true</FlattenNamespaces>\n  <OverloadedRenaming>true</OverloadedRenaming>\n  <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>\n</PropertyGroup>\nWith external=true, calls into the .NET base class library and referenced assemblies are hidden —\nthis alone defeats the trick where a decompiler recovers a variable's original name from the type it\ncalls. With internal=true, the calls between your own types are hidden as well, obscuring the\napplication's logic. Dynamic Proxy covers static, instance, virtual,\ninterface and generic (including LINQ) calls, and leaves a small set of caller-sensitive calls direct\nso behavior never changes.\nBuilding the sample in Release produces identical output while replacing the original direct calls\nof the pricing engine with generated proxy delegate types — the call flow a decompiler reconstructs\nis no longer the one you wrote. Dynamic Proxy also\nresists automated deobfuscation."},{"page":81,"heading":"","anchor":"","text":"Shipping an application together with its dependency DLLs gives an attacker more surface, and those\nlibraries are usually not obfuscated at all. This example uses the Babel Obfuscator NuGet package to\nmerge a referenced assembly into the host, internalize its public types and obfuscate the\nresult, so you deliver a single self-contained file with no loose, readable libraries.\nTo use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center\neditions). The source code is available on GitHub:\ngit clone https://github.com/babelfornet/single-file-merge-nuget-example.git\nPaymentCore is an ordinary class library with a public API (src/PaymentCore/PaymentProcessor.cs)\nthat Checkout uses like any dependency:\n// PaymentCore (the dependency)\npublic sealed class PaymentProcessor\n{\n    public PaymentProcessor(decimal feeRate) => _feeRate = feeRate;\n    public decimal Charge(decimal amount) => amount + Math.Round(amount * _feeRate, 2);\n}\n\n// Checkout (the host)\nvar processor = new PaymentProcessor(feeRate: 0.029m);\nConsole.WriteLine(processor.Charge(100.00m));   // 102.90\nAfter the build, PaymentProcessor is an internal, renamed type inside Checkout.dll — there is no\nPaymentCore.dll to ship. The Checkout console project references the library and folds it in with\ntwo MSBuild properties in Release:"},{"page":81,"heading":"","anchor":"","text":"<ItemGroup>\n  <ProjectReference Include=\"..\\PaymentCore\\PaymentCore.csproj\" />\n</ItemGroup>\n\n<ItemGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <PackageReference Include=\"Babel.Obfuscator\" Version=\"12.0.0\">\n    <PrivateAssets>all</PrivateAssets>\n    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n  </PackageReference>\n</ItemGroup>\n\n<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <MergeAssemblies>true</MergeAssemblies>\n  <Internalize>true</Internalize>\n  <StringEncryption>hash</StringEncryption>\n  <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>\n</PropertyGroup>\nMergeAssemblies folds the referenced assemblies into the output, and Internalize changes the\nmerged public types to internal so they can be renamed and are no longer part of any public\nsurface. The Babel package runs the merge before the SDK's later\nsteps (dependency resolution, trimming, single-file bundling) and keeps dotnet publish consistent by\nupdating the .deps.json file and the set of published files.\nBuilding the sample in Release produces a single Checkout.dll — PaymentCore.dll is no longer\npresent because it was merged in — and the application runs from that one file with identical output.\nIf you would rather keep a dependency as an opaque encrypted blob than merge its types, use\nEmbedAssemblies instead."},{"page":82,"heading":"","anchor":"","text":"Strong protection does not come from a single trick — it comes from layers. This example turns on\nevery protection of the Babel Obfuscator NuGet package on one small assembly, so you can see the\ncomplete Ultimate configuration in a single project file and adapt it to your own application.\nTo use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center\neditions). The source code is available on GitHub:\ngit clone https://github.com/babelfornet/defense-in-depth-nuget-example.git\nThe application is a small feature gate (src/LicenseGate/FeatureGate.cs) that carries exactly the\nkinds of things every layer protects — strings, numeric weights, an array, and branching logic:\ninternal static class FeatureGate\n{\n    private static readonly int[]  Weights = { 3, 7, 11, 13, 17, 19, 23, 29, 31, 37 };\n    private static readonly string Pepper  = \"d3f3ns3-1n-d3pth-pepper\";\n\n    public static GateReport Evaluate(string edition, int tokens, double budget)\n    {\n        bool allowed = edition is \"PRO\" or \"ENTERPRISE\" && tokens > 0 && budget >= 100.0;\n        double score = 0.0;\n        for (int i = 0; i < Weights.Length; i++)\n            score += Weights[i] * (tokens + 1) * 0.5;\n        return new GateReport(edition, allowed, Math.Round(score / budget, 4), Digest(edition, tokens));\n    }\n    // Digest …\n}\nThe LicenseGate console project stacks the layers in Release:"},{"page":82,"heading":"","anchor":"","text":"<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <!-- Rename & restructure -->\n  <FlattenNamespaces>true</FlattenNamespaces>\n  <OverloadedRenaming>true</OverloadedRenaming>\n  <VirtualFunctions>true</VirtualFunctions>\n  <!-- Hide data -->\n  <StringEncryption>stream</StringEncryption>\n  <ValueEncryption>int32=true;int64=true;single=true;double=true;array=true;true</ValueEncryption>\n  <ResourceEncryption>true</ResourceEncryption>\n  <!-- Obscure logic -->\n  <ControlFlowObfuscation>if=true;switch=true;case=true;chain=true;true</ControlFlowObfuscation>\n  <ControlFlowIterations>3</ControlFlowIterations>\n  <DynamicProxy>external=true;true</DynamicProxy>\n  <!-- Detect & deter runtime attacks -->\n  <TamperingDetection>true</TamperingDetection>\n  <DebuggingProtection>true</DebuggingProtection>\n  <SuppressIldasm>true</SuppressIldasm>\n  <!-- Strip metadata -->\n  <CleanAttributes>true</CleanAttributes>\n  <SealClasses>true</SealClasses>\n  <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>\n</PropertyGroup>"},{"page":82,"heading":"","anchor":"","text":"Each property adds a layer: renaming and namespace flattening hide intent; String, Value and Resource\nencryption hide data; control flow and dynamic proxy hide logic; tampering detection and anti-debugging\ndeter runtime attacks; and metadata hygiene removes what the running application does not need. Because\nthe package is a build-only dependency (PrivateAssets=all), none of this leaks into the app's own\ndependency graph, and the SDK's later steps work on the already-protected assembly.\nBuilding the sample in Release applies all of the above with identical program output; open the result\nin a decompiler and compare it with the Debug build to see the difference. This mirrors the guidance in\nEnhancing Code Security — start from this configuration and drop\nthe layers you do not need."},{"page":83,"heading":"","anchor":"","text":"In this example project, we will utilize the Babel Obfuscator NuGet package to enable obfuscation in an Android application based on .NET 7. The Babel Obfuscator NuGet package can be easily integrated into a .NET project. It provides a convenient way to configure and apply obfuscation directly from Visual Studio or the command line.\nTo use this example project and follow the instructions provided, you need to have a site license for Babel Obfuscator (Ultimate, Server or Data Center editions). Additionally, the source code for the example project is available for download from the GitHub repository associated with the project.\ngit clone https://github.com/babelfornet/android-app-example.git\nThe example project \"AndroidApp\" is designed to demonstrate the obfuscation process of an Android application. The project contains the reference to the Babel Obfuscator NuGet package, which runs the obfuscation against the target assembly AndroidApp.dll during the build process.\nIn addition to using the Babel Obfuscator NuGet package to set up obfuscation in the AndroidApp project, some additional configuration has been added to the project file (AndroidApp.csproj) to enable other types of obfuscations."},{"page":83,"heading":"","anchor":"","text":"<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <TargetFramework>net7.0-android</TargetFramework>\n    <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>\n    <OutputType>Exe</OutputType>\n    <Nullable>enable</Nullable>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <ApplicationId>com.companyname.AndroidApp</ApplicationId>\n    <ApplicationVersion>1</ApplicationVersion>\n    <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Babel.Obfuscator\" Version=\"10.0.0\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n  \n  <PropertyGroup>\n    <Use>tagassembly=true</Use>\n    <StringEncryption>true</StringEncryption>\n    <ControlFlowObfuscation>goto=on;if=on;switch=on;case=on;call=on;true</ControlFlowObfuscation>\n    <DynamicProxy>all</DynamicProxy>\n    <ResourceEncryption>true</ResourceEncryption>\n    <VerboseLevel>3</VerboseLevel>\n    <XmlRules>\n      <Rules>\n        <Rule name=\"rule1\" feature=\"renaming\" exclude=\"false\">\n          <Pattern>*</Pattern>\n        </Rule>\n\t</Rules>\n    </XmlRules>\n  </PropertyGroup>\n</Project>"},{"page":83,"heading":"","anchor":"","text":"For example, the project file includes settings for string encryption, which obfuscates string literals in the application's code to make it harder for attackers to reverse-engineer the app. Additionally, the configuration sets up a custom rule for renaming all public types, which increases the number of renamed types.\nOnce the app starts, it shows all the types inside the obfuscated assembly in the main view.\nAndroid App Emulator\nThe view displays that most of the types have been renamed by Babel, showing that we are running the obfuscated application.\nThis example project demonstrates integrating the Babel Obfuscator NuGet package into an Android application and customising its obfuscation settings to achieve specific results. Through this example, users can gain insights into how Babel Obfuscator can help protect their Android applications by renaming types and methods, removing metadata, encrypting strings and adding control flow obfuscation to their code, enhancing the overall application security."},{"page":84,"heading":"","anchor":"","text":"Continuous Integration (CI) and Build Server are important components of modern software development and deployment. They are used to automate the process of building, testing, and deploying software.\nThe examples in this section primarily address the most commonly used build servers. However, it's crucial to note that build server integration is exclusively available with the Babel Obfuscator Ultimate edition. This functionality is essential for companies aiming to streamline their build processes. By leveraging NuGet and MSBuild, the principles outlined here can be applied to virtually any build system, ensuring that obfuscation is executed consistently and correctly with each build.\nIn addition to continuous integration and Build Servers, Babel Obfuscator provides support for testing the obfuscated assemblies using unit tests. This is an important step in ensuring the quality and functionality of the obfuscated code. By executing the unit tests against the obfuscated assembly, you can verify that the obfuscation process has not altered the code's behaviour.\nAzure DevOps\nGitHub Actions\nAppVeyor\nUnit Tests"},{"page":85,"heading":"","anchor":"","text":"Run Babel Obfuscator on Azure Pipelines by referencing the Babel Obfuscator\nNuGet package from a private Azure Artifacts feed, with the license supplied\nas a secret variable.\nAzure Pipelines builds the project with the .NET SDK, and the Babel.Obfuscator package inserts the Babel task into that build. Nothing on the agent needs Babel installed: the package carries the build tools, and the pipeline only has to authenticate to the feed that hosts it and hand Babel a license.\nThe sample used on this page is a small console application:\ngit clone https://github.com/babelfornet/devops-integration.git"},{"page":85,"heading":"Host the Package on an Azure Artifacts Feed","anchor":"host-the-package-on-an-azure-artifacts-feed","text":"The Babel.Obfuscator package is not published on nuget.org — you receive it with the Ultimate edition or with a Babel Licensing site edition. Push it to a private feed that only your organisation can read.\nWarning: Never push the Babel Obfuscator package to a public feed. The package contains the Babel build tools, and republishing it breaks the terms of your license.\nIn Azure DevOps open Artifacts, create a feed named Babel, then push the package to it:\ndotnet nuget push Babel.Obfuscator.12.0.0.nupkg \\\n  --source \"https://pkgs.dev.azure.com/ORGANISATION/_packaging/Babel/nuget/v3/index.json\" \\\n  --api-key az\nAdd a NuGet.config next to the solution so both your machine and the build agent resolve the package from that feed:\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <clear />\n    <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n    <add key=\"babel\" value=\"https://pkgs.dev.azure.com/ORGANISATION/_packaging/Babel/nuget/v3/index.json\" />\n  </packageSources>\n</configuration>\nCredentials are deliberately absent from this file. On a developer machine the Azure Artifacts Credential Provider prompts for them once; in the pipeline the NuGetAuthenticate task supplies the build identity's token. Neither writes a secret into the repository."},{"page":85,"heading":"Reference the Package","anchor":"reference-the-package","text":"Add the package reference to every project whose assembly you want obfuscated:\n<ItemGroup>\n  <PackageReference Include=\"Babel.Obfuscator\" Version=\"12.0.0\">\n    <PrivateAssets>all</PrivateAssets>\n    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n  </PackageReference>\n</ItemGroup>\nPrivateAssets keeps the reference out of the packages your project produces: Babel is a build-time tool, not a dependency of the shipped assembly."},{"page":85,"heading":"Supply the License as a Secret","anchor":"supply-the-license-as-a-secret","text":"Babel needs a license to produce a permanently working assembly; without one it runs in evaluation mode and the output stops working after a short period.\nError: Do not commit babel.licenses to the repository. A license file in a repository is readable by everyone who can read the repository, and by everyone who forks it — including after you delete the file, because the blob stays reachable in the fork and in the original repository's history.\nStore the license key as a secret variable instead. In the pipeline, under Variables, add BabelLicense and mark it secret. Then map it to an environment variable in the build step and read it from the project:\n<PropertyGroup Condition=\"'$(BABEL_LICENSE)' != ''\">\n  <BabelLicense>$(BABEL_LICENSE)</BabelLicense>\n</PropertyGroup>\nThe BabelLicense property accepts a license file path, a license key, or a floating license user key written as floating:<user key>. On a build agent the last two are the ones to use, because neither needs a file on disk. Locally, the property is left unset and Babel picks up the babel.licenses file from the project folder or a parent folder, so developers keep working without any pipeline configuration. See Package Setup."},{"page":85,"heading":"The Pipeline","anchor":"the-pipeline","text":"trigger:\n  - main\n\npool:\n  vmImage: ubuntu-latest\n\nvariables:\n  buildConfiguration: Release\n\nsteps:\n  - task: UseDotNet@2\n    displayName: Install the .NET SDK\n    inputs:\n      version: 10.0.x\n\n  - task: NuGetAuthenticate@1\n    displayName: Authenticate to the Babel feed\n\n  - script: dotnet restore DevOpsIntegration.sln\n    displayName: Restore\n\n  - script: dotnet build DevOpsIntegration.sln --configuration $(buildConfiguration) --no-restore\n    displayName: Build and obfuscate\n    env:\n      BABEL_LICENSE: $(BabelLicense)\n\n  - task: PublishPipelineArtifact@1\n    displayName: Publish the obfuscated output\n    inputs:\n      targetPath: DevOpsIntegration/bin/$(buildConfiguration)/net10.0\n      artifact: DevOpsIntegration\nTwo details are worth pointing out.\nNuGetAuthenticate@1 is what makes the private feed reachable. It configures the credential provider with the pipeline's own identity, so the NuGet.config above needs no packageSourceCredentials section and no token of yours.\nSecret variables are not passed to scripts automatically — that is the point of marking them secret. The env: block on the build step is what maps BabelLicense into the process, and it is the only place the key appears.\nObfuscation runs as part of dotnet build; there is no separate Babel step. The Babel log appears in the build output, and a licensing or configuration error fails the step."},{"page":85,"heading":"The Pipeline","anchor":"the-pipeline","text":"Info: The agent image only has to run the .NET SDK. ubuntu-latest is the cheapest choice and works for any target runtime, because Babel operates on IL: a Linux agent can obfuscate assemblies destined for Windows. Use windows-latest when the build itself needs Windows — .NET Framework targets, WPF, or Windows Forms."},{"page":85,"heading":"Configure the Obfuscation","anchor":"configure-the-obfuscation","text":"Babel is configured with MSBuild properties in the project file. A common arrangement is to leave Debug builds untouched, so local debugging behaves normally, and protect Release builds:\n<PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\n  <BabelEnabled>false</BabelEnabled>\n</PropertyGroup>\n\n<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <StringEncryption>stream</StringEncryption>\n  <ControlFlowObfuscation>if=on;goto=on;switch=on;case=on;call=on</ControlFlowObfuscation>\n  <ControlFlowIterations>3</ControlFlowIterations>\n  <ResourceEncryption>true</ResourceEncryption>\n</PropertyGroup>\nEvery property is listed in Package Reference, and Configuring Obfuscation explains how they map to Babel features.\nFor anything finer than a whole-assembly switch, add a rules file. The rule below keeps control flow obfuscation off short methods, where flattening costs more than it hides:\n<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<Rules>\n  <Rule name=\"reduce control flow\" feature=\"control flow\" exclude=\"false\" applyToMembers=\"true\">\n    <Target>Classes,Structures</Target>\n    <Pattern>*</Pattern>\n    <Properties>\n      <MaxSwitchTargets>5</MaxSwitchTargets>\n      <MinInstructionCount>18</MinInstructionCount>\n      <UseValueEncryption>false</UseValueEncryption>\n    </Properties>\n    <Description>Do not scramble methods with few instructions.</Description>\n  </Rule>\n</Rules>\nPoint the build at it with the BabelRules property:"},{"page":85,"heading":"Configure the Obfuscation","anchor":"configure-the-obfuscation","text":"<PropertyGroup>\n  <BabelRules>$(MSBuildThisFileDirectory)babelRules.xml</BabelRules>\n</PropertyGroup>"},{"page":85,"heading":"Verifying the Result","anchor":"verifying-the-result","text":"Download the pipeline artifact and check that the assembly really is obfuscated, rather than assuming it. The Detecting Babel Obfuscation example shows how to test this automatically, which is worth adding to the pipeline as a gate: a misconfigured license or a skipped build step otherwise ships a plain assembly without failing anything.\nKeep the map file produced by the build if you intend to decode stack traces coming back from production. See Decoding Stack Traces."},{"page":86,"heading":"","anchor":"","text":"GitHub Actions provides a convenient way to automate the obfuscation process for your code by allowing you to specify obfuscation tasks as part of your build and deployment pipeline.\nThis example features a basic WebApi application that showcases how to integrate Babel Obfuscator with GitHub Actions seamlessly. The purpose of this integration is to demonstrate how easily Babel Obfuscator can be added to your project using the NuGet package and how to access the license file through GitHub secrets securely.\nIn addition, this example provides valuable insights on how to configure NuGet to directly access the GitHub package store and install the Babel Obfuscator NuGet package dependency in your project. By following the step-by-step instructions, you can easily implement Babel Obfuscator in your project and benefit from its powerful obfuscation capabilities.\nTo help you get started, the sample source code is readily available on our GitHub repository, allowing you to explore the integration process in greater detail.\ngit clone https://github.com/babelfornet/webapi-actions-example.git\nIntegrating Babel Obfuscator with GitHub Actions requires adding a reference to the Babel Obfuscator NuGet package in your project. This package enables Babel Obfuscator to become part of your build process and obfuscate the target assembly. The package can be downloaded and installed directly from the private GitHub NuGet feed."},{"page":86,"heading":"","anchor":"","text":"To set up the Babel Obfuscator NuGet package in the GitHub package store, you'll need to create an access token with enough privileges to publish, install, and delete NuGet packages from the GitHub package store (see GitHub documentation). You can then use the dotnet CLI tool to push the Babel Obfuscator NuGet package.\ndotnet nuget push .\\Babel.Obfuscator.nupkg --api-key TOKEN --source https://nuget.pkg.github.com/USERNAME/index.json\nIn the above command:\nTOKEN is your personal access token with enough privileges to publish packages.\nUSERNAME with the name of your personal account on GitHub.\nTo install the Babel Obfuscator NuGet package from the GitHub package store, add the following XML configuration file to your project:\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <add key=\"nuget\" value=\"https://www.nuget.org/api/v2\" />\n    <add key=\"github\" value=\"https://nuget.pkg.github.com/USERNAME/index.json\" />\n  </packageSources>\n  <activePackageSource>\n    <add key=\"All\" value=\"(Aggregate source)\" />\n  </activePackageSource>\n  <packageSourceCredentials>\n    <github>\n      <add key=\"Username\" value=\"babelfornet\" />\n      <add key=\"ClearTextPassword\" value=\"%PACKAGES_TOKEN%\" />\n    </github>\n  </packageSourceCredentials>\n</configuration>\nIn the XML configuration file above:\nPACKAGES_TOKEN is the environment variable containing your personal access token with privileges to read from the store\nUSERNAME with the name of your personal account on GitHub."},{"page":86,"heading":"","anchor":"","text":"Once you've installed the Babel Obfuscator NuGet package, you can configure GitHub Actions to use it in your continuous integration (CI) workflow. This can be achieved by creating a YAML file in your repository that defines your workflow. The YAML file specifies the steps that will be executed during the CI process, including the build step.\nHere's an example YAML file:\nname: dotnet package\n\non: [push]\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        dotnet-version: [ '8.0.x' ]\n\n    steps:\n      - uses: actions/checkout@v3\n      - name: Setup .NET Core SDK ${{ matrix.dotnet-version }}\n        uses: actions/setup-dotnet@v3\n        with:\n          dotnet-version: ${{ matrix.dotnet-version }}\n      - name: Install dependencies\n        run: dotnet restore\n        env:\n          PACKAGES_TOKEN: ${{ secrets.PACKAGES_TOKEN }}        \n      - name: Build\n        run: dotnet build --configuration Release --no-restore\n        env:\n          BABEL_LICENSE: ${{ secrets.BABEL_LICENSE_SECRET }}\nIn addition to the package reference, you will also need to set the BABEL_LICENSE environment variable to the path of your license file in your CI workflow. You can do this by adding the following line to your workflow file under the envsection:\nBABEL_LICENSE: ${{ secrets.BABEL_LICENSE_SECRET }}"},{"page":86,"heading":"","anchor":"","text":"Where the secret BABEL_LICENSE_SECRET contains the license key, which is passed to Babel Obfuscator during the build process by setting the following property in the project file.\n<PropertyGroup>\n  <BabelLicense>$(BABEL_LICENSE)</BabelLicense>\n</PropertyGroup>\nYou can create the BABEL_LICENSE_SECRET in the GitHub repository settings, under Security > Secrets and variables > Actions.\nUpdate the BABEL_LICENSE_SECRET variable to store the received license type.\nFloating License\nSet the BABEL_LICENSE_SECRET to the floating license key as follow:\nBABEL_LICENSE_SECRET=floating:UAZK7-GTO0E-98KR1-CKPUJ\nFile License\nSet the BABEL_LICENSE_SECRET to the path of the license file, for example:\nBABEL_LICENSE_SECRET=./Babel/babel.licenses\nOverall, this example demonstrates how to integrate Babel Obfuscator with GitHub Actions and highlights the importance of securing access to sensitive information such as license keys."},{"page":87,"heading":"","anchor":"","text":"Obfuscate on AppVeyor by hosting the Babel Obfuscator NuGet package on your\nAppVeyor account feed and passing the license through a secure variable.\nAppVeyor builds the solution with the .NET SDK, and the Babel.Obfuscator package adds the Babel task to that build. As with any other build server, the work is limited to two things: letting the agent reach the private feed that holds the package, and giving Babel a license without writing it into the repository.\nThe sample used on this page is a small console application:\ngit clone https://github.com/babelfornet/appveyor-integration.git"},{"page":87,"heading":"Upload the Package to the AppVeyor Feed","anchor":"upload-the-package-to-the-appveyor-feed","text":"Every AppVeyor account has its own NuGet feed. From Account Settings → NuGet, copy the feed URL and the API key, then push the package:\ndotnet nuget push Babel.Obfuscator.12.0.0.nupkg \\\n  --api-key APPVEYOR_API_KEY \\\n  --source https://ci.appveyor.com/nuget/ACCOUNT/api/v2/package\nWarning: The account feed is private, but it is the only thing standing between the package and the internet. Never push Babel.Obfuscator to nuget.org or to any feed outside your organisation.\nRegister the same feed as a package source so the solution restores identically on a developer machine and on the build agent:\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <clear />\n    <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n    <add key=\"appveyor\" value=\"https://ci.appveyor.com/nuget/ACCOUNT/api/v2\" />\n  </packageSources>\n</configuration>\nError: Do not put the feed credentials in this file, and do not pass them on a nuget sources add command line in appveyor.yml. Both end up committed, and a password in a public repository is a password that has been read. Use AppVeyor's encrypted variables, as below.\nEncrypt the feed password with Account Settings → Encrypt YAML, then reference the encrypted value from the build configuration. AppVeyor decrypts it only for builds of your own repository, and never for pull requests from forks."},{"page":87,"heading":"Reference the Package","anchor":"reference-the-package","text":"<ItemGroup>\n  <PackageReference Include=\"Babel.Obfuscator\" Version=\"12.0.0\">\n    <PrivateAssets>all</PrivateAssets>\n    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n  </PackageReference>\n</ItemGroup>\nReferencing the package is all it takes: the Babel task is injected into the build and obfuscates the project's output assembly. Building locally already produces obfuscated output, and the Babel log appears in the build output — which is the right moment to check the configuration, before involving the build server at all."},{"page":87,"heading":"Supply the License","anchor":"supply-the-license","text":"Add the license key as a secure variable in Settings → Environment, named BABEL_LICENSE, then read it from the project file:\n<PropertyGroup Condition=\"'$(BABEL_LICENSE)' != ''\">\n  <BabelLicense>$(BABEL_LICENSE)</BabelLicense>\n</PropertyGroup>\nThe condition keeps developer machines working unchanged: with the variable unset, Babel falls back to the babel.licenses file found in the project folder or a parent folder. BabelLicense also accepts a floating license user key written as floating:<user key>, which is the better choice when several build agents share one license. See Package Setup.\nError: Adding babel.licenses to the repository, as older guides suggested, exposes the license to anyone who can read or fork it. Deleting the file later does not undo the exposure: the blob remains reachable in every fork and in the repository's own history."},{"page":87,"heading":"The Build Configuration","anchor":"the-build-configuration","text":"appveyor.yml at the root of the repository replaces whatever is configured in the AppVeyor UI:\nversion: '1.0.{build}'\nimage: Visual Studio 2022\n\nbranches:\n  only:\n    - main\n\nconfiguration: Release\n\nenvironment:\n  feed_user: ACCOUNT\n  feed_password:\n    secure: <paste the value produced by Encrypt YAML>\n\ninstall:\n  - ps: dotnet nuget update source appveyor --username $env:feed_user --password $env:feed_password --store-password-in-clear-text\n\nbefore_build:\n  - ps: dotnet restore AppVeyorIntegration.sln\n\nbuild_script:\n  - ps: dotnet build AppVeyorIntegration.sln --configuration $env:CONFIGURATION --no-restore\n\nartifacts:\n  - path: AppVeyorIntegration\\bin\\$(configuration)\\net10.0\n    name: Build_$(configuration)_$(appveyor_build_version)\n    type: zip\nThe Visual Studio 2022 image ships current .NET SDKs; add a dotnet-install step only if you need an SDK the image does not carry. Obfuscation happens inside dotnet build, so there is no Babel step to add and a licensing failure fails the build.\nThe artifacts block collects the build output into a zip published on the Artifacts tab, so you can download the obfuscated assembly and inspect it.\nInfo: --store-password-in-clear-text writes the feed password into the agent's NuGet.config. That is acceptable on a disposable build VM, which is destroyed when the build ends, but it is the reason this command must never be run on a developer machine."},{"page":87,"heading":"Configure the Obfuscation","anchor":"configure-the-obfuscation","text":"Babel settings are MSBuild properties, applied per configuration so that debugging stays untouched:\n<PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\n  <BabelEnabled>false</BabelEnabled>\n</PropertyGroup>\n\n<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <StringEncryption>stream</StringEncryption>\n  <ControlFlowObfuscation>if=on;goto=on;switch=on;case=on;call=on</ControlFlowObfuscation>\n  <ControlFlowIterations>3</ControlFlowIterations>\n</PropertyGroup>\nThe full set is in Package Reference; Configuring Obfuscation covers what each one does. When a whole-assembly setting is too blunt, an obfuscation rules file narrows it down to the types and members that matter."},{"page":87,"heading":"Verifying the Result","anchor":"verifying-the-result","text":"Download the artifact and confirm the assembly is obfuscated instead of assuming it — the Detecting Babel Obfuscation example automates that check, and running it in the build turns a silently unobfuscated release into a failed build."},{"page":88,"heading":"","anchor":"","text":"When using Babel Obfuscator, it is possible to maintain unit tests even after obfuscating the code. This is achieved by configuring Babel Obfuscator to apply obfuscation to the code and run the unit tests against the obfuscated code. This setup requires using an XML mapping file, which helps to resolve issues that may arise from the access of internal classes consumed by the unit tests. This way, you can ensure that the unit tests continue to provide reliable and accurate results even after the code has been obfuscated. This helps maintain the code's quality and ensures that it continues to function as intended after obfuscation.\nTo effectively run unit tests against obfuscated code, it is necessary to use an XML mapping file with Babel Obfuscator. The XML mapping file helps Babel Obfuscator keep track of the names of your classes, methods, and variables in your target assembly and ensure that they remain consistent even after obfuscation. This is important because unit tests often depend on the internal structure of your code and may use references to specific classes, methods, or variables. If these references are changed during obfuscation, the unit tests will no longer be able to access the necessary elements making the tests fail."},{"page":88,"heading":"","anchor":"","text":"To overcome this issue, Babel Obfuscator generates an XML mapping file for the target assembly that records the original names of your classes, methods, and variables before obfuscation. During the obfuscation process, Babel Obfuscator updates the names in the mapping file to match the obfuscated names. The unit tests can then be processed using Babel Obfuscator and the generated mapping file to access the correct obfuscated names, allowing them to run correctly against the obfuscated code."},{"page":88,"heading":"Configure Babel for Unit Tests","anchor":"configure-babel-for-unit-tests","text":"In order to use Babel Obfuscator with your unit tests, you need to take the following steps:\nReference the NuGet package\nAdd a reference to the Babel Obfuscator NuGet package in the unit test project.\nLoad the XML mapping file\nModify the project by adding MSBuild instructions allowing Babel to load the XML mapping file generated for the target assembly.\nDisable renaming\nThe unit test project does not need renaming, so disable it.\n  <PropertyGroup>\n    <ObfuscateTypes>false</ObfuscateTypes>\n    <ObfuscateProperties>false</ObfuscateProperties>\n    <ObfuscateMethods>false</ObfuscateMethods>\n    <ObfuscateParameters>false</ObfuscateParameters>\n    <ObfuscateFields>false</ObfuscateFields>\n    <ObfuscateEvents>false</ObfuscateEvents>    \n  </PropertyGroup>\n  <ItemGroup>\n    <MapInFile Include=\"$(SolutionDir)/MapOut/ClassLibrary.dll.map.xml\" />\n  </ItemGroup>\nWhere ClassLibrary.dll.map.xml is the XML map file generated for the target assembly we are testing.\nDoing this allows you to run your unit tests against the obfuscated code and use the XML mapping file to resolve any issues with references to obfuscated names consumed by the unit test code. This setup will ensure that your unit tests continue to work even after obfuscation is applied to your code."},{"page":88,"heading":"Run the Sample Project","anchor":"run-the-sample-project","text":"You can download the sample project here. To run the sample project, please follow the instructions below:\nExtract the archive\nExtract the UnitTest.zip file into a folder on your computer.\nCopy the license file\nCopy your license file to the extracted folder.\nOpen a terminal\nOpen a command prompt or terminal window and navigate to the folder where you extracted the files.\nRun the tests\nEnter the command \"dotnet test\" to run the sample project.\nUnit Test Output"},{"page":89,"heading":"","anchor":"","text":"Code encryption is a powerful feature of obfuscation tools that allows developers to protect their application code from being reverse-engineered by hackers or competitors. With code encryption, the code is transformed in such a way that it can only be decrypted and executed by the application at runtime. This makes it much more difficult for an attacker to analyze and understand the code, as they cannot simply decompile it into its original source form.\nCode encryption can be used with Babel Licensing to protect the code that implements the licensed features, ensuring they cannot be accessed or executed without a valid license file. By encrypting the code, the license file can contain a password or key that is used to decrypt and execute the protected code when the licensed feature is accessed.\nThis means that even if an unauthorized user gains access to the protected code, they will not be able to execute it without the correct password or key, which is only available through a valid license file. Additionally, code encryption can help prevent reverse engineering and tampering with the code, further enhancing the security of the licensed features.\nWhen used in combination with other license management techniques, such as license keys or activation codes, code encryption can provide a robust and secure licensing solution for software applications with feature-based licensing models."},{"page":89,"heading":"","anchor":"","text":"These examples show Code Encryption on its own and combined with Babel Licensing. Each has a public GitHub repository you can clone and build.\nProtecting an Algorithm with Code Encryption — the simplest setup: one MSBuild property, runs standalone with no runtime license.\nFeature Based Licenses — unlock encrypted feature code from a license, per edition.\nLicense-Bound Code Encryption — the decryption password lives inside a signed, hardware-locked license, not in the binary.\nFeature as an External Encrypted File — deliver a premium feature as a separate, license-gated .eil file.\nSubscription License with Encrypted Pro Code — a time-limited license with grace period gating encrypted pro code.\nSee also the Code Encryption knowledge base article."},{"page":90,"heading":"","anchor":"","text":"A proprietary algorithm is often the most valuable thing in an assembly — and the easiest to lift\nstraight out of a decompiler. This example uses the Babel Obfuscator NuGet package to apply MSIL\nCode Encryption to a scoring engine with a single MSBuild property. It is the simplest\ncode-encryption setup: no Babel Licensing and no runtime license, because the default code\nencryption embeds the key in the binary and the protected application runs on its own.\nTo use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center\neditions). The source code is available on GitHub:\ngit clone https://github.com/babelfornet/code-encryption-nuget-example.git\nThe protected code is a proprietary scoring algorithm (src/AlgorithmApp/ScoringEngine.cs) — the\nkind of intellectual property you do not want a competitor to lift out of a decompiler:\ninternal static class ScoringEngine\n{\n    public static int Score(int recency, int frequency, int monetary)\n    {\n        int r = Bucket(recency, 3, 12, 30);\n        int f = Bucket(frequency, 2, 5, 12);\n        int m = Bucket(monetary, 50, 250, 1000);\n        return Normalize(r * 25 + f * 17 + m * 11);   // vendor's secret weighting\n    }\n    // Bucket / Normalize …\n}\nAfter encryption, the bodies of Score, Bucket and Normalize are gone from the IL and are\nreconstructed only by the Babel Virtual Machine at runtime. The AlgorithmApp console project\nencrypts the sensitive type in Release:"},{"page":90,"heading":"","anchor":"","text":"<ItemGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <PackageReference Include=\"Babel.Obfuscator\" Version=\"12.0.0\">\n    <PrivateAssets>all</PrivateAssets>\n    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n  </PackageReference>\n</ItemGroup>\n\n<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <MsilEncryption>AlgorithmApp\\.ScoringEngine::.*</MsilEncryption>\n  <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>\n</PropertyGroup>\nMsilEncryption is a regular expression selecting which methods to encrypt — here every method on\nthe ScoringEngine type. Babel rewrites those method bodies into custom encrypted instructions that\nonly the Babel Virtual Machine can execute. This is the default\n(no-<Source>) code encryption, so a Babel license is only required at build time; the protected\napplication runs standalone.\nBuilding the sample in Release encrypts the three scoring methods with identical program output, and\nthe algorithm's IL is no longer present in the assembly. To make the encrypted code unlock only with\na valid license — so removing the license check is not enough — see the licensing examples below."},{"page":91,"heading":"","anchor":"","text":"Babel Obfuscator includes a licensing feature that allows you to generate feature-based licenses for your obfuscated code. This means that you can create licenses that unlock specific features or functionality within your application based on the license key that is provided.\nOne way to implement this is by using code encryption in combination with Babel Licensing. You can use Babel Obfuscator to encrypt your code and then generate a license key that unlocks specific encrypted sections of the code. This way, you can provide different license levels or feature sets based on the user's needs.\nFor example, suppose you have an application with three levels of functionality: Standard, Professional and Enterprise. You can use Babel Obfuscator to encrypt the Enterprise features of the application and then generate a license key that unlocks those features. You can then provide different license keys to users based on their subscription level, with each key unlocking the appropriate set of features.\nTo implement this, you would use Babel Licensing to generate the license keys and verify them at runtime. When the user enters a license key, your application uses Babel Licensing to validate the key and determine which features should be unlocked. The encrypted sections of the code would then be decrypted and made available to the user.\nThe source code of the example that demonstrates feature-based licensing with code encryption is available on GitHub"},{"page":91,"heading":"","anchor":"","text":"git clone https://github.com/babelfornet/license-features-example.git\nThe example references the Babel Licensing NuGet package to use its features. The example code will include an implementation of the LicenseManager class, which provides methods for checking the validity of a license and the presence of specific features."},{"page":91,"heading":"","anchor":"","text":"public ILicense ValidateLicense()\n{\n   // To validate the license, only the public key is required.\n   // The private key is only used to sign the license, and in production the private key\n   // should not be distributed with the application.\n   // The public key should be distributed with the application and used to validate the license.\n\n   // The following signature provider can be used to create and validate the license\n   // as includes both the private key and the public key.\n   var signature = CreateSignature();\n\n   // The public key string can be embedded into the application and used to create a signature\n   // provider used only to validate the license.\n   string publicKey = signature.ExportKeys(publicKeyOnly: true);\n\n   // To create the RSASignature from the public key use the following code\n   var validatingSignature = RSASignature.FromKeys(publicKey);\n\n   // And assign the validating signature provider to the license manager\n   var licenseManager = new XmlLicenseManager();\n   licenseManager.SignatureProvider = validatingSignature;\n\n   license = licenseManager.Validate(File.ReadAllText(LicenseFileName), typeof(LicenseManager), this);\n   return license;\n}\nThe example will also include the code to generate an XML license file that specifies the license information, such as the expiration date, licensed features, and product information."},{"page":91,"heading":"","anchor":"","text":"Warning: Note that the code made available in the example to generate the license is only for demonstration purposes and must not be included in production.\nCode encryption can be used to protect the code that makes up the features of a software application from being used without the proper license file. This can be achieved by encrypting the code that implements a particular feature and requiring a password to decrypt and execute the code.\n[Obfuscation(Feature = \"msil encryption:internal=true;source=feature1;cache=false;password=aR&tj4i7u@\", Exclude = false)]\ninternal class Feature1\n{\n   public Feature1() { }\n\n   public string DoTask()\n   {\n      return \"Feature1: \" + Add(7, 8);\n   }\n\n   public int Add(int a, int b) => a + b;\n}\nThe password can be obtained from a license file that is generated based on the features that the user has licensed.\nBabel Obfuscator uses the Obfuscation attribute to mark the code that makes up the feature to be protected and specifies the method that should be called at runtime to retrieve the password needed to decrypt and execute the protected code. This method is typically a small function that retrieves the password from a license file or a licensing server. The password is then used by Babel Obfuscator to decrypt the protected code during runtime, ensuring that only licensed users can access the feature."},{"page":91,"heading":"","anchor":"","text":"[Obfuscation(Feature = \"msil encryption get password\")]\ninternal static string GetSourcePassword(string source)\n{\n   var lm = LicenseManager.Instance;\n\n   var feature = lm.License.Features.FirstOrDefault(item => item.Name == source);\n   if (feature == null)\n      throw new ApplicationException(source + \" not found\");\n\n   return Encoding.UTF8.GetString(feature.Data);\n}\nOnce the example is compiled, open the obfuscation project obfuscate.babel in Babel Desktop and run it to protect the application features with Code Encryption.\nYou can start the protected application and generate a license for the three different application editions provided: Standard, Professional and Enterprise. Each edition unlocks an incremental number of features, meaning that the higher the edition you license, the more features you will be able to use within the application. So, generating a license for the Enterprise edition will unlock all the features, while generating a license for the Standard edition will only unlock a subset of the features.\nLicensed Features\nThe LicenseManager class will check for a valid license and the presence of the requested features. If the license is valid and the features are enabled, the application will allow the user to access those features.\nOverall, using code encryption with Babel Licensing can provide a powerful way to create flexible and feature-rich applications while still protecting your code from reverse engineering and piracy."},{"page":92,"heading":"","anchor":"","text":"This example makes a protected feature cryptographically dependent on a valid license by\ncombining two Babel technologies: MSIL Code Encryption encrypts the body of a sensitive method,\nand Babel Licensing stores the decryption password — itself encrypted — inside a signed,\nhardware-locked license. The Babel Virtual Machine asks the application for the password through a\nget password hook, which returns it only after the license validates. Removing or bypassing the\nlicense check is not enough: without a valid license there is no password, and without the password\nthe encrypted code cannot run.\nTo use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center\neditions) and Babel Licensing. The source code is available on GitHub:\ngit clone https://github.com/babelfornet/license-bound-encryption-console-example.git\nThe sensitive method is marked so Babel keeps the encrypted body inside the assembly and asks for its\npassword at runtime:\n[Obfuscation(Feature = \"msil encryption:internal=true;source=core;password=...\")]\npublic static int Compute(int a, int b) { /* protected body */ }\n\n[Obfuscation(Feature = \"msil encryption get password\")]\ninternal static string GetSourcePassword(string source)\n{\n    // Validate the license and return the password only when it is valid.\n}"},{"page":92,"heading":"","anchor":"","text":"The code password never appears in clear in the shipped binary. It is written (encrypted with a\nvendor secret) into a license field, and recovered at runtime only from a validly signed license\nbound to the current machine. A companion LicenseGenerator project mints the license.\nValid license      ->  Compute(7, 5) = 147   (the encrypted method runs)\nMissing / tampered ->  Protected computation blocked (the BVM cannot decrypt the method)\nThis is the pattern behind Babel's own feature gating; see\nLicense-Bound Code Encryption in the\nCode Encryption manual for the full explanation, and\nFeature Based Licenses for a\nmulti-feature variant."},{"page":93,"heading":"","anchor":"","text":"This example delivers a premium feature as encrypted code that ships separately from the\napplication, unlocked only when the customer also has a license that grants it. Babel Obfuscator can\nstrip the encrypted body of a method into an external .eil file instead of embedding it. At runtime\nthe Babel Virtual Machine asks the application for that file (get stream) and for its password\n(get password). This example gates both hooks on a valid Babel Licensing license, so unlocking\nthe premium feature requires two things at once: the premium.eil file deployed next to the app, and\na signed, hardware-locked license that grants the feature.\nTo use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center\neditions) and Babel Licensing. The source code is available on GitHub:\ngit clone https://github.com/babelfornet/external-encrypted-code-console-example.git\nBecause the feature source is set but internal is not, Babel emits the encrypted body to\npremium.eil instead of embedding it:\n[Obfuscation(Feature = \"msil encryption:source=premium;password=...\")]   // no internal -> external .eil\npublic string Analyze(string data) { /* premium body, stripped to premium.eil */ }\n\n[Obfuscation(Feature = \"msil encryption get stream\")]     // returns the premium.eil stream (license-gated)\n[Obfuscation(Feature = \"msil encryption get password\")]   // returns the password       (license-gated)"},{"page":93,"heading":"","anchor":"","text":"The project copies premium.eil from the build's intermediate folder to the output with a small\nAfterTargets=\"Build\" MSBuild target, so it can be deployed — or deliberately withheld to sell the\nfeature separately.\nStandard license, no premium.eil   ->  Premium blocked\nPremium license, no premium.eil    ->  Premium blocked (feature not delivered)\nStandard license, premium.eil      ->  Premium blocked (not licensed)\nPremium license  + premium.eil     ->  Premium analysis runs\nSee External Code Files in the Code Encryption\nmanual for more on the .eil mechanism."},{"page":94,"heading":"","anchor":"","text":"This example shows a time-limited (subscription) license with a grace period, where the\nsubscription-only functionality is protected with Babel Obfuscator MSIL Code Encryption. The pro\ncode can only run while the subscription — including its grace window — is valid, because the Babel\nVirtual Machine gets the decryption password from the license itself. Once the subscription lapses\npast the grace period the license no longer validates, so the encrypted pro code stops running.\nTo use this example you need a site license for Babel Obfuscator (Ultimate, Server or Data Center\neditions) and Babel Licensing. The source code is available on GitHub:\ngit clone https://github.com/babelfornet/subscription-license-console-example.git\nThe license carries two dates: an engine-enforced ExpireDate set to the end of the grace period\n(the hard cutoff), and a soft subscription-end field marking when renewal is due. Between those\ntwo dates the app keeps working but reminds the user to renew; after the hard cutoff the license no\nlonger validates and the encrypted pro code is locked.\nActive            ->  Pro forecast runs\nGrace (lapsed)    ->  Pro forecast runs + \"please renew\" warning\nExpired (>grace)  ->  Pro forecast locked (BVM cannot decrypt it)\nThe pro method is encrypted and gets its password from the license through a get password hook:\n[Obfuscation(Feature = \"msil encryption:internal=true;source=pro;password=...\")]\npublic static double Forecast(double[] history) { /* protected body */ }"},{"page":94,"heading":"","anchor":"","text":"A companion LicenseGenerator project mints subscription licenses (--days, --grace, --expired)\nso you can try each state. Because the protection is cryptographic, extending the subscription by\npatching a date check does not help — without a valid license there is no password, and the pro code\ncannot be decrypted."},{"page":95,"heading":"","anchor":"","text":"Cross-assembly renaming is an obfuscation technique used to increase the level of security in applications by renaming the public interface of the referenced assemblies. This technique is particularly useful when an application uses multiple assemblies, and some of those assemblies are third-party libraries that are publicly available. By renaming the public interface of the referenced assemblies, it becomes more difficult for an attacker to understand the code and reverse-engineer it.\nThis section provides practical examples that demonstrate how to set up and configure cross-assembly renaming with Babel Obfuscator during the build process. The examples illustrate how to use the relevant configuration options in the obfuscator tool to specify which assemblies to obfuscate and which map files to use. Following these examples, users can learn how to effectively apply cross-assembly renaming to their projects to increase obfuscation and protection against reverse engineering.\nPublish .NET App"},{"page":96,"heading":"","anchor":"","text":"This example demonstrates how to use the Babel task to configure cross-assembly renaming during the build process of a .NET application. Specifically, the public interface of the MathNet.Numerics package will be obfuscated to showcase how to publish an obfuscated application that consumes an obfuscated assembly. It is worth noting that the Babel.Obfuscator NuGet package is required to follow this example, and an Ultimate or Server license edition is necessary to use it. The example will showcase how to configure cross-assembly renaming to enhance the obfuscation yield of the application, making it more challenging for reverse engineering.\nThe complete source code example is available on GitHub and can be downloaded with the following command:\ngit clone https://github.com/babelfornet/cross-assembly-reference-example.git\nThe example code is a simple .NET console application that performs some basic statistical operations using MathNet.Numerics library.\nTo start configuring cross-assembly renaming, we need first to reference the Babel Obfuscator NuGet package using the Visual Studio NuGet package manager or by adding the following MSBuild instruction to the project file:\n<PackageReference Include=\"Babel.Obfuscator\" Version=\"10.0.0\">\n  <PrivateAssets>all</PrivateAssets>\n  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n</PackageReference>"},{"page":96,"heading":"","anchor":"","text":"This will make to obfuscate the target assembly Math.dll without cross-assembly renaming enabled.\nOnce the package is added, we can use the Babel task to configure cross-assembly renaming during the build process by renaming the public interface of the referenced NuGet package library MathNet.Numerics.\n<!-- Obfuscate the public interface of MathNet.Numerics reference -->\n<Target Name=\"BeforeObfuscate\">\n  <PropertyGroup>\n    <MathNetNumerics Condition=\"'%(filename)' == 'MathNet.Numerics'\">@(ReferencePathWithRefAssemblies->'%(fullpath)')</MathNetNumerics>\n    <MathNetRules>\n      <Rules>\n        <Rule name=\"rename public\" feature=\"renaming\" exclude=\"false\">\n          <Access>Public</Access>\n          <Pattern>*</Pattern>\n      </Rule>\n    </Rules>\n  </MathNetRules>\n</PropertyGroup>\n<Message Text=\"MathNet.Numerics: $(MathNetNumerics)\" Importance=\"high\" />\n  <Babel InputFile=\"$(MathNetNumerics)\" OutputFile=\"$(TargetDir)MathNet.Numerics.dll\" \n         FlattenNamespaces=\"true\" XmlRules=\"$(MathNetRules)\" \n         GenerateMapOutFile=\"true\" />\n</Target>\nSpecifically, we need to get the full path of the referenced components from the list of references used to build the application.\n<MathNetNumerics Condition=\"'%(filename)' == 'MathNet.Numerics'\">@(ReferencePathWithRefAssemblies->'%(fullpath)')</MathNetNumerics>"},{"page":96,"heading":"","anchor":"","text":"This will be the input of the Babel task with the XML rule that will configure babel to rename the public interface of the component. We also need to generate the mapping file that will be used when obfuscating the target assembly by setting the property GenerateMapOutFile=\"true\".\nNote that we set the target name to BeforeObfuscate which is an entry point defined by the Babel Obfuscator NuGet package that allows performing some additional tasks before the target assembly is obfuscated.\nTo enable cross-assembly renaming for the target assembly Math.dll, we need to add the XML mapping file generated for the referenced library MathNet.Numerics.dll to the obfuscation task for the target assembly. This can be done using the properties defined for the Babel Obfuscator NuGet package, which are described in the Package Reference.\n<!-- Target assembly obfuscation settings -->\n<ItemGroup>\n  <MapInFile Include=\"$(TargetDir)MathNet.Numerics.dll.map.xml\" />\n</ItemGroup>\n<PropertyGroup>\n  <StringEncryption>true</StringEncryption>\n  <ValueEncryption>array=true;true;</ValueEncryption>\n  <ControlFlowObfuscation>goto=on;if=on;switch=on;case=on;call=on</ControlFlowObfuscation>\n  <CopyOutputSymbolsToPublishDirectory>false</CopyOutputSymbolsToPublishDirectory>\n</PropertyGroup>\nIn order to prevent attackers from extracting additional information that can be used to analyze the obfuscated code, the publishing of PDB files has been disabled by setting:\nCopyOutputSymbolsToPublishDirectory=false."},{"page":96,"heading":"","anchor":"","text":"Info: PDB files contain debugging information, such as source code file names and line numbers, that can make it easier for attackers to understand the obfuscated code.\nUpon building the project, the cross-assembly obfuscated application will be generated in the target directory. In order to create the deployable package, it is necessary to substitute the file reference to the MathNet.Numerics.dll from the NuGet package with the file path to the obfuscated version. This step is essential to ensure that Visual Studio packages the correct obfuscated assemblies.\n<!-- Replace the deployed MathNet.Numerics.dll assembly reference with the obfuscated one -->\n<Target Name=\"UpdateFilesToPublish\" AfterTargets=\"ComputeFilesToPublish\">\n  <ItemGroup>\n    <ResolvedFileToPublish Remove=\"$(MathNetNumerics)\" />\n    <ResolvedFileToPublish Include=\"$(TargetDir)MathNet.Numerics.dll\">\n      <RelativePath>MathNet.Numerics.dll</RelativePath>\n    </ResolvedFileToPublish>\n  </ItemGroup>\n</Target>\nThe MSBuild XML fragment shown is a target named UpdateFilesToPublish that is executed after the target ComputeFilesToPublish. This target is used to replace the original MathNet.Numerics.dll assembly reference from the NuGet package with the obfuscated one in the deployment package.\nThe target first defines an item group that removes the original reference to the MathNet.Numerics.dll file by using the \"Remove\" attribute and referencing the property that contains the original file path."},{"page":96,"heading":"","anchor":"","text":"Then, the target adds the obfuscated version of the MathNet.Numerics.dll file to the item group by using the \"Include\" attribute and referencing the obfuscated file path in the target directory. The \"RelativePath\" element is used to specify the relative path to the file from the root of the deployment directory.\nWhen the target is executed, it will remove the original file reference and add the obfuscated file reference to the deployment package, ensuring that the obfuscated assembly is deployed instead of the original one.\nTo publish the completely obfuscated application, navigate to the project folder and execute the following command:\ndotnet publish\nOverall, the example serves as a starting point for developers who want to integrate Babel obfuscation into their .NET build pipeline and protect their code using cross-assembly obfuscation. In addition, we have provided some supplementary advice on how to modify the deployment package in order to incorporate the obfuscated assemblies."},{"page":97,"heading":"","anchor":"","text":"Babel Licensing is a licensing system for .NET applications and components:\ndigitally signed licenses, a licensing service for activation and floating\nlicenses, and the tools to issue, distribute and monitor them from the\ndesktop, the browser, the command line or an AI assistant."},{"page":97,"heading":"How Babel Licensing Works","anchor":"how-babel-licensing-works","text":"A Babel license is a document signed with an asymmetric key pair. You keep the private key and use it to sign licenses; your application carries the public key and uses it to verify that a license is genuine and unmodified. A license can be an XML file or a compact encoded string, such as a serial a customer can type, and it carries whatever your product needs: the licensee, expiration dates, the features it unlocks, hardware or domain restrictions, and custom fields of your own.\nThe Babel.Licensing client library validates a license inside the application, offline, so a license file works in disconnected environments. When you need central control, the Babel Licensing Service activates licenses on specific machines, shares floating licenses across a network, tracks license tokens, collects reports from the field and exposes everything over gRPC and REST. On top of the service sit the management tools: Babel Desktop on Windows, macOS and Linux, the administrative web application (Data Center), the WordPress plugin that sells licensed products through WooCommerce, the lic command line tool, and an MCP server for AI assistants."},{"page":97,"heading":"What's New","anchor":"whats-new","text":"Highlights of the recent releases, up to 12.0.\nLicensing MCP Server: Manage customers, products, licenses and activations from Claude or any MCP\nclient, in natural language, through the service REST API.\nBabel Desktop: New in 12.0: a cross-platform desktop application for Windows, macOS and\nLinux that replaces Babel UI. Its Licensing views manage customers,\nproducts, orders, licenses and templates on a Babel Licensing Service, and\nits MCP server lets an assistant do the same.\nOne Service Package: New in 12.0: a single service package serves both editions; a Data Center\nlicense unlocks the web application, with no reinstall.\nSecurity Hardening: Since 11.7: no default administrator account, a signing key generated at\nstart-up when none is configured, credentials kept out of the logs, and an\nIP whitelist that exempts trusted addresses from rate limiting.\nFIPS-Enabled Hosts: Since 11.8 license validation no longer touches the operating-system crypto\nstack, so licensed applications and the service itself start on FIPS-mode\nhosts, including containers without a FIPS provider.\nActivation License Lifecycle: Extend the expiration date of an activation license without re-issuing it,\nand add features that reach already-activated clients on their next\nvalidation.\nAI-Friendly lic CLI: Since 11.8 the lic tool emits JSON or NDJSON, with --quiet and\n--strict-exit, using the same output contract and exit codes as the\nobfuscator command line."},{"page":97,"heading":"Editions and Badges","anchor":"editions-and-badges","text":"Babel Licensing comes in two editions, and both include Babel Obfuscator Ultimate. Server provides the Babel Licensing Service, the licensing database, Babel Desktop with its Licensing views, the WordPress plugin, the lic command line tool and the client packages, with up to 1000 license tokens. Data Center adds the administrative web application, AI integration through the MCP server, and unlimited license tokens. Both editions use the same service package. With a Server license, the service address shows an upgrade page instead of the web application. To upgrade to Data Center, replace the license file and restart the service.\nTwo badges mark this in the manual. (Server) marks a component that comes with the Server edition or higher; it appears on the overview page of each Babel Licensing component, which matters most to readers who own Babel Obfuscator alone. (Data Center) marks a capability available with the Data Center edition only, and appears on every page that documents one. A heading without a badge describes something both editions include. The obfuscator manual uses (Ultimate) in the same way, and since both licensing editions include Ultimate, everything marked Ultimate is yours as well. The complete matrix, with pricing, is on the Compare Editions page."},{"page":97,"heading":"Licensing Modes","anchor":"licensing-modes","text":"License File: A signed XML file or string distributed to the customer and validated\noffline, with no server involved.\nLicense Activation: The customer activates a license on a machine; the service binds it to that\nhardware and can deactivate, extend or revoke it later.\nFloating License: A pool of seats shared across a network, allocated to clients while they\nrun and released when they stop.\nLicense Tokens: The unit the service counts for activated and floating clients: up to 1000\non Server, unlimited on Data Center."},{"page":97,"heading":"What a License Can Express","anchor":"what-a-license-can-express","text":"Every mode uses the same license model, defined once in a license template and applied to each license you issue:\nTrial restrictions that limit time, run count or instance count, so a customer can evaluate before buying.\nHardware and domain restrictions that lock a license to a machine or to a network domain.\nFeatures that switch parts of the product on and off, the basis of tiered editions; combined with the obfuscator's Code Encryption they become feature-based licenses whose code is not even present until unlocked.\nCustom restrictions and fields for anything else your product needs to check or carry, validated by your own code through the SDK.\nUser key formats that define how serials look, so a license can be a string a customer types rather than a file.\nSee License Restrictions, License Properties and the License Workflow from product definition to deployment."},{"page":97,"heading":"Components","anchor":"components","text":"Babel Licensing Service: Activation, floating licenses, tokens, reports and webhooks over gRPC and\nREST, on Windows, Linux, macOS or Docker, backed by SQL Server, MySQL or\nSQLite.\nBabel Desktop: The cross-platform desktop application: its Licensing views manage\nproducts, customers, orders, templates, licenses, tokens, reports, users and\nAPI keys on the service.\nWeb Application: Browser administration of the service: dashboard, licenses, templates,\nproducts, customers, orders, API keys, webhooks, users and logs. Included in\nthe service package and unlocked by a Data Center license.\nWordPress Plugin: Sell licensed products through WooCommerce; licenses are generated and\nemailed when an order is placed.\nCommand Line Tools: The lic dotnet tool generates signed licenses and serials from scripts and\nbuild pipelines.\nClient Components: The Babel.Licensing and Babel.Data NuGet packages that validate,\nactivate and track licenses inside your application.\nREST API: Programmatic access to licenses, products, customers, orders, reports and\nwebhooks, authenticated with API keys or JWT tokens.\nReporting: Exception, license-usage and custom reports sent from the field to the\nservice, with webhooks to forward them.\nLicense Workflow: From product definition and sign keys to templates and deployment, the\nfour stages every license goes through."},{"page":97,"heading":"Built for AI-Assisted Workflows","anchor":"built-for-ai-assisted-workflows","text":"Babel Licensing can be operated by an AI assistant at three levels.\nBabel Licensing MCP Server  (Data Center). A standalone Model Context Protocol server exposes the whole REST API of a hosted Babel Licensing Service as tools, so Claude or any MCP client can look up a customer's licenses, activate or revoke them, create orders, analyze usage and explain errors, in natural language and from anywhere. See AI Integration.\nBabel Desktop MCP server  (Server). Babel Desktop hosts an opt-in local MCP server. It lets an assistant read licensing entities, dashboards and reports and propose changes that you confirm, on the service profile the desktop is connected to, alongside the obfuscation project tools. See Babel Desktop MCP Server.\nAI-friendly command line. Since version 11.8 the lic tool shares the machine-readable output mode of the obfuscator: --format=json or --format=ndjson for a structured lic.cli.v1 stream, --quiet for unattended runs, --strict-exit for semantic exit codes, and --help --format=json to let an agent discover every option. See AI-Friendly Mode.\nInfo: Pick the Babel Licensing MCP Server for a hosted service driven from any MCP client, and the Babel Desktop MCP server when you already work in Babel Desktop and want the assistant to use its connected service profile."},{"page":97,"heading":"Platforms","anchor":"platforms","text":"Area | Support\nBabel Licensing Service | Windows, Linux and macOS on the .NET runtime, or Docker; SQL Server, MySQL, MariaDB and SQLite databases (MySQL and MariaDB on every supported .NET version, including .NET 10); gRPC over HTTP/2, gRPC-Web and REST with JSON or TOON payloads\nClient library | .NET Framework 2.0 to 4.8, .NET Standard, .NET Core and .NET up to .NET 10, ASP.NET, .NET MAUI, Xamarin, UWP and Mono\nManagement tools | Babel Desktop on Windows, macOS and Linux; the web application in any browser (Data Center); the WordPress plugin with WooCommerce; the lic tool wherever the .NET SDK runs\nHosting | On-premises or in the cloud, with health checks for orchestrators and load balancers"},{"page":97,"heading":"Next Steps","anchor":"next-steps","text":"Getting Started to install the service and the client components\nGeneral Features for a feature-by-feature tour\nLicense Workflow to define a product and issue its first license\nExamples for trial serials, feature-based licenses and activation in MAUI\nAPI Reference for the REST endpoints"},{"page":98,"heading":"","anchor":"","text":"Babel Licensing\nBabel Licensing is a licensing system for .NET applications and components:\ndigitally signed licenses, a licensing service for activation and floating\nlicenses, and the tools to issue, distribute and monitor them from the\ndesktop, the browser, the command line or an AI assistant."},{"page":98,"heading":"How Babel Licensing Works","anchor":"how-babel-licensing-works","text":"A Babel license is a document signed with an asymmetric key pair. You keep the private key and use it to sign licenses; your application carries the public key and uses it to verify that a license is genuine and unmodified. A license can be an XML file or a compact encoded string, such as a serial a customer can type, and it carries whatever your product needs: the licensee, expiration dates, the features it unlocks, hardware or domain restrictions, and custom fields of your own.\nThe Babel.Licensing client library validates a license inside the application, offline, so a license file works in disconnected environments. When you need central control, the Babel Licensing Service activates licenses on specific machines, shares floating licenses across a network, tracks license tokens, collects reports from the field and exposes everything over gRPC and REST. On top of the service sit the management tools: Babel Desktop on Windows, macOS and Linux, the administrative web application (Data Center), the WordPress plugin that sells licensed products through WooCommerce, the lic command line tool, and an MCP server for AI assistants."},{"page":98,"heading":"What's New","anchor":"whats-new","text":"Highlights of the recent releases, up to 12.0.\nLicensing MCP Server: Manage customers, products, licenses and activations from Claude or any MCP\nclient, in natural language, through the service REST API.\nBabel Desktop: New in 12.0: a cross-platform desktop application for Windows, macOS and\nLinux that replaces Babel UI. Its Licensing views manage customers,\nproducts, orders, licenses and templates on a Babel Licensing Service, and\nits MCP server lets an assistant do the same.\nOne Service Package: New in 12.0: a single service package serves both editions; a Data Center\nlicense unlocks the web application, with no reinstall.\nSecurity Hardening: Since 11.7: no default administrator account, a signing key generated at\nstart-up when none is configured, credentials kept out of the logs, and an\nIP whitelist that exempts trusted addresses from rate limiting.\nFIPS-Enabled Hosts: Since 11.8 license validation no longer touches the operating-system crypto\nstack, so licensed applications and the service itself start on FIPS-mode\nhosts, including containers without a FIPS provider.\nActivation License Lifecycle: Extend the expiration date of an activation license without re-issuing it,\nand add features that reach already-activated clients on their next\nvalidation.\nAI-Friendly lic CLI: Since 11.8 the lic tool emits JSON or NDJSON, with --quiet and\n--strict-exit, using the same output contract and exit codes as the\nobfuscator command line."},{"page":98,"heading":"Editions and Badges","anchor":"editions-and-badges","text":"Babel Licensing comes in two editions, and both include Babel Obfuscator Ultimate. Server provides the Babel Licensing Service, the licensing database, Babel Desktop with its Licensing views, the WordPress plugin, the lic command line tool and the client packages, with up to 1000 license tokens. Data Center adds the administrative web application, AI integration through the MCP server, and unlimited license tokens. Both editions use the same service package. With a Server license, the service address shows an upgrade page instead of the web application. To upgrade to Data Center, replace the license file and restart the service.\nTwo badges mark this in the manual. (Server) marks a component that comes with the Server edition or higher; it appears on the overview page of each Babel Licensing component, which matters most to readers who own Babel Obfuscator alone. (Data Center) marks a capability available with the Data Center edition only, and appears on every page that documents one. A heading without a badge describes something both editions include. The obfuscator manual uses (Ultimate) in the same way, and since both licensing editions include Ultimate, everything marked Ultimate is yours as well. The complete matrix, with pricing, is on the Compare Editions page."},{"page":98,"heading":"Licensing Modes","anchor":"licensing-modes","text":"License File: A signed XML file or string distributed to the customer and validated\noffline, with no server involved.\nLicense Activation: The customer activates a license on a machine; the service binds it to that\nhardware and can deactivate, extend or revoke it later.\nFloating License: A pool of seats shared across a network, allocated to clients while they\nrun and released when they stop.\nLicense Tokens: The unit the service counts for activated and floating clients: up to 1000\non Server, unlimited on Data Center."},{"page":98,"heading":"What a License Can Express","anchor":"what-a-license-can-express","text":"Every mode uses the same license model, defined once in a license template and applied to each license you issue:\nTrial restrictions that limit time, run count or instance count, so a customer can evaluate before buying.\nHardware and domain restrictions that lock a license to a machine or to a network domain.\nFeatures that switch parts of the product on and off, the basis of tiered editions; combined with the obfuscator's Code Encryption they become feature-based licenses whose code is not even present until unlocked.\nCustom restrictions and fields for anything else your product needs to check or carry, validated by your own code through the SDK.\nUser key formats that define how serials look, so a license can be a string a customer types rather than a file.\nSee License Restrictions, License Properties and the License Workflow from product definition to deployment."},{"page":98,"heading":"Components","anchor":"components","text":"Babel Licensing Service: Activation, floating licenses, tokens, reports and webhooks over gRPC and\nREST, on Windows, Linux, macOS or Docker, backed by SQL Server, MySQL or\nSQLite.\nBabel Desktop: The cross-platform desktop application: its Licensing views manage\nproducts, customers, orders, templates, licenses, tokens, reports, users and\nAPI keys on the service.\nWeb Application: Browser administration of the service: dashboard, licenses, templates,\nproducts, customers, orders, API keys, webhooks, users and logs. Included in\nthe service package and unlocked by a Data Center license.\nWordPress Plugin: Sell licensed products through WooCommerce; licenses are generated and\nemailed when an order is placed.\nCommand Line Tools: The lic dotnet tool generates signed licenses and serials from scripts and\nbuild pipelines.\nClient Components: The Babel.Licensing and Babel.Data NuGet packages that validate,\nactivate and track licenses inside your application.\nREST API: Programmatic access to licenses, products, customers, orders, reports and\nwebhooks, authenticated with API keys or JWT tokens.\nReporting: Exception, license-usage and custom reports sent from the field to the\nservice, with webhooks to forward them.\nLicense Workflow: From product definition and sign keys to templates and deployment, the\nfour stages every license goes through."},{"page":98,"heading":"Built for AI-Assisted Workflows","anchor":"built-for-ai-assisted-workflows","text":"Babel Licensing can be operated by an AI assistant at three levels.\nBabel Licensing MCP Server  (Data Center). A standalone Model Context Protocol server exposes the whole REST API of a hosted Babel Licensing Service as tools, so Claude or any MCP client can look up a customer's licenses, activate or revoke them, create orders, analyze usage and explain errors, in natural language and from anywhere. See AI Integration.\nBabel Desktop MCP server  (Server). Babel Desktop hosts an opt-in local MCP server. It lets an assistant read licensing entities, dashboards and reports and propose changes that you confirm, on the service profile the desktop is connected to, alongside the obfuscation project tools. See Babel Desktop MCP Server.\nAI-friendly command line. Since version 11.8 the lic tool shares the machine-readable output mode of the obfuscator: --format=json or --format=ndjson for a structured lic.cli.v1 stream, --quiet for unattended runs, --strict-exit for semantic exit codes, and --help --format=json to let an agent discover every option. See AI-Friendly Mode.\nInfo: Pick the Babel Licensing MCP Server for a hosted service driven from any MCP client, and the Babel Desktop MCP server when you already work in Babel Desktop and want the assistant to use its connected service profile."},{"page":98,"heading":"Platforms","anchor":"platforms","text":"Area | Support\nBabel Licensing Service | Windows, Linux and macOS on the .NET runtime, or Docker; SQL Server, MySQL, MariaDB and SQLite databases (MySQL and MariaDB on every supported .NET version, including .NET 10); gRPC over HTTP/2, gRPC-Web and REST with JSON or TOON payloads\nClient library | .NET Framework 2.0 to 4.8, .NET Standard, .NET Core and .NET up to .NET 10, ASP.NET, .NET MAUI, Xamarin, UWP and Mono\nManagement tools | Babel Desktop on Windows, macOS and Linux; the web application in any browser (Data Center); the WordPress plugin with WooCommerce; the lic tool wherever the .NET SDK runs\nHosting | On-premises or in the cloud, with health checks for orchestrators and load balancers"},{"page":98,"heading":"Next Steps","anchor":"next-steps","text":"Getting Started to install the service and the client components\nGeneral Features for a feature-by-feature tour\nLicense Workflow to define a product and issue its first license\nExamples for trial serials, feature-based licenses and activation in MAUI\nAPI Reference for the REST endpoints"},{"page":99,"heading":"","anchor":"","text":"What Babel Licensing does, where it runs, and which edition includes what.\nEach section links to the page that shows how to use the feature."},{"page":99,"heading":"Fully Managed Licensing System","anchor":"fully-managed-licensing-system","text":"Babel Licensing covers the whole life of a software license: defining products and templates, generating and signing licenses, distributing them as files or serials, activating them on machines or sharing them across a network, tracking their use, and revoking or extending them. The client library enforces the terms inside your application; the service, the desktop and web tools, the WordPress plugin and the command line tool manage them on your side. The License Workflow page walks through the four stages from product definition to deployment."},{"page":99,"heading":"Based on Digitally Signed Licenses","anchor":"based-on-digitally-signed-licenses","text":"Every license is signed with an asymmetric key pair: the private key stays with you and signs, the public key travels with the application and verifies. A tampered or forged license fails verification before any of its content is trusted. Licenses are stored as XML files, which are easy to read and to ship with an installer, or as encoded strings, which fit in a serial a customer types, an activation response, or a database field. Both forms carry the same content and validate the same way."},{"page":99,"heading":"Compatible With Any .NET Technology","anchor":"compatible-with-any-net-technology","text":"The Babel.Licensing client library targets every .NET runtime that produces standard assemblies:\n.NET Core and .NET, up to .NET 10\n.NET Framework 2.0 to 4.8\n.NET Standard\nASP.NET and ASP.NET Core\n.NET MAUI and Xamarin\nUWP and Mono\nThe Babel Licensing Service is a .NET application that runs on Windows, Linux and macOS, natively or in Docker. Both work with the usual development environments, including Visual Studio and Visual Studio Code, and the client components install as NuGet packages."},{"page":99,"heading":"Flexible Licensing Model","anchor":"flexible-licensing-model","text":"A license expresses what your product needs to check, all of it defined once in a license template:\nTrial licenses limited by time, run count or instance count, so a customer can evaluate before buying.\nHardware-locked licenses tied to a machine fingerprint, so a license cannot be copied to another computer.\nDomain-restricted licenses that only validate inside a given network domain.\nFeature-based licenses that enable or disable parts of the product, the basis of tiered editions.\nCustom restrictions validated by your own code, for rules the built-in ones do not cover.\nCustom fields that carry any metadata you need: customer data, contract terms, configuration.\nLicense Restrictions and License Properties describe each in detail; User Key Format defines how serials look."},{"page":99,"heading":"Three Licensing Modes","anchor":"three-licensing-modes","text":"The same license model is deployed in one of three licensing modes. A license file is validated offline, with no server involved, which suits disconnected and protected environments. License activation binds a license to a specific machine through the service, which can later deactivate it, extend its expiration date or push new features to already-activated clients. A floating license is a pool of seats shared across a network, allocated to clients while they run and released when they stop."},{"page":99,"heading":"License Tokens (Server)","anchor":"license-tokens-","text":"Activated and floating clients each hold a license token on the service while they are in use; file licenses consume none. The Server edition allows up to 1000 active tokens at a time, which is the maximum number of clients that can be connected or activated simultaneously, and reclaims a token as soon as its license is released or deactivated. The Data Center edition (Data Center) removes the limit."},{"page":99,"heading":"Babel Licensing Service (Server)","anchor":"babel-licensing-service-","text":"The Babel Licensing Service is the central component: it activates and validates licenses, allocates floating seats, counts tokens, receives reports from licensed applications, dispatches webhooks and exposes a gRPC and REST API. It runs on-premises or in the cloud, on Windows, Linux, macOS or Docker, and stores its data in the Babel Licensing Database on SQL Server, MySQL, MariaDB or SQLite, with MySQL and MariaDB supported on .NET 10 as well. Since version 11.7 it ships without a default administrator account or a hardcoded signing key, and since 11.8 it starts on FIPS-mode hosts whose container lacks a certified crypto provider; see Configuration, Health Check and FIPS Compliance."},{"page":99,"heading":"Management From the Desktop (Server)","anchor":"management-from-the-desktop-","text":"Babel Desktop is a cross-platform application for Windows, macOS and Linux that also configures obfuscation. Its Licensing section connects to a Babel Licensing Service with an API key. From it you manage customers, contacts, products, releases, orders, licenses and templates, generate, revoke, export and email licenses, browse reports, tokens, traces and logs, and administer users, API keys and webhooks, with a dashboard and a geography view. Changes require a local management profile, that is, Babel Desktop running on the service machine; profiles of remote services are read-only. Its MCP server can expose these operations to an AI assistant."},{"page":99,"heading":"Management From the Browser (Data Center)","anchor":"management-from-the-browser-","text":"The web application administers the service from any browser with role-based users. Its dashboard shows license distribution on a map, sales by product and token usage; its pages manage licenses, templates, products, customers, orders and resources such as sign keys and email templates; it issues API keys for external integrations, configures webhooks that notify your systems of licensing events, and exposes exception reports and the activity log. The web application ships inside the single service package and is unlocked by a Data Center license; with a Server license the service address shows an upgrade page."},{"page":99,"heading":"Sell Through WordPress and WooCommerce (Server)","anchor":"sell-through-wordpress-and-woocommerce-","text":"The WordPress plugin manages products, templates, customers and licenses from the WordPress admin and integrates with WooCommerce, so a license is generated and emailed automatically when a licensed product is purchased. Email templates for issue, expiration and renewal notices are editable from the same interface."},{"page":99,"heading":"Reporting From the Field","anchor":"reporting-from-the-field","text":"Licensed applications can send reports to the service: exception reports with stack traces, environment and system information for crash diagnosis; license reports that record which features, fields and restrictions are actually used; and custom reports carrying any data your application wants to collect, encrypted when sensitive. Reports are browsed in Babel Desktop or the web application and can be forwarded through webhooks."},{"page":99,"heading":"Integrated SDK, MSBuild and Command Line (Server)","anchor":"integrated-sdk-msbuild-and-command-line-","text":"The client library and the Babel.Data package let you script every licensing operation, from validation in the application to license generation in a build. The lic command line tool, installed as a dotnet tool, generates signed licenses and serials with all their properties and restrictions from scripts and CI pipelines; since version 11.8 it emits machine-readable JSON or NDJSON output, with --quiet and --strict-exit; see AI-Friendly Mode. The Lic MSBuild task exposes the same switches to a build."},{"page":99,"heading":"Operated by AI Assistants Through MCP (Data Center)","anchor":"operated-by-ai-assistants-through-mcp-","text":"The Babel Licensing MCP Server exposes the service REST API to Claude and any Model Context Protocol client, so an assistant can look up a customer's licenses, activate, extend or revoke them, create customers and orders, analyze activation trends and explain error messages, all in natural language. The AI Integration page shows the use cases for support, sales, development and administration."},{"page":99,"heading":"Fully Integrated With Babel Obfuscator","anchor":"fully-integrated-with-babel-obfuscator","text":"Both licensing editions include Babel Obfuscator Ultimate, and the two products are designed to work together. The client library is meant to be obfuscated with the application that carries it, and the obfuscator's Code Encryption lets a license password unlock encrypted code, so a feature-based license protects not just a switch but the implementation behind it. Licenses can also be generated and validated from Babel Desktop, the same application that runs obfuscation projects, and from its MCP server."},{"page":99,"heading":"FIPS-Ready","anchor":"fips-ready","text":"License validation uses no algorithm FIPS disallows, and since version 11.8 it does not depend on the operating-system crypto stack at all, so licensed applications start on FIPS-mode hosts even when the container has no certified OpenSSL provider. The service itself starts on such hosts when obfuscated with the managed AES option of Babel Obfuscator. See FIPS Compliance."},{"page":100,"heading":"","anchor":"","text":"Babel Licensing is a set of components and tools for building and managing licensed applications. Some components run on the server, others inside the client application.\nThe server-side components of Babel Licensing include:\nBabel Licensing Database: This is a database that stores license-related information such as license keys, expiration dates, and license usage. It supports different database providers such as SQL Server, MySQL/MariaDB, SQLite and PostgreSQL. The database can be installed on-premises or on a cloud platform.\nBabel Licensing Services: This is a centralized service that manages licenses over a network. It provides features such as license activation, license validation, and floating licenses. The service can be installed on-premises or on a cloud platform.\nThe client-side component of Babel Licensing are:\nBabel.Licensing NuGet package: This provides .NET client libraries to access the Babel Licensing Services.\nBabel.Data NuGet package: Provides the types to access the Babel Licensing Database.\nThese client-side components allow developers to integrate licensing into their applications and manage licenses from within the application.\nThe service is managed with these tools:"},{"page":100,"heading":"","anchor":"","text":"Babel Desktop: the cross-platform desktop application for Windows, macOS and Linux, which also manages the service (see Babel Desktop).\nWeb application: included in the service package and unlocked by a Data Center license.\nlic CLI: a dotnet tool that generates digitally signed license files. It is useful for automating license generation and can be integrated into any build system."},{"page":100,"heading":"Supported databases","anchor":"supported-databases","text":"Babel Licensing Service 12.0 supports SQL Server, MySQL/MariaDB, SQLite and PostgreSQL on Windows, Linux and macOS. Select the provider in the service configuration; Babel Desktop connects to the service endpoint, not directly to its database.\nDatabase | Provider | Connection string key | Default port\nSQL Server | SQLServer | ConnectionStrings:SQLServer | 1433\nMySQL / MariaDB | MySQL | ConnectionStrings:MySQL | 3306\nPostgreSQL | PostgreSQL | ConnectionStrings:PostgreSQL | 5432\nSQLite | SQLite | ConnectionStrings:SQLite | Local file\nConfigure and start the Licensing Service yourself, including a local SQLite service. Babel Desktop does not install, start or stop it. Point the Desktop connection profile at the service’s HTTP/HTTPS endpoint.\nDatabase configuration and connection strings."},{"page":101,"heading":"Packages","anchor":"packages","text":"Babel is distributed in the following packages:\nBabel Desktop installers: a Windows installer (NSIS .exe) and MSI, a macOS .dmg and .zip, and Linux AppImage, .deb and .rpm packages. Babel Desktop manages licensing from the desktop; see Babel Desktop.\nLicensing service zips: babel_service_net60_<version>.zip, babel_service_net70_<version>.zip, babel_service_net80_<version>.zip, babel_service_net90_<version>.zip and babel_service_net100_<version>.zip. One package serves both the Server and Data Center editions; there is no separate Data Center package.\nObfuscator zips: babel_net472_<version>.zip, babel_net80_<version>.zip, babel_net90_<version>.zip and babel_net100_<version>.zip. They contain the babel and lic command lines, HardwareId and the MSBuild task.\nNuGet packages: Babel.Licensing, Babel.Licensing.Tool and Babel.Data, plus Babel.Obfuscator and Babel.Obfuscator.Tool.\nInfo: The Windows MSI installers of earlier versions (babel_obfuscator_<version>.msi and babel_licensing_<version>.msi) and the macOS package (babel_mac_<version>.zip) are no longer distributed. To manage licensing from the desktop, install Babel Desktop. Use the zip packages or NuGet tools for the command line."},{"page":101,"heading":"Server Components","anchor":"server-components","text":"Babel Licensing Service is a .NET application, so it runs on Windows, Linux and macOS. The following guides explain how to install it:\nWindows 11\nLinux Ubuntu\nDocker"},{"page":101,"heading":"Supported databases","anchor":"supported-databases","text":"Babel Licensing Service 12.0 supports SQL Server, MySQL/MariaDB, SQLite and PostgreSQL on Windows, Linux and macOS. Select the provider in the service configuration; Babel Desktop connects to the service endpoint, not directly to its database.\nDatabase | Provider | Connection string key | Default port\nSQL Server | SQLServer | ConnectionStrings:SQLServer | 1433\nMySQL / MariaDB | MySQL | ConnectionStrings:MySQL | 3306\nPostgreSQL | PostgreSQL | ConnectionStrings:PostgreSQL | 5432\nSQLite | SQLite | ConnectionStrings:SQLite | Local file\nConfigure and start the Licensing Service yourself, including a local SQLite service. Babel Desktop does not install, start or stop it. Point the Desktop connection profile at the service’s HTTP/HTTPS endpoint.\nDatabase configuration and connection strings."},{"page":101,"heading":"Client Components","anchor":"client-components","text":"To integrate Babel Licensing into your .NET applications and software components, you will need to install the Babel Licensing client components. These components include the Babel Licensing NuGet package and the Babel Data NuGet package.\nBabel Licensing NuGet Package: The client library that talks to Babel Licensing Services. It adds license validation, activation and enforcement to your .NET applications, with online and offline license key verification, license generation and license lifecycle management.\nBabel Data NuGet Package: Types for accessing the Babel Licensing Database, used together with the Babel Licensing package. It includes data models, repositories and utilities for retrieving license information, managing license data and running database operations.\nTo install the client components, add the NuGet packages to your .NET projects."},{"page":102,"heading":"","anchor":"","text":"This section provides a step-by-step guide to installing Babel Licensing\nService on Windows 11.\nFollow these instructions to install and configure the Babel Licensing Service on Windows 11."},{"page":102,"heading":"Prerequisites","anchor":"prerequisites","text":"To successfully install Babel Licensing Service on Windows 11, you will need to ensure that the following prerequisites are met.\nEnsure that Windows 11 has been updated to the latest version\nMicrosoft SQL Server, or MySQL/MariaDB (the .NET 10 service is tested with MySQL 8.4 and MariaDB 11.4)\nThe ASP.NET Core runtime that matches the service package (for example .NET 10 for babel_service_net100_x.y.z.w.zip)\nBabel Licensing Service ZIP package (e.g., babel_service_net100_x.y.z.w.zip). The same package serves both editions.\nBabel Licensing Server or Data Center edition license file (babel.licenses)\nIf running the install script, PowerShell version 7 or greater is required"},{"page":102,"heading":"Install Script","anchor":"install-script","text":"The BabelLicensingService.ps1 PowerShell script is designed to automate the installation and configuration process of the Babel Licensing Service on Windows environments described in this paragraph.\nThis script ensures prerequisites such as administrative privileges, correct PowerShell version, and the MariaDB CLI command are met before initiating the installation process. It lets you install the service and query its status.\nDuring the installation, it handles tasks like extracting the installation ZIP, copying the license file, creating the database, modifying the appsettings.json for accurate connection strings, and installing the service with the correct configuration, so you avoid the errors of a manual setup.\nTo use the BabelLicensingService.ps1 script, follow the steps below:"},{"page":102,"heading":"Install Script","anchor":"install-script","text":"Download the script\nDownload the script from this link.\nCopy the script to a temporary folder\nCopy the downloaded script into a temporary folder.\nAdd the service zip and the license file\nPlace the Babel service zip archive (named babel_service_net100_x.y.z.w.zip, where x.y.z.w is the version) and the license file (babel.licenses) in the same temporary folder as the script.\nRun the script\nRun the BabelLicensingService.ps1 script from the temporary folder to start the installation process.\nWhen attempting to run the script, you may encounter the following error:\nThe file C:\\Projects\\BabelSvc\\BabelLicensingService.ps1 is not digitally signed. You cannot run this script on the current system.\nTo resolve this, you can modify the execution policy to a less restrictive one, allowing the script to run, by executing the following command:\nSet-ExecutionPolicy -ExecutionPolicy Unrestricted\nSetting the execution policy to Unrestricted can expose the system to security risks. Only run scripts from trusted sources, and consider resetting the policy to a more secure setting when the script has finished.\nIf you prefer not to use the BabelLicensingService.ps1 script, you can continue reading for step-by-step instructions on how to manually set up the service."},{"page":102,"heading":"Setup Files","anchor":"setup-files","text":"Setting up the Babel Licensing Service requires extracting the necessary service assemblies and configurations from the provided ZIP file, babel_service_net100_x.y.z.w.zip, to the appropriate directory on your Windows machine. Below are the step-by-step instructions to extract the ZIP file using Windows Explorer to the C:\\BabelSvc directory.\nIn Windows Explorer, go to the folder where babel_service_net100_x.y.z.w.zip is saved.\nRight-click the archive\nRight-click on the babel_service_net100_x.y.z.w.zip file.\nChoose Extract All\nSelect Extract All... from the context menu.\nSet the destination folder\nIn the 'Extract Compressed (Zipped) Folders' dialog box, enter C:\\BabelSvc as the destination folder.\nExtract the files\nClick Extract.\nThe Babel Licensing Service files from babel_service_net100_x.y.z.w.zip are now in the C:\\BabelSvc directory.\nLicense File\nCopy the license file babel.licenses, into the extract folder. This step ensures that the service can access the required licensing information.\nInfo: The license file sets the edition. With a Data Center license the web application is served at the service address. With a Server license that address shows an upgrade page with an edition comparison; the service, its API and Babel Desktop keep working. To upgrade, replace babel.licenses and restart the service; there is nothing to reinstall."},{"page":102,"heading":"Creating Database","anchor":"creating-database","text":"When setting up the Babel Licensing Service, creating a dedicated database and user is essential. Below are the step-by-step instructions for creating the Babel Licensing database with Microsoft SQL Server and MySQL MariaDB.\nMicrosoft SQL Server\nTo manage Babel Licensing Service licenses with SQL Server, setting up a dedicated database is essential. This guide provides steps to configure the database for seamless operation.\nLaunch SQL Server Management Studio (SSMS).\nConnect to your SQL Server instance.\nOpen a new query window to execute the SQL commands.\nRun the following SQL commands to create the database and configure the user\n-- Create the licenses database\nCREATE DATABASE licenses;\nGO\n\n-- Create a new SQL Server login for the Babel Licensing Service\nCREATE LOGIN babel WITH PASSWORD = 'YourUniquePassword';\nGO\n\n-- Create a database user linked to the login\nUSE licenses;\nCREATE USER babel FOR LOGIN babel;\nGO\n\n-- Grant the necessary privileges to the user\nALTER ROLE db_owner ADD MEMBER babel;\nGO\nMySQL MariaDB\nHeidiSQL, a powerful and easy-to-use open-source database management tool, can be used in conjunction with MariaDB to facilitate this process. Below are the step-by-step instructions to create a database using HeidiSQL and MariaDB.\nStart by launching HeidiSQL and switch to the SQL tab to run the following SQL commands:"},{"page":102,"heading":"Creating Database","anchor":"creating-database","text":"CREATE DATABASE licenses;\nCREATE USER babel@localhost IDENTIFIED BY 'YourUniquePassword';\nGRANT ALL PRIVILEGES ON licenses.* TO babel@localhost;\nFLUSH PRIVILEGES;\nAfter executing the above steps, verify that the licenses database has been created successfully and that the babel user has the correct privileges assigned. You can do this by logging in with the babel user credentials and trying to access the licenses database."},{"page":102,"heading":"Configuring Babel Licensing Service","anchor":"configuring-babel-licensing-service","text":"Configuring the Babel Licensing Service is a crucial step to ensure its proper functionality and integration with your environment. This involves modifying the appsettings.json file located in the extracted folder and adjusting various settings to match your specific requirements.\nEditing appsettings.json\nNavigate to the extracted folder and locate the appsettings.json file. Open the file using your preferred text editor and update the database configuration to match the database server you selected for setting up the Babel Licensing database.\nMicrosoft SQL Server\nTo set up the Babel Licensing database on Microsoft SQL Server, please configure the Database Provider and SQLServer connection string as follows:\n\"Database\": {\n  \"Provider\": \"SQLServer\"\n},\n\"ConnectionStrings\": {\n  \"SQLServer\": \"Data Source=SQLSERVER_INSTANCE_NAME;User Id=babel;Password=YourUniquePassword;Encrypt=false;Initial Catalog=licenses\",\n  \"MySQL\": \"\",\n  \"SQLite\": \"\"\n},\nReplace SQLSERVER_INSTANCE_NAME with the name of your SQL Server instance as displayed in SQL Server Object Explorer or your SQL Server Management Studio (SSMS) connection.\nUse YourUniquePassword as the password you set for the babel login in Microsoft SQL Server.\nMySQL MariaDB\nIf you opted for MySQL and MariaDB when creating Babel Licensing database, configure the Database Provider and the MySQL connection string as follows:"},{"page":102,"heading":"Configuring Babel Licensing Service","anchor":"configuring-babel-licensing-service","text":"\"Database\": {\n  \"Provider\": \"MySQL\"\n},\n\"ConnectionStrings\": {\n  \"SQLServer\": \"\",\n  \"MySQL\": \"Server=127.0.0.1;User=babel;Password=YourUniquePassword;Database=licenses\",\n  \"SQLite\": \"\"\n},\nHere, ensure that the Provider under Database is set to MySQL, and the MySQL connection string is correctly configured with the appropriate server address, user, password, and database name. Replace YourUniquePassword with the actual password you've set for the babel user in MariaDB.\nInfo: On .NET 10 the service uses the Microting.EntityFrameworkCore.MySql provider, an MIT-licensed fork of Pomelo with Entity Framework Core 10 support. Earlier frameworks use Pomelo. The MySQL provider name, connection string and schema are the same on every framework."},{"page":102,"heading":"Configuring Kestrel","anchor":"configuring-kestrel","text":"In the EndpointDefaults section, the Protocols is set to Http1AndHttp2, allowing the server to communicate using both HTTP1 and HTTP2 protocols, providing flexibility and compatibility with different types of clients.\n\"Kestrel\": {\n  \"EndpointDefaults\": {\n    \"Protocols\": \"Http1AndHttp2\"\n  },\n  \"Endpoints\": {\n    \"gRPC\": {\n      \"Url\": \"http://*:5005\",\n      \"Protocols\": \"Http2\"\n    }\n  }\n},\nThe Endpoints section is where you define specific endpoints for the service. Here, an endpoint named gRPC is configured with the Url set to http://*:5005, allowing the service to listen on all available network interfaces on port 5005. The Protocols for this endpoint is specifically set to Http2, optimizing it for gRPC communication.\nWhen configuring Kestrel, ensure that the specified URLs and protocols align with your service requirements and network environment, and adjust them as necessary to achieve the desired behavior and performance of your service.\nConfiguring Serilog\nFurther, configure the Serilog section to set up logging preferences:"},{"page":102,"heading":"Configuring Kestrel","anchor":"configuring-kestrel","text":"\"Serilog\": {\n  \"Using\": [\"Serilog.Sinks.Console\", \"Serilog.Sinks.File\"],\n  \"MinimumLevel\": {\n    \"Default\": \"Information\",\n    \"Override\": {\n      \"Microsoft\": \"Warning\",\n      \"System\": \"Warning\",\n      \"Grpc\": \"Warning\"\n    }\n  },\n  \"Enrich\": [\"FromLogContext\", \"WithMachineName\", \"WithThreadId\"],\n  \"WriteTo\": [\n    {\"Name\": \"Console\"},\n    {\n      \"Name\": \"File\",\n      \"Args\": {\n        \"path\": \"C:\\\\BabelSvc\\\\log.txt\",\n        \"rollingInterval\": \"Day\"\n      }\n    }\n  ]\n},\nInfo: In this section, specify the full path to the log file, especially when running Babel Licensing Service as a Windows Service, to avoid any logging issues. For instance, \"path\": \"C:\\\\BabelSvc\\\\log.txt\" sets the log file to be stored in the C:\\BabelSvc directory.\nApplication Settings\nLastly, under the Application section, specify the LicenseFile, SigningKey, and TokenExpiration values:\n\"Application\": {\n  \"AdminUsername\": \"your-admin-user\",\n  \"AdminEmail\": \"admin@example.com\",\n  \"AdminPassword\": \"<strong-initial-password>\",\n  \"LicenseFile\": \"babel.licenses\",\n  \"SigningKey\": \"Secret Token Key\",\n  \"TokenExpiration\": \"00:30:00\"\n},\nHere, LicenseFile should be set to babel.licenses. Customize the SigningKey by replacing Secret Token Key with your unique key, which will secure the communication between application clients and the Babel Licensing Service. Adjust the TokenExpiration value according to your requirements to set the token's validity duration."},{"page":102,"heading":"Configuring Kestrel","anchor":"configuring-kestrel","text":"Warning: Since 11.7.0 — the service no longer ships with admin / admin default credentials, and SigningKey is no longer prefilled. Populate AdminUsername and AdminPassword before the first start to provision the initial administrator account (AdminEmail is optional but recommended); if either required value is empty the service still starts but no admin user is created, so the Web Application (Data Center) cannot sign in with that account and Babel Desktop has no administrator API key to connect with, until you set them and restart. If SigningKey is left empty, a random key is generated at startup, but it is regenerated at every restart and not shared across instances — for production, always set an explicit value (for example via the BABEL_SERVICE_APPLICATION__SIGNINGKEY environment variable)."},{"page":102,"heading":"Start Babel Licensing Service","anchor":"start-babel-licensing-service","text":"To start the Babel Licensing Service using PowerShell, follow these steps:\nOpen PowerShell\nOpen PowerShell from the Start menu.\nNavigate to the installation folder\nNavigate to the directory where Babel.Licensing.Service.exe is located using the cd command, typically:\ncd C:\\BabelSvc\nRun the service executable\nRun the executable with the following command:\n.\\Babel.Licensing.Service.exe\nCheck the output messages to confirm that the service starts without errors. If something goes wrong, see the service documentation for troubleshooting.\nInfo: When starting the service, a Windows Firewall popup may appear, requesting permission for the service to communicate over the network. Choose 'Allow access', otherwise the service cannot communicate with other systems on the network or the internet."},{"page":102,"heading":"Running as a Windows Service","anchor":"running-as-a-windows-service","text":"To ensure Babel Licensing Service operates efficiently in the background and is available upon system startups, it is recommended to run it as a Windows service. Running as a service allows Babel Licensing Service to operate independently of user sessions, offering uninterrupted service availability and functionality.\nTo accomplish this, you can use PowerShell’s New-Service command, which is designed to create a new entry for a Windows service in the registry and the service database. Below is the adapted command using New-Service in PowerShell:\nNew-Service -Name \"Babel.Licensing\" -BinaryPathName \"C:\\BabelSvc\\Babel.Licensing.Service.exe\" -DisplayName \"Babel Licensing\" -StartupType \"Automatic\" -Description \"Babel licensing and reporting network services.\"\nIn this command:\n-Name \"Babel.Licensing\" specifies the name of the service.\n-BinaryPathName \".\\Babel.Licensing.Service.exe\" defines the path to the service's executable file, indicating the current directory.\n-DisplayName \"Babel Licensing\" assigns a display name to the service, which is how it will appear in the Services application or other user interfaces.\n-StartupType \"Automatic\" configures the service to start automatically with the system.\n-Description \"Babel licensing and reporting network services.\" provides a description, offering insights into the service's role and functionality."},{"page":102,"heading":"Running as a Windows Service","anchor":"running-as-a-windows-service","text":"This command should be run in a PowerShell session with administrative privileges to ensure the proper creation and configuration of the service. After executing the command, the Babel Licensing Service will be set up as a Windows service, ready to offer continuous operation and availability on the system.\nStart the Service\nStart-Service -Name \"Babel.Licensing\"\nStop the Service\nStop-Service -Name \"Babel.Licensing\"\nGet Service Status\nGet-Service -Name \"Babel.Licensing\"\nUninstall the Service\nGet-Service -Name \"Babel.Licensing\" | Remove-Service\nRemember to run these commands in a PowerShell session with administrative privileges to ensure they execute correctly."},{"page":103,"heading":"","anchor":"","text":"This section provides a step-by-step guide to installing Babel Licensing\nService on Linux Ubuntu.\nBy following these instructions, you will be able to set up and configure the Babel Licensing Service on your Ubuntu system."},{"page":103,"heading":"Prerequisites","anchor":"prerequisites","text":"To successfully install Babel Licensing Service on Linux Ubuntu LTS, you will need to ensure that the following prerequisites are met.\nLinux Ubuntu 22.04 LTS\nMariaDB or MySQL (the .NET 10 service is tested with MySQL 8.4 and MariaDB 11.4)\nThe ASP.NET Core runtime that matches the service package (for example .NET 10 for babel_service_net100_x.y.z.w.zip)\nBabel Licensing Service ZIP package (babel_service_net100_x.y.z.w.zip). The same package serves both editions.\nBabel Licensing Server or Data Center license file (babel.licenses)\nAdditionally, ensure you have the root password available during the installation process. This password is required to perform administrative tasks, such as installing files and configuring the system.\nHere are the commands you can use to check the versions of the installed components on your Linux Ubuntu system.\nTo check the Ubuntu version\nlsb_release -a\nThis command will display detailed information about your Ubuntu distribution, including the version number.\nTo check the MariaDB version\nmariadb-admin --version\nRunning this command will provide you with the version information of the installed MariaDB server.\nTo check the .NET runtime versions\ndotnet --list-runtimes\nExecuting this command will list the available .NET runtime versions installed on your system."},{"page":103,"heading":"Install Script","anchor":"install-script","text":"The BabelLicensingService.sh Bash script is crafted to streamline the installation and configuration of the Babel Licensing Service on Ubuntu Linux environments as outlined in this section.\nThis script verifies prerequisites such as root privileges, the presence of required tools like MariaDB CLI command, and dotnet before commencing the installation procedure. It offers an intuitive interface, enabling users to effortlessly install and check the service status.\nThroughout the installation, the script manages various tasks including unzipping the installation archive, transferring the license file, initializing the database, adjusting the appsettings.json for proper connection strings, and setting up the service with the right configurations.\nTo use the BabelLicensingService.sh script, follow these steps:\nDownload the script\nDownload the script from the provided link.\nMove the script to a temporary directory\nMove the downloaded script to a temporary directory (the user's home directory).\nAdd the service zip and the license file\nPut the Babel service zip file (named babel_service_net100_x.y.z.w.zip, where x.y.z.w is the version) and the license file (babel.licenses) in the same temporary directory as the script.\nRun the script\nRun the following commands to start the installation.\nchmod +x ./BabelLicensingService.sh\nsudo <a data-footnote-ref href=\"#user-content-fn-1\">./BabelLicensingService.sh</a>"},{"page":103,"heading":"Install Script","anchor":"install-script","text":"If you opt not to use the BabelLicensingService.sh script, you may proceed to the subsequent sections for detailed instructions on manual service setup."},{"page":103,"heading":"Setup Files","anchor":"setup-files","text":"To install the Babel Licensing Service, copy the ZIP file containing all the service assemblies and the license file to the home directory of the \"babel\" user (/home/babel), then extract, configure and set up the database. Assuming you are currently in the directory where the ZIP file is located, follow these steps:"},{"page":103,"heading":"Setup Files","anchor":"setup-files","text":"Copy the files to the babel user's home directory\nOpen a terminal and run the following command to copy the ZIP file and the license file to the desired location:\ncp babel_service_net100_x.y.z.w.zip /home/babel/\ncp babel.licenses /home/babel/\nNow, the ZIP file containing the Babel Licensing Service assemblies will be available in the home directory of the \"babel\" user (/home/babel). You can proceed with the installation and configuration of the Babel Licensing Service using the files in this directory.\nCreate the installation folder and extract the archive\nCreate the \"svc/babel\" folder under \"/var/www\" and extract the contents of the ZIP archive:\nIn the terminal window, run the following command to create the \"svc/babel\" folder under \"/var/www\"\nsudo mkdir -p /var/www/svc/babel\nYou will be prompted to enter your password, as \"sudo\" grants administrative privileges for creating directories under the system directory.\nChange the current working directory to the newly created \"babel\" folder:\ncd /var/www/svc/babel\nExtract the contents of the ZIP archive into the current directory (\"/var/www/svc/babel\"):\nsudo unzip /home/babel/babel_service_net100_x.y.z.w.zip\nBy following these steps, you will create the necessary folder structure and extract the contents of the ZIP archive into the \"/var/www/svc/babel\" directory. This will allow you to proceed with the installation and configuration of the Babel Licensing Service in the appropriate location.\nCopy the license file"},{"page":103,"heading":"Setup Files","anchor":"setup-files","text":"Copy the license file \"babel.licenses\" into the \"/var/www/svc/babel\" directory using the following command:\nsudo cp /home/babel/babel.licenses /var/www/svc/babel/\nNow, the license file \"babel.licenses\" is installed in \"/var/www/svc/babel\" directory, you can proceed with the configuration of the user that will run the Babel Licensing Service user.\nInfo: The license file sets the edition. With a Data Center license the web application is served at the service address. With a Server license that address shows an upgrade page with an edition comparison; the service, its API and Babel Desktop keep working. To upgrade, replace babel.licenses and restart the service; there is nothing to reinstall.\nSet application ownership\nWith the license file \"babel.licenses\" successfully installed in the \"/var/www/svc/babel\" directory, the next step is to configure the user that will run the Babel Licensing Service. In this case, we will set the user as \"www-data.\"\nTo configure the user, execute the following command in the terminal:\nsudo chown www-data:www-data -R /var/www/svc/babel\nThis command changes the ownership of the \"/var/www/svc/babel\" directory and its contents to the \"www-data\" user and group. By setting the correct ownership, you ensure that the Babel Licensing Service can be run by the appropriate user, allowing it to access and operate on the necessary files and directories.\nConfigure the service"},{"page":103,"heading":"Setup Files","anchor":"setup-files","text":"To configure the Babel Licensing Service and edit the appsettings.json file with the appropriate database connection settings and other application configurations, follow these steps:\nIn a terminal window, use the following command to open the appsettings.json file in the Nano text editor\nsudo nano /var/www/svc/babel/appsettings.json\nIn the appsettings.json file, locate the \"Database\" section. Set the \"Provider\" value to \"MySQL\" to specify that you are using MySQL as the database provider\n\"Database\": {\n  \"Provider\": \"MySQL\"\n},\nFind the \"ConnectionStrings\" section. Under the \"MySQL\" key, modify the connection string to match your MySQL server configuration. Update the server, User, Password, and Database values accordingly:\n\"ConnectionStrings\": {\n  \"SQLServer\": \"\",\n  \"MySQL\": \"Server=127.0.0.1;User=babel;Password=YourUniquePassword;Database=licenses\",\n  \"SQLite\": \"\"\n},\nInfo: On .NET 10 the service uses the Microting.EntityFrameworkCore.MySql provider, an MIT-licensed fork of Pomelo with Entity Framework Core 10 support. Earlier frameworks use Pomelo. The MySQL provider name, connection string and schema are the same on every framework.\nRemember to replace \"YourUniquePassword\" with a strong password of your choice. It is highly recommended to use a combination of uppercase and lowercase letters, numbers, and special characters to create a secure password. Keep the password for later use during the database configuration."},{"page":103,"heading":"Setup Files","anchor":"setup-files","text":"Optionally, you can customize other application settings. For example, under the \"Serilog\" section, you can configure logging settings and adjust the minimum log level:\n\"Serilog\": {\n  \"Using\": [ \"Serilog.Sinks.Console\", \"Serilog.Sinks.File\" ],\n  \"MinimumLevel\": {\n    \"Default\": \"Information\",\n    \"Override\": {\n      \"Microsoft\": \"Debug\",\n      \"System\": \"Debug\",\n      \"Grpc\": \"Debug\"\n    }\n  },\n  ...\n},\nIt might be useful for debugging installation issues to set the minimum log level to Debug. When the service is running, we can revert the log level to Information or Warning.\nFurther down, under the \"Application\" section, you can specify the \"LicenseFile\" (babel.licenses) and customize the \"SigningKey\" and \"TokenExpiration\" values according to your requirements:\n\"Application\": {\n  \"AdminUsername\": \"your-admin-user\",\n  \"AdminEmail\": \"admin@example.com\",\n  \"AdminPassword\": \"<strong-initial-password>\",\n  \"LicenseFile\": \"babel.licenses\",\n  \"SigningKey\": \"Secret Token Key\",\n  \"TokenExpiration\": \"00:30:00\"\n},\nReplace the Secret Token Key with your unique key. This will we used to secure the communication between application clients and the Babel Licensing Service."},{"page":103,"heading":"Setup Files","anchor":"setup-files","text":"Warning: Since 11.7.0 — the service no longer ships with admin / admin default credentials, and SigningKey is no longer prefilled. Populate AdminUsername and AdminPassword before the first start to provision the initial administrator account (AdminEmail is optional but recommended); if either required value is empty the service still starts but no admin user is created, so the Web Application (Data Center) cannot sign in with that account and Babel Desktop has no administrator API key to connect with, until you set them and restart. If SigningKey is left empty, a random key is generated at startup, but it is regenerated at every restart and not shared across instances — for production, always set an explicit value (for example via the BABEL_SERVICE_APPLICATION__SIGNINGKEY environment variable).\nTo save the changes and exit Nano, press Ctrl + X, then press Y to confirm the changes, and finally, press Enter to save the file.\nBy following these steps, you will have successfully configured the Babel Service by editing the appsettings.json file. The updated configuration will include the correct database connection settings and any other customizations you have made.\nTo learn more about the Babel Licensing Service configuration file, please refer to the Configuration paragraph.\nCreate the database"},{"page":103,"heading":"Setup Files","anchor":"setup-files","text":"We need to create the \"licenses\" database configured in the connection string we set for Babel Licensing Service. Then create the \"babel\" user, grant privileges to the database, and verify the user's permissions.\nOpen a terminal.\nLog in to the MariaDB console as the root user using the following command:\nsudo mariadb -u root -p\nYou will be prompted to enter the root password.\nOnce you are logged in to the MariaDB console, you can list all existing databases by running the command:\nSHOW DATABASES;\nTo list all existing users, execute the following query:\nSELECT User FROM mysql.user;\nCreate the \"licenses\" database using the command:\nCREATE DATABASE licenses;\nCreate the \"babel\" user and grant all privileges to the \"licenses\" database by executing the following commands:\nCREATE USER babel@localhost IDENTIFIED BY 'YourUniquePassword';\nGRANT ALL PRIVILEGES ON licenses.* TO babel@localhost;\nFLUSH PRIVILEGES;\nReplace 'YourUniquePassword' with the password you set for the Babel Licensing Service MySQL connection string.\nTo verify that the \"babel\" user has the appropriate permissions, you can use the following statement:\nSHOW GRANTS FOR babel@localhost;\nYou can now exit the MariaDB console by typing the command quit then ENTER.\nBy following these steps, you will have successfully created the \"licenses\" database, created the \"babel\" user, granted privileges to the database, and verified the user's permissions."},{"page":103,"heading":"Start Babel Licensing Service","anchor":"start-babel-licensing-service","text":"To start the Babel Licensing Service, follow these steps:\nOpen a terminal\nOpen a terminal window.\nNavigate to the service directory\nNavigate to the directory where the Babel Licensing Service is located. For example:\ncd /var/www/svc/babel\nRun the service\nRun the following command to start the Babel Licensing Service:\ndotnet Babel.Licensing.Service.dll\nIf everything is configured correctly, you will see the service starting up. The terminal log will display information about the service initialization, including the creation of tables in the database, depending on the log level you choose in the appsettings.json file.\nKeep an eye on the terminal log for any errors or warnings. If there are any issues, make sure to review the configuration, database connection settings, and permissions to ensure they are set up correctly.\nIf the Babel Licensing Service starts successfully, it will be ready to handle licensing operations and provide licensing services to your applications.\nInfo: It is recommended to run the Babel Licensing Service as a background process or set up a service manager to ensure it continues running even after closing the terminal."},{"page":103,"heading":"Configure As Background Process","anchor":"configure-as-background-process","text":"In Linux, service files, also known as service unit files, are configuration files with a \".service\" extension that are used to control the behaviour of daemons or services. These files define various settings and parameters related to the service, such as its name, description, execution command, working directory, environment variables, and more.\nTo configure the Babel Licensing Service as a system service in Linux, follow these steps:"},{"page":103,"heading":"Configure As Background Process","anchor":"configure-as-background-process","text":"Open the service file\nOpen a terminal and run the following command to create and edit the service file:\nsudo nano /etc/systemd/system/babel.licensing.service\nPaste the service configuration\nPaste the following configuration into the file:\n[Unit]\nDescription=Babel Licensing Service\n\n[Service]\nWorkingDirectory=/var/www/svc/babel/\nExecStart=/usr/bin/dotnet /var/www/svc/babel/Babel.Licensing.Service.dll\nRestart=always\nRestartSec=10\nKillSignal=SIGINT\nSyslogIdentifier=babel-licensing-svc\nUser=www-data\nEnvironment=ASPNETCORE_ENVIRONMENT=Production\nEnvironment=DOTNET_PRINT_TELEMETRY_MESSAGE=false\n\n[Install]\nWantedBy=multi-user.target\nSave the service file\nSave the file by pressing Ctrl+O, then exit the editor by pressing Ctrl+X.\nStart the service\nStart the Babel Licensing Service by running the following command:\nsudo systemctl start babel.licensing\nCheck the service status\nTo check the status of the service, use the following command:\nsystemctl status babel.licensing\nThis command will display the current status of the service, including any error messages or warnings:\n● babel.service - Babel Licensing Service\n     Loaded: loaded (/etc/systemd/system/babel.licensing.service; disabled; vendor preset: enabled)\n     Active: active (running) since Fri 2023-05-19 09:24:53 UTC; 1s ago\n   Main PID: 2710499 (dotnet)\n      Tasks: 17 (limit: 4392)\n     Memory: 28.0M\n        CPU: 903ms\n     CGroup: /system.slice/babel.licensing"},{"page":103,"heading":"Configure As Background Process","anchor":"configure-as-background-process","text":"             └─2710499 /usr/bin/dotnet /var/www/svc/babel/Babel.Licensing.Service.dll\n\nMay 19 09:24:57 babel-licensing-svc[2710499]: [09:24:57 DBG] Hosting started\nEnable automatic startup\nBy default, the service is not set to start automatically when the server is started. To enable the service to start automatically, run the following command:\nsudo systemctl enable babel.licensing\nEnabling the service ensures that it will start automatically after the server is rebooted.\nWith these steps, you have configured the Babel Licensing Service as a systemd service in Linux. The service will start automatically upon system boot and can be managed using the systemctl command."},{"page":104,"heading":"","anchor":"","text":"Docker is a convenient and efficient method to run the Babel Licensing Service for testing purposes. Docker provides a lightweight and isolated environment called a container, which encapsulates the Babel Licensing Service and all its dependencies, making it easy to deploy and test the service on various systems without worrying about compatibility issues or conflicts with the host environment."},{"page":104,"heading":"Prerequisites","anchor":"prerequisites-","text":"Docker Desktop\nBabel Licensing Service ZIP package (babel_service_net80_x.y.z.w.zip), one package for both editions\nBabel Licensing Server or Data Center license file (babel.licenses)\nInfo: Docker must be installed before you start. Download it from the official Docker website and follow the installation instructions for your operating system.\nThe steps below install the Babel Licensing Service on Docker."},{"page":104,"heading":"Create the Dockerfile","anchor":"create-the-dockerfile","text":"To prepare the environment for building the Babel Licensing Service image using Docker, follow the steps below.\nCreate a working folder\nCreate a folder on your local machine for the Babel Licensing Service files. This guide calls it the \"working folder\".\nCopy the service files\nCopy the Babel Licensing Service ZIP archive and the babel.licenses file into the working folder created in the previous step.\nExtract the archive\nExtract the contents of the Babel Licensing Service ZIP archive into a subfolder titled \"babel\" within the working folder.\nCreate the Dockerfile\nIn the working folder, create a new file named \"Dockerfile\" with any text editor or IDE.\nAdd the Dockerfile content\nCopy the following content into the \"Dockerfile\" file and save it.\nFROM mcr.microsoft.com/dotnet/aspnet:8.0 as runtime\n\n# Expose service ports\nEXPOSE 5005\n\n# Set working directory\nWORKDIR /var/www/babel-lic\n\n# Copy babel licensing service files to working directory\nCOPY /babel .\n\n# Copy license file to working directory\nCOPY /babel.licenses .\n\n# Set entrypoint\nENTRYPOINT [ \"dotnet\", \"Babel.Licensing.Service.dll\" ]\nLet's break down its contents:\nFROM mcr.microsoft.com/dotnet/aspnet:8.0 as runtime\nThis line specifies the base image for the Docker container. In this case, it is using the ASP.NET runtime image from Microsoft's Container Registry.\nEXPOSE 5005\nThe EXPOSE instruction specifies that the container exposes this port to the host machine, allowing external access.\nWORKDIR /var/www/svc/babel"},{"page":104,"heading":"Create the Dockerfile","anchor":"create-the-dockerfile","text":"The WORKDIR instruction sets the working directory inside the container to /var/www/svc/babel. This is the location where subsequent commands will be executed.\nCOPY /babel .\nThis line copies the contents of the babel directory (containing the Babel Licensing Service files) from the babel working folder directory into the container's working directory /var/www/svc/babel.\nCOPY /babel.licenses .\nSimilarly, this line copies the babel.licenses file from the build context into the container's working directory.\nENTRYPOINT [ \"dotnet\", \"Babel.Licensing.Service.dll\" ]\nThe ENTRYPOINT instruction specifies the command that will be executed when the container starts. In this case, it is running the dotnet command with the Babel.Licensing.Service.dll as the entry point for the Babel Licensing Service.\nThis Dockerfile sets up the necessary environment, exposes the required port, copies the service files and license file, and defines the entry point for the Babel Licensing Service.\nOnce built using Docker, this image can be used in conjunction with Docker Compose to deploy the Babel Licensing Service."},{"page":104,"heading":"Docker Compose","anchor":"docker-compose--","text":"So far, we have instructed Docker to build the image that runs the Babel Licensing Service, but we have not instructed the configuration to actually startup any database.\nTo configure the complete setup for the Babel Licensing Service, including the necessary database, we will create a new file named docker-compose.yml in the working folder. Add the following content to the docker-compose.yml file:"},{"page":104,"heading":"Docker Compose","anchor":"docker-compose--","text":"version: '3.7'\n\nservices:\n  # Database\n  db:\n    image: mysql:latest\n    volumes:\n      - type: volume\n        source: dbdata\n        target: /var/lib/mysql\n    restart: always \n    ports:\n      - '6610:3306'\n    environment:\n      MYSQL_ROOT_PASSWORD: eWk4fSTa45PGpJ\n      MYSQL_DATABASE: licenses\n      MYSQL_USER: babel\n      MYSQL_PASSWORD: babel\n    networks:\n      - babellic\n  # Babel Licensing\n  licensing:\n    depends_on:\n      - db\n    container_name: babel-licensing\n    restart: always\n    build:\n      dockerfile: Dockerfile\n      context: .\n    image: babel/licensing:latest\n    ports:\n      - '5005:5005'\n    environment:\n      DOTNET_CLI_HOME: /tmp\n\n      # Environment\n      ASPNETCORE_ENVIRONMENT: Production\n\n      # Service Address\n      KESTREL__ENDPOINTS__GRPC__URL: http://*:5005\n\n      # Available database providers: SQLServer, MySQL, SQLite\n      BABEL_SERVICE_DATABASE__PROVIDER: MySQL\n\n      # Connection strings environment variables\n      # SQL Server: BABEL_SERVICE_CONNECTIONSTRINGS__SQLSERVER\n      # MySQL: BABEL_SERVICE_CONNECTIONSTRINGS__MYSQL\n      # SQLite: BABEL_SERVICE_CONNECTIONSTRINGS__SQLITE\n      BABEL_SERVICE_CONNECTIONSTRINGS__MYSQL: Server=db;User=babel;Password=babel;Database=licenses\n\n      # Authentication token variables\n      BABEL_SERVICE_APPLICATION__SIGNINGKEY: q9F0nLFRuphIHUdrlphe\n      BABEL_SERVICE_APPLICATION__TOKENEXPIRATION: 00:30:00\n\n      # Licensing variables\n      BABEL_SERVICE_LICENSING__HEARTBEATINTERVAL: 00:05:00\n"},{"page":104,"heading":"Docker Compose","anchor":"docker-compose--","text":"      # Reporting variables\n      BABEL_SERVICE_REPORTING__ENCRYPTIONKEY: p5UwIWaqaChLxe3eJA9o\n      \n    networks:\n      - babellic\nnetworks:\n  babellic:\nvolumes:\n  dbdata:\n  licensing:\nThe docker-compose.yml file defines an application with two services: licensing and db. The image for the licensing service is built using the specified Dockerfile.\nWhen deploying the application using Docker Compose, the container port 5005 is mapped to the host port 5005, as indicated in the file. Please ensure that the port 5005 on the host machine is not being used by another container. If it is, you can modify the port to an available one.\nInfo: Remember to replace the MySQL root and user passwords with strong and secure passwords (you don't need to remember them) under the db service and inside the Babel Service Connection string. The user password is used to set up the connection with the MySQL database.\nThe docker-compose.yml file is responsible for defining how the Docker images interact with each other at runtime. It specifies the necessary configurations, environment variables, and network setup for the services. By using Docker Compose with this file, you can easily deploy and manage the Babel Licensing Service along with the associated database."},{"page":104,"heading":"Starting the Service","anchor":"starting-the-service","text":"After setting up the docker-compose.yml file as described in the previous paragraph, you can proceed to run the command:\ndocker-compose up -d\nThis command will start the Babel Licensing Service and the associated database in detached mode. Wait for the containers to start: Docker Compose will start pulling the required images (if not already present) and create the containers based on the configurations specified in the docker-compose.yml file. It may take a few moments for the containers to be fully up and running.\nAfter running the command, you can use the docker ps command to verify that the containers are running. It will display a list of running containers along with their details, including the Babel Licensing Service and the associated database container.\n$ docker ps\nCONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                               NAMES\n5d2d3fc62f0a   babel/licensing:latest   \"dotnet Babel.Licens…\"   25 seconds ago   Up 23 seconds   0.0.0.0:5005->5005/tcp              babel-licensing\n0e4245f683cf   mysql:latest             \"docker-entrypoint.s…\"   25 seconds ago   Up 24 seconds   33060/tcp, 0.0.0.0:6610->3306/tcp   babel-licesing-db-1"},{"page":104,"heading":"Starting the Service","anchor":"starting-the-service","text":"Info: The license file sets the edition. With a Data Center license the web application is served at the service address. With a Server license that address shows an upgrade page with an edition comparison; the service, its API and Babel Desktop keep working. To upgrade, replace babel.licenses and restart the container; there is nothing to reinstall."},{"page":104,"heading":"Stopping the Service","anchor":"stopping-the-service","text":"To stop and remove the containers, as well as delete the associated volumes, you can use the following commands:\nStop and Remove Containers: To stop and remove the containers that were created using Docker Compose, execute the following command:\n$ docker compose down\nThe down command halts and removes the containers defined in the docker-compose.yml file. It stops the running containers and removes their associated resources, such as networks and volumes while preserving the images.\nStop and Delete Volumes: If you also want to delete the volumes associated with the containers, you can use the -v flag with the down command. Run the following command:\n$ docker compose down -v\nAdding the -v flag instructs Docker Compose not only to stop and remove the containers but also to delete the volumes that were created during the container lifecycle. This ensures the clean removal of all resources related to the containers including the database data files.\nPlease note that when executing these commands, it is important to be in the same directory where the docker-compose.yml file is located. Additionally, make sure you have Docker Compose installed and available in your command-line environment.\nBy running docker compose down or docker compose down -v, you will effectively stop and remove the containers, as well as delete the associated volumes, cleaning up the resources used by the Babel Licensing Service."},{"page":104,"heading":"Configure Babel Licensing Service","anchor":"configure-babel-licensing-service","text":"The docker-compose.yml file allows you to configure the environment for the babel-licensing service container by specifying several environment variables. These variables override the default configuration settings of the Babel Licensing Service, which are stored in the appsettings.json file. Here is an expanded description of the available configuration variables:"},{"page":104,"heading":"Configure Babel Licensing Service","anchor":"configure-babel-licensing-service","text":"DOTNET_CLI_HOME: Specifies the location of the CLI (Command Line Interface) temporary directory for .NET. In this case, it is set to /tmp.\nASPNETCORE_ENVIRONMENT: Sets the environment for the Babel Licensing Service to run in. The value Production indicates that the service is running in a production environment.\nKESTREL__ENDPOINTS__GRPC__URL: Defines the URL for the gRPC endpoint of the Babel Licensing Service. In this case, it is set to http://*:5005, indicating that the service listens on all available network interfaces on port 5005.\nBABEL_SERVICE_DATABASE__PROVIDER: Specifies the database provider to be used by the Babel Licensing Service. The value MySQL indicates that MySQL will be used as the database provider.\nBABEL_SERVICE_CONNECTIONSTRINGS__MYSQL: Sets the connection string for the MySQL database. It specifies the server, user, password, and database name to be used by the Babel Licensing Service. The MySQL provider also works on the .NET 10 image (mcr.microsoft.com/dotnet/aspnet:10.0 with the babel_service_net100_x.y.z.w.zip package), where the service uses the Pomelo fork Microting.EntityFrameworkCore.MySql, with the same environment variables."},{"page":104,"heading":"Configure Babel Licensing Service","anchor":"configure-babel-licensing-service","text":"BABEL_SERVICE_APPLICATION__SIGNINGKEY: Defines the signing key used for generating and validating authentication tokens for the Babel Licensing Service. Since 11.7.0 the bundled appsettings.json no longer contains a hardcoded value: if SigningKey is empty at startup the service generates a random one for the current process (and logs a warning). For any non-development deployment — and especially when running multiple replicas behind a load balancer — always set this variable to an explicit, persistent secret so issued tokens survive restarts and are accepted across instances.\nBABEL_SERVICE_APPLICATION__TOKENEXPIRATION: Sets the expiration time for authentication tokens issued by the Babel Licensing Service.\nWarning: Initial administrator (since 11.7.0) — the service no longer ships with admin / admin default credentials. To provision the initial administrator on first start, set BABEL_SERVICE_APPLICATION__ADMINUSERNAME and BABEL_SERVICE_APPLICATION__ADMINPASSWORD (and optionally BABEL_SERVICE_APPLICATION__ADMINEMAIL). The container starts even when these are missing, but no admin user is created, so the Web Application (Data Center) cannot sign in with that account and Babel Desktop has no administrator API key to connect with, until both required values are set and the container is restarted. These values are consumed only on first start; rotate the password through the Web Application afterwards and clear ADMINPASSWORD from your environment."},{"page":104,"heading":"Configure Babel Licensing Service","anchor":"configure-babel-licensing-service","text":"BABEL_SERVICE_LICENSING__HEARTBEATINTERVAL: Specifies the maximum interval at which the clients must send heartbeats to the Babel Licensing Service. The format is hh:mm:ss, indicating the time interval between each heartbeat.\nBABEL_SERVICE_REPORTING__ENCRYPTIONKEY: Defines the encryption key used for encrypting data in the reporting functionality of the Babel Licensing Service.\nThese environment variables allow you to customize and configure various aspects of the Babel Licensing Service according to your specific requirements. By overriding these variables in the docker-compose.yml file, you can modify the service's behaviour without modifying the original appsettings.json file, providing flexibility and ease of configuration."},{"page":104,"heading":"MSSQL Server Docker Image","anchor":"mssql-server-docker-image","text":"To configure Babel Licensing with MSSQL in Docker, the setup utilizes the latest Azure SQL Edge image, which is compatible with Linux Ubuntu. The YAML configuration provided outlines key environment variables essential for database access, authentication tokens, and licensing parameters. This approach streamlines the deployment and integration of Babel Licensing with an MSSQL database within a Docker environment."},{"page":104,"heading":"MSSQL Server Docker Image","anchor":"mssql-server-docker-image","text":"version: '3.7'\n\nservices:\n  # Database\n  ms-sql-server:\n    image: mcr.microsoft.com/azure-sql-edge:latest\n    volumes:\n      - events_mssql:/var/opt/mssql\n    restart: always \n    ports:\n      - '1433:1433'\n    environment:\n      MSSQL_SA_PASSWORD: eWk4fSTa45PGpJ\n      ACCEPT_EULA: Y\n      DATABASE: licenses\n    networks:\n      - babellic\n  # Babel Licensing\n  licensing:\n    depends_on:\n      - ms-sql-server\n    container_name: babel-licensing-mssql\n    restart: always\n    build:\n      dockerfile: Dockerfile\n      context: .\n    image: babel/licensing:latest\n    ports:\n      - '5005:5005'\n    volumes: \n      - type: bind\n        source: ./babel\n        target: /var/www/babel-lic\n    environment:\n      DOTNET_CLI_HOME: /tmp\n\n      # Environment\n      ASPNETCORE_ENVIRONMENT: Production\n\n      # Service Address\n      KESTREL__ENDPOINTS__GRPC__URL: http://*:5005\n\n      # Available database providers: SQLServer, MySQL, SQLite\n      BABEL_SERVICE_DATABASE__PROVIDER: SQLServer\n\n      # Connection strings environment variables\n      # SQL Server: BABEL_SERVICE_CONNECTIONSTRINGS__SQLSERVER\n      # MySQL: BABEL_SERVICE_CONNECTIONSTRINGS__MYSQL\n      # SQLite: BABEL_SERVICE_CONNECTIONSTRINGS__SQLITE\n      BABEL_SERVICE_CONNECTIONSTRINGS__SQLSERVER: data source=ms-sql-server;user id=sa;password=eWk4fSTa45PGpJ;initial catalog=licenses;trusted_connection=false;encrypt=false\n\n      # Authentication token variables\n      BABEL_SERVICE_APPLICATION__LOGTODATABASE: true"},{"page":104,"heading":"MSSQL Server Docker Image","anchor":"mssql-server-docker-image","text":"      BABEL_SERVICE_APPLICATION__SIGNINGKEY: q9F0nLFRuphIHUdrlphe\n      BABEL_SERVICE_APPLICATION__TOKENEXPIRATION: 00:30:00\n\n      # Licensing variables\n      BABEL_SERVICE_LICENSING__HEARTBEATINTERVAL: 00:05:00\n\n      # Reporting variables\n      BABEL_SERVICE_REPORTING__ENCRYPTIONKEY: p5UwIWaqaChLxe3eJA9o\n      \n    networks:\n      - babellic\nnetworks:\n  babellic:\nvolumes:\n  events_mssql:\n  licensing:\nBy using Docker, you can quickly set up an instance of the Babel Licensing Service without having to manually configure and install all the required dependencies on your local machine or server. This means you can avoid potential conflicts with existing software versions or dependencies, streamlining the setup process and saving time.\nWarning: Running on a FIPS-enabled host? If the container runs on a host with\nFIPS mode enabled and the base image does not ship a certified OpenSSL\nFIPS provider, the service can fail to start with an\nOpenSslCryptographicException: error:03000086. See\nFIPS Compliance for the cause and how to\nresolve it (typically OPENSSL_FORCE_FIPS_MODE=0 or a FIPS-capable base\nimage)."},{"page":105,"heading":"","anchor":"","text":"To add Babel Licensing to your .NET applications and components, you need to install the Babel Licensing client components. They include the Babel Licensing NuGet package and the Babel Data NuGet package, which you reference from your projects to add licensing features. This page explains how to install the client components and what each one does."},{"page":105,"heading":"Babel NuGet Packages","anchor":"babel-nuget-packages","text":"Babel Licensing (Server and Data Center editions) is distributed with the following NuGet packages:\nPackage | Description\nBabel.Licensing.Tool.x.y.z.nupkg | Babel Licensing dotnet CLI tool\nBabel.Licensing.x.y.z.nupkg | Babel Licensing client library\nBabel.Data.x.y.z.nupkg | Babel Licensing Database components\nThese NuGet packages are not available on the public NuGet repository. To use them in your projects, you need to install them on your private NuGet feeds or your local machine.\nUserKey Authentication over gRPC\nWarning: If your application authenticates with a License UserKey over the gRPC transport (the default for most client applications), update Babel.Licensing to the current package version. Versions prior to this fix send an internal client identifier as the login username instead of leaving it empty, which a Babel Licensing Service running 11.7.0 or later rejects with \"Invalid username or password\" — for both existing and newly generated UserKeys. The HTTP transport is not affected.\nIf you have many deployed applications and cannot update and redistribute them all right away, the Babel Licensing Service can be temporarily configured to accept the older client behavior. See EnableLegacyUserKeyFallback in Configuration > Application.\nThere are several NuGet private feeds available:\nAzure Artifacts\nGitHub Package Registry\nGitLab Package Registry\nMyGet\nTeamCity\nGitea (Open Source)\nNuGet Server (Open Source)"},{"page":105,"heading":"Babel NuGet Packages","anchor":"babel-nuget-packages","text":"If you don't have a private NuGet feed, you can create one on your local machine.\nInfo: Regardless your packages are hosted on a server or your local machine, you can access them using the nuget CLI tool or Visual Studio."},{"page":105,"heading":"Create a Local NuGet Feed Using dotnet","anchor":"create-a-local-nuget-feed-using-dotnet-","text":"If you have installed Visual Studio or dotnet SDK, you can access NuGet directly from the dotnet CLI tool. Now you have to decide where to store your packages on your local machine. For this example, we will create the folder NuGet under the user Documents folder. If you are on Linux or Mac OS, you can create the folder under the user home directory ~/NuGet.\nYou can add the packages to your local feed using dotnet nuget add command.\nWindows PowerShell or DOS shell:\ndotnet nuget add Babel.Licensing.Tool.10.0.0.nupkg -Source %UserProfile%\\Documents\\NuGet\nLinux or Mac OS:\ndotnet nuget add Babel.Licensing.Tool.10.0.0.nupkg -Source ~/NuGet\nThe dotnet tool should report that the package was successfully added, and you can now access your packages through the dotnet command."},{"page":105,"heading":"Create a Local NuGet Feed Using Visual Studio","anchor":"create-a-local-nuget-feed-using-visual-studio","text":"To install the NuGet package in your local machine, follow these steps:\nOpen the package sources settings\nOpen Visual Studio and from the Tools menu select Options. In the Options panel, search for NuGet and select the Package Sources node under the NuGet Package Manager tree item.\n\nVisual Studio Options Package Sources\nAdd the Babel package source\nPress the button with the plus icon and enter the Name field Babel and the Source field the full path to the folder containing the Babel NuGet package files. Press the OK button.\nInstall the Babel.Licensing package\nTo reference Babel.Licensing NuGet package, in the Solution Explorer, right-click your project file. Select Manage NuGet Packages…\nSelect your newly added Babel package source in the Package source combo box, then Install the Babel.Licensing package.\n\nVisual Studio NuGet package manager\nCopy the license file and rebuild\nCopy your license file babel.licenses in the solution folder and rebuild the solution."},{"page":105,"heading":"Installing Babel Licensing Lic CLI Tool","anchor":"installing-babel-licensing-lic-cli-tool","text":"Once the Babel NuGet packages are in your local NuGet repository, you can install the CLI tools using dotnet tool install command.\nInstall the babel CLI tool\nInstall Babel Obfuscator CLI tool babel:\ndotnet tool install Babel.Obfuscator.Tool -g\nInstall the lic CLI tool\nInstall Babel Licensing CLI tool lic:\ndotnet tool install Babel.Licensing.Tool -g\nList the installed tools\nTo show the versions of the dotnet tool installed, use the following command:\ndotnet tool list -g\n\nPackage Id                 Version      Commands\n------------------------------------------------\nbabel.licensing.tool       10.0.0       lic     \nbabel.obfuscator.tool      10.0.0       babel"},{"page":106,"heading":"","anchor":"","text":"Babel Licensing Service serves as a comprehensive and robust licensing solution designed specifically for .NET applications. It provides a wide range of functionalities aimed at managing software licenses effectively. The primary purpose of Babel Licensing Service is to protect the intellectual property of software developers by ensuring that their applications and components are licensed and used in compliance with the specified terms.\nWith Babel Licensing Service, developers can implement secure licensing mechanisms for their .NET Framework components and applications. It utilizes asymmetric cryptographic algorithms to guarantee the integrity and authenticity of software licenses. By digitally signing the licenses, Babel Licensing Service prevents unauthorized tampering and ensures that only valid and genuine licenses are accepted.\nOne of the key functionalities of Babel Licensing Service is its integration with Babel Obfuscator. This integration provides an added layer of protection by incorporating top-notch obfuscation techniques. By obfuscating the code, Babel Licensing Service makes it more challenging for unauthorized users to reverse-engineer or understand the underlying implementation of the licensed software."},{"page":106,"heading":"","anchor":"","text":"Moreover, Babel Licensing Service offers a flexible licensing model that caters to different licensing scenarios. Developers can create trial licenses to allow users to evaluate their software before purchasing, hardware-locked licenses to tie the license to specific hardware and feature-based licenses to enable or disable specific features based on license entitlements.\nBy utilizing Babel Licensing Service, developers can seamlessly integrate licensing capabilities into their applications or software components. It has minimal impact on deployment and can be easily integrated into existing projects. Additionally, Babel Licensing Service provides a set of client libraries, such as Babel.Licensing NuGet package, that enables straightforward interaction with the licensing system, allowing developers to implement license validation and enforcement within their applications.\nIn summary, Babel Licensing Service offers a powerful solution for licensing .NET applications, providing robust protection for intellectual property, flexible licensing models, and seamless integration capabilities. With its advanced cryptographic algorithms, integration with obfuscation techniques, and easy-to-use client libraries, Babel Licensing Service empowers software developers to safeguard their applications and enforce proper license usage."},{"page":107,"heading":"","anchor":"","text":"The configuration of Babel Licensing services is an essential aspect of setting up a secure and reliable licensing infrastructure. One key element of this configuration is the appsettings.json file, which allows you to define various parameters and settings for the Babel Licensing service.\nThe appsettings.json configuration file for Babel Licensing Service contains various settings for the application. Here is a breakdown of the different sections:"},{"page":107,"heading":"","anchor":"","text":"Serilog: This section configures the logging settings using the Serilog library. It specifies the sinks for logging (console and file), log levels for different namespaces, and enrichers for additional contextual information.\nAllowedHosts: Used for host filtering to bind your app to specific hostnames.\nKestrel: This section configures the Kestrel web server settings. It defines the default protocols and endpoints for the gRPC service.\nApplication: This section includes settings specific to the Babel Licensing Service application. It specifies whether gRPC-Web is enabled, the path to the license file, the signing key for license validation, and the token expiration duration.\nEmail: These settings configure email notifications. It includes options to enable or disable sending emails, SMTP server details (host, port, SSL), authentication credentials, and sender/receiver information.\nLicensing: This section configures various aspects of the licensing system. It specifies the heartbeat interval, token formats for activation and floating licenses.\nReporting: This section configures the reporting service and includes the encryption key used for report generation.\nDatabase: This section specifies the database provider used by the application.\nConnectionStrings: These settings define the connection strings for different database providers (SQL Server, MySQL/MariaDB, SQLite, PostgreSQL)."},{"page":107,"heading":"","anchor":"","text":"Each section can be customized according to the specific requirements of the Babel Licensing Service deployment."},{"page":107,"heading":"Serilog","anchor":"serilog","text":"Serilog is used for logging purposes within the Babel Licensing service. Let's take a closer look at how the Serilog configuration is set up in the appsettings.json file.\n\"Serilog\": {\n  \"Using\": [ \"Serilog.Sinks.Console\", \"Serilog.Sinks.File\" ],\n  \"MinimumLevel\": {\n    \"Default\": \"Information\",\n    \"Override\": {\n      \"Microsoft\": \"Warning\",\n      \"System\": \"Warning\",\n      \"Grpc\": \"Warning\"\n    }\n  },\n  \"Enrich\": [\n    \"FromLogContext\",\n    \"WithMachineName\",\n    \"WithThreadId\"\n  ],\n  \"WriteTo\": [\n    { \"Name\": \"Console\" },\n    {\n      \"Name\": \"File\",\n      \"Args\": {\n        \"path\": \"log.txt\",\n        \"rollingInterval\": \"Day\"\n      }\n    }\n  ]\n}\nFirst, we define the \"Serilog\" section, which contains several key elements.\nUsing: This property specifies the Serilog sinks that will be utilized for logging. In this example, we have \"Serilog.Sinks.Console\" and \"Serilog.Sinks.File\", indicating that logs will be written to both the console and a file.\nMinimumLevel: Defines the minimum logging level for different log sources. The Default value is set to \"Information\", meaning that all logs at the Information level or above will be captured. Additionally, there is an Override section that specifies specific logging levels for certain namespaces. The available log levels are:"},{"page":107,"heading":"Serilog","anchor":"serilog","text":"Verbose: Verbose is the noisiest level, rarely (if ever) enabled in production.\nDebug: Debug is used for internal system events that are not necessarily observable from the outside but useful when determining how something happened\nInformation: Information events describe things in the system that correspond to its responsibilities and functions. Generally used to log GRPC calls.\nWarning: When service is degraded, endangered, or maybe behaving outside of its expected parameters, Warning level events are used.\nError: An Error event is used when functionality is unavailable or expectations are broken.\nFatal: The most critical level, Fatal events demand immediate attention.\nEnrich: This property allows enriching log events with additional information. In this example, log events will be enriched with information such as the log context, machine name, and thread ID.\nWriteTo: The WriteTo property defines the sinks to which the log events will be written. We have two sinks configured: \"Console\" and \"File\". The \"Console\" sink writes the log events to the console. The \"File\" sink is configured with the \"path\" property set to \"log.txt\", indicating that log events will be written to a file named log.txt. Additionally, the \"rollingInterval\" is set to \"Day\", which means that a new log file will be created each day."},{"page":107,"heading":"Serilog","anchor":"serilog","text":"For more specific settings and advanced configurations related to filtering, sub-loggers, and other features offered by Serilog, it is recommended to refer to the official Serilog documentation. The Serilog documentation provides detailed information on various configuration options, including log event filtering, enriching, and configuring sub-loggers."},{"page":107,"heading":"AllowedHosts","anchor":"allowedhosts","text":"The \"AllowedHosts\" configuration in the appsettings.json file is used to specify the hosts filtering for Babel Licensing Service. It is an important security measure to restrict access to the service only from trusted URLs. The value \"*\" indicates that host filtering is disabled and any URLs that bind to the host can access the service, which can be appropriate for development or testing environments. However, in production, it is recommended to specify the hosts explicitly.\nHere are a few examples of how you can configure the \"AllowedHosts\" setting:\nAllowing a specific host:\n\"AllowedHosts\": \"example.com\"\nThis configuration restricts access to the Babel Licensing service only for requests made to the \"example.com\" domain. All other requests to other hosts will return a 400 response, stating the hostname is invalid.\nAllowing multiple hosts:\n\"AllowedHosts\": \"example.com;subdomain.example.com\"\nThis configuration allows access to the Babel Licensing service from \"example.com\", and \"subdomain.example.com\" only. Requests from any other domain will be denied.\nAllowing multiple hosts using wildcard expression:\n\"AllowedHosts\": \"*.example.com\"\nThis configuration allows access to the Babel Licensing service from any subdomain of \"example.com\". For example, \"subdomain.example.com\" and \"another.subdomain.example.com\" will be allowed, but requests from other domains or subdomains will be rejected."},{"page":107,"heading":"AllowedHosts","anchor":"allowedhosts","text":"It is important to carefully consider and configure the \"AllowedHosts\" setting based on your specific deployment environment and security requirements. By restricting access to trusted hosts, you can enhance the security and integrity of your Babel Licensing service."},{"page":107,"heading":"Kestrel","anchor":"kestrel","text":"The \"Kestrel\" configuration section in the appsettings.json file is used to configure the Kestrel web server, which is used to host the Babel Licensing Service. Kestrel is a cross-platform web server that provides a fast and reliable hosting environment for your application.\n\"Kestrel\": {\n  \"EndpointDefaults\": {\n    \"Protocols\": \"Http1AndHttp2\"\n  },\n  \"Endpoints\": {\n    \"gRPC\": {\n      \"Url\": \"http://localhost:5005\",\n      \"Protocols\": \"Http2\"\n    }\n  }\n}\nWithin the \"Kestrel\" section, you can define various settings to customize the behaviour of the server. Let's explore some key elements of the Kestrel configuration:\nEndpointDefaults: This subsection allows you to set default configurations for all endpoints. Here, you can specify the protocols supported by the server. In the example provided, \"Http1AndHttp2\" indicates that both HTTP/1.1 and HTTP/2 protocols are enabled by default.\nEndpoints: This subsection allows you to define specific endpoints for the server. In the given example, the \"gRPC\" endpoint is configured with the URL \"http://localhost:5005\" and the \"Http2\" protocol. This endpoint is specifically designed to handle gRPC requests made to Babel Licensing Service using the HTTP/2 protocol.\nConfiguring Kestrel correctly is essential for ensuring the smooth operation of your Babel Licensing Service. You can customize various aspects such as protocols, port numbers, SSL certificates, and more to meet your specific requirements."},{"page":107,"heading":"Kestrel","anchor":"kestrel","text":"It is important to refer to the official documentation and follow best practices when configuring Kestrel to ensure optimal performance, security, and reliability."},{"page":107,"heading":"Application","anchor":"application","text":"The \"Application\" configuration section in appsettings.json allows you to customize various aspects of the Babel Licensing service. Let's explore each setting in detail:\n\"Application\": {\n    \"AdminUsername\": \"\",\n    \"AdminEmail\": \"\",\n    \"AdminPassword\": \"\",\n    \"EnableLegacyUserKeyFallback\": false,\n    \"EnableGrpcWeb\": true,\n    \"LogToDatabase\": false,\n    \"LogRetentionPeriod\": \"1.00:00:00\",\n    \"LicenseFile\": \"babel.licenses\",\n    \"SigningKey\": \"\",\n    \"TokenExpiration\": \"00:30:00\",\n    \"EnableWebApi\": true,\n    \"EnableWebUI\": true,\n    \"ApiKeyHeaderName\": \"x-api-key\",\n    \"ApiKeyCacheDuration\": \"00:03:00\",\n    \"EnableSwagger\": true,\n    \"SwaggerRoutePrefix\": \"swagger\",\n    \"SwaggerEndpointUrl\": \"/swagger/v1/swagger.json\",\n    \"GeoLocationService\": \"IpApiIs\",\n    \"HealthCheckEndPoint\": \"/health\",\n    \"HealthCheckResponseType\": \"JSON\"\n}\nAdminUsername: With AdminEmail and AdminPassword, these are the credentials used to create the initial administrative user the first time the service starts."},{"page":107,"heading":"Application","anchor":"application","text":"Starting with 11.7.0, the service ships with all three values empty — the historical admin / admin default has been removed. The initial administrator is provisioned only when both AdminUsername and AdminPassword are non-empty (AdminEmail is optional but recommended). If either of the two required values is empty the service still starts and the standard roles are seeded, but no administrator account is created and the Web Application cannot be used until you populate the settings and restart. Use either appsettings.json or the BABEL_SERVICE_APPLICATION__ADMINUSERNAME / ..._ADMINPASSWORD / ..._ADMINEMAIL environment variables, then rotate the password through the Web Application and clear AdminPassword from configuration once the account exists.\nLogToDatabase: Toggles whether logs are stored in a database.\nLogRetentionPeriod: Specifies the duration logs are kept, formatted as days.hours:minutes:seconds.\nEnableGrpcWeb: By setting this value to false, you disable GRPC Web support, which means the server will only accept requests using the HTTP/2 protocol. Note that some client platforms, such as UWP or Unity, may not support HTTP/2, so enabling HTTP/1.1 alongside HTTP/2 ensures compatibility with all client applications. Keep in mind that enabling both protocols on the same port requires TLS for protocol negotiation."},{"page":107,"heading":"Application","anchor":"application","text":"LicenseFile: This setting specifies the path to the license file used by the Babel Licensing service. The license file contains information about the granted licenses and their associated features. The license also selects the edition: a license with the web application feature (Data Center) unlocks the web application included in the package. Other licenses show an upgrade page at the web application address. Replacing the file and restarting the service is enough to upgrade.\nSigningKey: The signing key is a secret used to sign the authentication bearer token. This token is used by clients to access the gRPC service securely. It's essential to keep this key confidential and choose a strong, unique value.\nStarting with 11.7.0, this setting ships empty (the historical hardcoded value has been removed). If SigningKey is empty at startup, the service generates a cryptographically random 32-byte key for the current process and logs a warning. This is convenient for local testing but not suitable for production: every restart invalidates all previously issued tokens, and instances behind a load balancer will reject each other's tokens. Production deployments must explicitly configure SigningKey — either in appsettings.json or via the BABEL_SERVICE_APPLICATION__SIGNINGKEY environment variable — with a strong secret managed outside source control."},{"page":107,"heading":"Application","anchor":"application","text":"Always configure SigningKey — In current builds (up to and including 11.8.0), leaving SigningKey empty does more than invalidate tokens across restarts: the token issued after authentication is not accepted on subsequent calls, so license activation fails with:\nRpcException: Status(StatusCode=\"Unauthenticated\", Detail=\"Bad gRPC response. HTTP status code: 401\")\nThe service log shows a successful authentication (User '' authenticated, token expires in ...) immediately before the 401, which makes the failure look like a client problem. Setting SigningKey to any stable, non-empty value of at least 32 characters resolves it. This will be fixed in a future release; configuring the key explicitly is the correct production setting in any case.\nEnableLegacyUserKeyFallback: Restores authentication compatibility for client applications built against a Babel.Licensing NuGet package older than the version that fixes the gRPC UserKey authentication issue described below. Defaults to false."},{"page":107,"heading":"Application","anchor":"application","text":"UserKey authentication over gRPC — Client applications built against Babel.Licensing versions prior to the fix send an internal client identifier as the login username instead of an empty value when authenticating with a License UserKey. Before 11.7.0 this was silently tolerated by a server-side fallback; the 11.7.0 security hardening removed that fallback (see Client Components), which causes every gRPC UserKey authentication from an affected client — existing or newly generated keys alike — to fail with \"Invalid username or password\". Update to the current Babel.Licensing package to fix this at the source. If you have many deployed client applications and cannot update them all immediately, set EnableLegacyUserKeyFallback to true as a temporary migration bridge: the service will again accept the malformed request, issuing the same roles-less application token an affected client would otherwise get (it grants no roles and cannot reach Management endpoints, so it carries no more privilege than normal UserKey authentication). Set it back to false once every client has been updated. Each time the fallback is used, the service logs a warning identifying the offending username so you can track remaining legacy clients."},{"page":107,"heading":"Application","anchor":"application","text":"TokenExpiration: This setting determines the validity duration of the authentication bearer token acquired by the client. The value \"00:30:00\" indicates a token expiration time of 30 minutes. After this period, the client needs to acquire a new token for further access.\nEnableWebApi: Whether to activates the Web API interface.\nEnableWebUI: Whether the service serves the web application. Set it to false to run the service as API only. The web application also requires a Data Center license.\nApiKeyHeaderName: Designates the HTTP header name for passing the API key.\nApiKeyCacheDuration: Determines how long an API key is stored in cache before it will be validated again.\nEnableSwagger: Turns on/off the Swagger UI for API documentation.\nSwaggerRoutePrefix: The URL segment where the Swagger UI can be accessed.\nSwaggerEndpointUrl: The path to the Swagger JSON file that describes the API.\nGeolocationService: Enables the functionality to determine the geographical location of clients based on their IP addresses, aiding in regional access control. Supported IpApiIs and MaxMind.\nHealthCheckEndPoint: Configures the endpoint path for the health check service. The health check endpoint provides system status information for monitoring tools and load balancers. If not explicitly configured, the system will default to \"/health\"."},{"page":107,"heading":"Application","anchor":"application","text":"HealthCheckResponseType: Controls the format of responses returned by the Babel Licensing Service's health check endpoint. This setting accepts two possible values: \"JSON\" or \"TEXT\".\nBy configuring these settings in the \"Application\" section, you can tailor the behaviour of the Babel Licensing Service according to your requirements, such as enabling or disabling specific protocol support, specifying the license file path, securing authentication with a signing key, and defining the token expiration duration.\nIpApi.is\nThe IpApi.is service enables geolocation by using IP addresses to determine the geographical location of users, which can be crucial for regional access control, logging, and analytics. It offers a quick and reliable way to map IP addresses to their corresponding geographic data.\nFor more information, visit IpApi.is.\nTo configure the IpApiIs service with Babel Licensing Service, follow these steps:\nIn the Application section, set the GeolocationService property to IpApiIs.\nAdd the IpApiIs section to appsettings.json to configure access to the service through a license key.\n\"IpApiIs\": {\n  \"Key\": \"IPAPI.IS WEB API SERVICE LICENSE KEY\"\n}\nMaxMind\nMaxMind offers a robust geolocation service that supports both web API access and local database usage. By integrating MaxMind, users can leverage its high precision in geolocation data. The service, available at MaxMind, allows for quick and reliable IP address information retrieval."},{"page":107,"heading":"Application","anchor":"application","text":"An advantage of using MaxMind's local database is that it eliminates dependency on external API calls, leading to faster query performance and increased reliability, especially in environments with limited or unstable internet connectivity. Additionally, local databases reduce the risks associated with data breaches or external service outages, providing enhanced security and privacy control.\nTo configure the MaxMind geolocation service with Babel Licensing Service, follow these steps:\nIn the Application section, set the GeolocationService property to MaxMind.\nAdd the MaxMind section to appsettings.json with the required configuration options.\n\"MaxMind\": {\n  \"AccountID\": \"MAXMIND ACCOUNT ID\",\n  \"LicenseKey\": \"MAXMIND WEB API SERVICE LICENSE KEY\"\n}\nTo configure the MaxMind database, use the following configuration:\n\"MaxMind\": {\n  \"DatabasePath\": \"wwwroot\\\\data\\\\GeoLite2-City.mmdb\"\n}\nThis setup allows the Babel Licensing Service to utilize MaxMind for geolocation, providing precise and reliable information on IP addresses."},{"page":107,"heading":"IP Filtering","anchor":"ip-filtering","text":"IP Filtering in application settings is a security measure designed to control access to the service based on IP addresses. This section of the configuration ensures that only trusted users can interact with your application, while malicious or unwanted traffic is effectively managed or blocked.\nConfiguration Details:\nBlacklist: An array of IP addresses that are denied access. Blacklisted IPs are always rejected with 403 Forbidden, regardless of any other setting.\nWhitelist: An array of trusted IP addresses that are exempt from brute-force rate limiting. Whitelisted IPs are not subject to the per-IP request quota or to dynamic blocking; they are still subject to the blacklist.\nBehavior change in 11.7.0 — Previous versions treated a non-empty Whitelist as an exclusive allowlist: any IP not present in the whitelist was rejected. Starting with 11.7.0 the whitelist is purely a rate-limit exemption: configuring it no longer blocks non-listed IPs from accessing the service. If you need to deny IPs, list them in the Blacklist (regex patterns are supported).\nBoth lists support pattern matching through regular expressions, which allows for a broader range of IP filtering possibilities.\nBrute Force Protection\nThis sub-section is dedicated to configure countermeasure against brute force attacks:\nEnabled: A boolean that, when true, activates protection against brute force attacks."},{"page":107,"heading":"IP Filtering","anchor":"ip-filtering","text":"MaxRequestsPerTimeFrame: The maximum number of requests allowed from a single IP address within the specified time frame.\nTimeFrameDuration: The period in which the request count is evaluated, formatted as hours:minutes:seconds.\nRequestsBlockDuration: The time that the offending IP address will be blocked after exceeding the maximum number of requests.\nAuthentication Protection\nThis sub-section is related to login attempts:\nEnabled: When true, this enables the monitoring of failed authentication attempts.\nMaxFailedAttempts: The allowed number of consecutive failed login attempts before triggering a block.\nLoginBlockDuration: The duration of the block imposed on the IP after reaching the maximum failed login attempts."},{"page":107,"heading":"Webhook","anchor":"webhook","text":"Webhook settings determine whether webhooks are processed, how frequently the system checks for new events, and how retry attempts are scheduled.\n\"Webhook\": {\n  \"Enabled\": true,\n  \"ProcessingInterval\": \"00:00:30\",\n  \"RetryInterval\": \"00:05:00\"\n}\nProcessing Interval: The default 30-second interval works well for most deployments. Setting this too low could increase database load, while setting it too high might delay webhook delivery.\nRetry Interval: The 5-minute retry interval allows for temporary network issues to resolve while ensuring timely delivery. You might consider increasing this value if your webhook consumers frequently experience longer outages.\nEnabling/Disabling: You can temporarily disable all webhook processing by setting Enabled to false. This can be useful during maintenance windows or when troubleshooting system issues."},{"page":107,"heading":"Email","anchor":"email","text":"The \"Email\" section in the appsettings.json file is responsible for configuring the email settings within the Babel Licensing Service. With this configuration, you can enable email functionality and specify the necessary details for sending emails from the service.\nEnableSend: Specifies whether email sending is enabled or disabled. If set to true, the Babel Licensing Service will attempt to send emails based on the configured settings. If set to false, email sending will be disabled.\nHost: The hostname or IP address of the email server or SMTP (Simple Mail Transfer Protocol) server that will be used to send emails. Enter the appropriate server address.\nPort: The port number that the email server listens on for incoming connections. This is typically the SMTP server port. The default port for SMTP is 587, but you can change it as per your email server configuration.\nUseSsl: Specifies whether SSL/TLS encryption should be used when connecting to the email server. If set to true, the Babel Licensing Service will establish a secure connection using SSL/TLS. If set to false, a non-secure connection will be used.\nLocalDomain: The local domain name used for email addressing. This setting is optional and can be left empty if not required.\nUsername: The username or account name used to authenticate with the email server. Enter the appropriate username.\nPassword: The password associated with the email account. Enter the password corresponding to the provided username for authentication."},{"page":107,"heading":"Email","anchor":"email","text":"FromUser: The display name or username that will be used as the sender of the emails. This can be a friendly name or an actual username.\nFromAddress: The email address from which the emails will be sent. Enter the valid email address for the sender.\nTo: An array of recipient email addresses and names. Each recipient object should contain a \"Name\" field for the recipient's name and an \"Email\" field for the recipient's email address. Add the desired recipient details within the array."},{"page":107,"heading":"Licensing","anchor":"licensing","text":"The \"Licensing\" section in the appsettings.json file is dedicated to configuring various aspects of the licensing functionality within the Babel Licensing Service. This section allows you to define settings related to license management and behaviour.\nWithin the \"Licensing\" section, you can specify parameters such as the heartbeat interval, activation token format, and floating token format. Let's take a closer look at these settings:\n\"Licensing\": {\n  \"HeartbeatInterval\": \"00:05:00\",\n  \"LicenseIdFormat\": \"lic{HEX:8}\",\n  \"CustomerCodeFormat\": \"C-{TOKEN:8}\",\n  \"OrderNumberFormat\": \"O-{TOKEN:8}\",\n  \"UserKeyFormat\": \"{TOKEN:5}-{TOKEN:5}-{TOKEN:5}-{TOKEN:5}\",\n  \"ActivationTokenFormat\": \"actk_{token:12}\",\n  \"FloatingTokenFormat\": \"fltk_{token:12}\",\n  \"ReclaimInactiveActivationDays\": 0\n}\nHeartbeat Interval: This parameter determines the duration between each heartbeat signal sent by the licensing service. The heartbeat signal helps monitor the health and status of the licensing system. A floating token that is not released by its client expires after this interval.\nReclaimInactiveActivationDays: New in 12.0. Number of days without contact after which an activation can be reclaimed when a license has used all its seats and a new machine asks to activate. The default 0 disables the feature. Set it with the BABEL_SERVICE_LICENSING__RECLAIMINACTIVEACTIVATIONDAYS environment variable if you prefer. Read License Tokens before enabling it.\nFormats for Identifiers and Keys"},{"page":107,"heading":"Licensing","anchor":"licensing","text":"The formats specified in the configuration use a combination of placeholders that get replaced with randomly generated values. The TOKEN, HEX, and DEC are types of placeholders, and the number following the colon (:) specifies the length of the generated value. Uppercase (TOKEN, HEX) generates uppercase values, while lowercase (token, hex) generates lowercase values. DEC stands for decimal numbers.\nLicenseIdFormat: \"lic{HEX:8}\" - This format will generate license IDs starting with \"lic\" followed by 8 random uppercase hexadecimal characters.\nCustomerCodeFormat: \"C-{TOKEN:8}\" - Customer codes will start with \"C-\" followed by 8 random uppercase alphanumeric characters.\nOrderNumberFormat: \"O-{TOKEN:8}\" - Order numbers will start with \"O-\" followed by 8 random uppercase alphanumeric characters.\nUserKeyFormat: \"{TOKEN:5}-{TOKEN:5}-{TOKEN:5}-{TOKEN:5}\" - User keys will be generated in a format with four groups of 5 random uppercase alphanumeric characters, separated by hyphens.\nActivation Token Format: This setting defines the format of the activation tokens used in the licensing process. Activation tokens are generated and provided to users to activate their licenses and unlock specific features or functionalities. The default value \"actk_{token:12}\" sets the activation token format as a fixed prefix given by \"actk_\" followed by 12 random characters."},{"page":107,"heading":"Licensing","anchor":"licensing","text":"Floating Token Format: Similar to activation tokens, floating tokens are used for floating licenses, allowing users to share licenses across multiple devices or users within a defined pool. The floating token format specifies the structure of these tokens. The default value \"fltk_{token:12}\" sets the activation token format as a fixed prefix given by \"fltk_\" followed by 12 random characters.\nBy configuring the \"Licensing\" section, you can customize these parameters to align with your specific licensing requirements. This flexibility enables you to tailor the licensing functionality to meet the needs of your application or software."},{"page":107,"heading":"Reporting","anchor":"reporting","text":"The \"Reporting\" section in the appsettings.json file is dedicated to configuring reporting-related settings within the Babel Licensing Service. This section allows you to define parameters related to reporting functionality, including encryption keys for secure transmission and storage of reports.\nWithin the \"Reporting\" section, you can specify settings such as the encryption key. Let's take a closer look at this setting:\n\"Reporting\": {\n  \"EncryptionKey\": \"\"\n}\nEncryption Key: This parameter is used to define the encryption key that is employed to encrypt and decrypt the reports generated by the Babel Licensing Service. By using encryption, the sensitive information contained within the reports remains secure and protected from unauthorized access.\nConfiguring the \"Reporting\" section enables you to define the encryption key, ensuring that the reports generated by the licensing service are encrypted using a strong cryptographic algorithm. This encryption adds an extra layer of security to the reports, safeguarding sensitive data from potential threats or breaches."},{"page":107,"heading":"Database","anchor":"database","text":"Babel Licensing Service 12.0 supports SQL Server, MySQL/MariaDB, SQLite and PostgreSQL on Windows, Linux and macOS. Select the provider in the service configuration; Babel Desktop connects to the service endpoint, not directly to its database.\nSelect a provider\nSet Database.Provider to one of the exact names below and supply the corresponding ConnectionStrings entry. MariaDB uses MySQL; Postgres, SQL Server and MariaDB are not provider names. Only the selected entry is used.\nDatabase | Provider | Connection string key | Default port\nSQL Server | SQLServer | ConnectionStrings:SQLServer | 1433\nMySQL / MariaDB | MySQL | ConnectionStrings:MySQL | 3306\nPostgreSQL | PostgreSQL | ConnectionStrings:PostgreSQL | 5432\nSQLite | SQLite | ConnectionStrings:SQLite | Local file\nSchema and migration settings\n{\n  \"Database\": {\n    \"Provider\": \"PostgreSQL\",\n    \"EnableMigration\": true,\n    \"EnableDetailedErrors\": false,\n    \"MaxRetryCount\": 5,\n    \"MaxRetryDelay\": \"00:00:30\"\n  }\n}\nEnableMigration=true applies this provider’s schema migrations when the service starts. Use it for initial setup or a planned schema upgrade with the required database permissions. With false, the schema must already be current. Changing the provider does not transfer data between databases. Back up an existing database and test the upgrade on a copy first. For a SQLite 11.8 file, stop the old application before making a consistent backup, then test the 12.0 service against the copy."},{"page":107,"heading":"Database","anchor":"database","text":"EnableDetailedErrors controls additional database error detail. MaxRetryCount and MaxRetryDelay configure transient-operation retries for SQL Server, MySQL and PostgreSQL; they do not enable SQLite retry-on-failure. Restart the service after changing its configuration.\nConnection strings by provider\nThese are complete JSON objects to merge into appsettings.json, not additional nested sections. Replace hosts, paths, users and REPLACE_WITH_PASSWORD. The network examples require a database server configured for TLS with a trusted certificate.\nSQL Server\n{\n  \"Database\": {\n    \"Provider\": \"SQLServer\"\n  },\n  \"ConnectionStrings\": {\n    \"SQLServer\": \"Server=db.example.com,1433;Database=licenses;User ID=babel_licensing;Password=REPLACE_WITH_PASSWORD;Encrypt=True;TrustServerCertificate=False;Connect Timeout=30\"\n  }\n}\nSQL Server uses Server (host and optional comma-separated TCP port), Database, User ID and Password. Encrypt=True;TrustServerCertificate=False encrypts the connection and validates the certificate. On Windows, replace the SQL credentials with Integrated Security=True to use the service account. LocalDB is a Windows development option, not a cross-platform server.\nDriver reference: SQL Server.\nMySQL / MariaDB\n{\n  \"Database\": {\n    \"Provider\": \"MySQL\"\n  },\n  \"ConnectionStrings\": {\n    \"MySQL\": \"Server=db.example.com;Port=3306;Database=licenses;User ID=babel_licensing;Password=REPLACE_WITH_PASSWORD;SslMode=VerifyFull;Connection Timeout=30\"\n  }\n}"},{"page":107,"heading":"Database","anchor":"database","text":"MySQL and MariaDB use the same MySQL key. Server and Port identify the database server; User ID, Password and Database select its account and schema. SslMode=VerifyFull validates both the certificate and server name. For a private CA, add SslCa=/path/to/ca.pem. Use a dedicated database account rather than root.\nMySQL and MariaDB use the MySQL provider on every framework. The .NET 6-9 services use Pomelo.EntityFrameworkCore.MySql; the .NET 10 service uses Microting.EntityFrameworkCore.MySql 10.0.11, an MIT-licensed Pomelo fork that supports Entity Framework Core 10. Starting with 12.0 the .NET 10 service runs on MySQL and MariaDB. Connection strings and database schema are identical. Tested with MySQL 8.4 and MariaDB 11.4.\nDriver reference: MySQL / MariaDB.\nPostgreSQL\n{\n  \"Database\": {\n    \"Provider\": \"PostgreSQL\"\n  },\n  \"ConnectionStrings\": {\n    \"PostgreSQL\": \"Host=db.example.com;Port=5432;Database=licenses;Username=babel_licensing;Password=REPLACE_WITH_PASSWORD;SSL Mode=VerifyFull;Timeout=30\"\n  }\n}\nPostgreSQL uses Npgsql: Host, Port, Database, Username and Password. This is a .NET connection string, not a postgresql:// URL. SSL Mode=VerifyFull validates the certificate and host name; add Root Certificate=/path/to/ca.pem for a private CA. The database and role must exist, and the role needs access to the schema and tables.\nDriver reference: PostgreSQL.\nSQLite"},{"page":107,"heading":"Database","anchor":"database","text":"{\n  \"Database\": {\n    \"Provider\": \"SQLite\"\n  },\n  \"ConnectionStrings\": {\n    \"SQLite\": \"Data Source=/var/lib/babel/licenses.db;Mode=ReadWriteCreate;Foreign Keys=True;Default Timeout=30\"\n  }\n}\nSQLite runs inside the Licensing Service and needs no separate database server, host, port, username or password. Data Source is a path on the machine or container running the service. Use an absolute path. Mode=ReadWriteCreate creates a missing file; use Mode=ReadWrite when an existing database must be present. The service account needs write access to the file and its directory, including journal/WAL files. In Docker, mount that directory as a persistent writable volume.\nWindows path, escaped for JSON:\n{\n  \"ConnectionStrings\": {\n    \"SQLite\": \"Data Source=C:\\\\Babel\\\\Data\\\\licenses.db;Mode=ReadWriteCreate;Foreign Keys=True;Default Timeout=30\"\n  }\n}\nForeign Keys=True enables foreign-key enforcement. Default Timeout=30 is the SQLite command timeout in seconds. A relative path such as licenses.db is resolved from the service working directory and can accidentally select a different file after changing how the service starts.\nConfigure and start the Licensing Service yourself, including a local SQLite service. Babel Desktop does not install, start or stop it. Point the Desktop connection profile at the service’s HTTP/HTTPS endpoint.\nDriver reference: SQLite.\nEnvironment variables"},{"page":107,"heading":"Database","anchor":"database","text":"Environment variables prefixed with BABEL_SERVICE_ override the JSON settings. Use two underscores for each nested separator. Set only the connection-string variable for the selected provider. Inject real secrets using your deployment secret store; the values below are placeholders.\nProvider | Provider variable value | Connection-string variable\nSQLServer | BABEL_SERVICE_Database__Provider=SQLServer | BABEL_SERVICE_ConnectionStrings__SQLServer\nMySQL | BABEL_SERVICE_Database__Provider=MySQL | BABEL_SERVICE_ConnectionStrings__MySQL\nPostgreSQL | BABEL_SERVICE_Database__Provider=PostgreSQL | BABEL_SERVICE_ConnectionStrings__PostgreSQL\nSQLite | BABEL_SERVICE_Database__Provider=SQLite | BABEL_SERVICE_ConnectionStrings__SQLite\nexport BABEL_SERVICE_Database__Provider=PostgreSQL\nexport BABEL_SERVICE_ConnectionStrings__PostgreSQL='Host=db.example.com;Port=5432;Database=licenses;Username=babel_licensing;Password=REPLACE_WITH_PASSWORD;SSL Mode=VerifyFull'\nValues containing semicolons must be quoted according to the selected driver’s connection-string syntax. Escape embedded double quotes and Windows backslashes again when storing the string in JSON."},{"page":108,"heading":"","anchor":"","text":"Configuring SSL/TLS in Babel Licensing Service\nSecuring the gRPC channel in the Babel Licensing Service with SSL/TLS is essential for ensuring encrypted and secure communication between the client applications and the server. SSL/TLS (Secure Sockets Layer/Transport Layer Security) provides a secure communication protocol that protects data integrity, confidentiality, and authenticity.\nTo configure SSL/TLS in the Babel Licensing Service, you need to follow a few steps. First, you need to generate or obtain a valid SSL/TLS certificate. This certificate is used to establish the identity of the server and encrypt the communication.\nOnce you have the SSL/TLS certificate, you need to configure the Babel Licensing Service to utilize it. This involves specifying the certificate's path and password in the configuration settings of the Babel Licensing Service and client applications."},{"page":108,"heading":"Self Signed Certificates","anchor":"self-signed-certificates","text":"Self-signed certificates are digital certificates that are generated and signed by the same entity without involving a trusted third-party certificate authority. Unlike certificates issued by recognized CAs, self-signed certificates are not inherently trusted by default in web browsers or operating systems.\nSelf-signed certificates are particularly useful during development as they allow for secure communication without the need to obtain a certificate from a trusted authority, which can be time-consuming and costly. They are ideal for testing and development scenarios, where the main objective is to establish an encrypted channel for communication.\nTo create a self-signed certificate, you can use PowerShell, a powerful scripting language and command-line shell. The following PowerShell code snippet demonstrates how to generate a self-signed certificate:"},{"page":108,"heading":"Self Signed Certificates","anchor":"self-signed-certificates","text":"# Create cert\n$certname = \"<cert name>\"\n$certpassword = \"<cert password>\"\n\n$cert = New-SelfSignedCertificate -Subject \"CN=$certname\" -CertStoreLocation \"Cert:\\CurrentUser\\My\" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256\n\n# Export PFX\nExport-Certificate -Cert $cert -FilePath \"$certname.cer\"\n$mypwd = ConvertTo-SecureString -String \"$certpassword\" -Force -AsPlainText\nExport-PfxCertificate -Cert $cert -FilePath \"$certname.pfx\" -Password $mypwd\n\n# Delete from local store\n$thumbprint = Get-ChildItem -Path \"Cert:\\CurrentUser\\My\" | Where-Object {$_.Subject -Match \"$certname\"} | Select-Object -ExpandProperty Thumbprint\nRemove-Item -Path \"Cert:\\CurrentUser\\My\\$thumbprint\" -DeleteKey\nThis PowerShell code generates a self-signed certificate with the given certname and certpassword. The New-SelfSignedCertificate cmdlet is used to create the certificate with specific parameters, such as the subject name, key length, and hash algorithm.\nThe certificate is then exported in both .cer and .pfx formats using the Export-Certificate and Export-PfxCertificate cmdlets, respectively. The .cer file contains the public key, while the .pfx file contains the private key along with the certificate.\nFinally, the certificate is deleted from the local certificate store using the Remove-Item cmdlet. This step is optional and can be done to ensure that the self-signed certificate is not present in the local certificate store after it has been exported."},{"page":108,"heading":"Self Signed Certificates","anchor":"self-signed-certificates","text":"By using this PowerShell code to create a self-signed certificate, you can easily configure SSL/TLS in the Babel Licensing Service during development, allowing for secure communication over encrypted channels."},{"page":108,"heading":"Server","anchor":"server","text":"Secure Socket Layer (SSL) and Transport Layer Security (TLS) protocols play a vital role in ensuring secure communication between clients and servers. Babel Licensing Service offers seamless integration with gRPC SSL/TLS, allowing you to establish a secure channel for transmitting data over the network.\nThe \"Certificate\" subsection within the gRPC endpoint configuration allows you to specify the SSL/TLS certificate details.\n\"Endpoints\": {\n  \"gRPC\": {\n    \"Url\": \"https://localhost:5005\",\n    \"Protocols\": \"Http1AndHttp2\",\n    \"Certificate\": {\n      \"AllowInvalid\": true,\n      \"Path\": \"<cert file>.pfx\",\n      \"Password\": \"<cert password>\"\n    }\n  }\n}\nHere, you can set the \"AllowInvalid\" parameter to true when using a self-signed certificate. This configuration accommodates development and testing scenarios where self-signed certificates are commonly used.\nProtocols\nEnabling HTTP1AndHttp2 protocols in the gRPC SSL/TLS configuration provides enhanced flexibility and compatibility for your Babel Licensing Service. This configuration option is specifically available when SSL/TLS is enabled, as it leverages the protocol negotiation capabilities provided by the TLS extension layer ALPN (Application-Layer Protocol Negotiation)."},{"page":108,"heading":"Server","anchor":"server","text":"When SSL/TLS is enabled, the TLS layer acts as a protocol mediator, allowing both HTTP/1 and HTTP/2 protocols to coexist on the same port. This means that clients using either HTTP/1 or HTTP/2 can communicate with the Babel Licensing Service seamlessly without the need for separate ports or configurations.\nThe HTTP/1 protocol is a widely adopted protocol used for communication on the web. It follows a request/response model, where clients send requests to servers and receive corresponding responses. The HTTP/1 protocol is known for its compatibility with various client applications and frameworks.\nOn the other hand, the HTTP/2 protocol brings significant performance improvements over its predecessor. It introduces features such as multiplexing, header compression, and server push, resulting in faster and more efficient communication between clients and servers. By enabling HTTP/2, you can take advantage of these advanced capabilities for enhanced performance and responsiveness."},{"page":108,"heading":"Client","anchor":"client","text":"To configure a client application to secure the gRPC channel with SSL/TLS, you can use the following code:\nBabelLicensing.Configure(config =>\n{\n    config.ServiceUrl = \"https://localhost:5005\";\n    var certificate = new X509Certificate2(\"<cert file>.pfx\", \"<cert password>\");\n\n    config.UseGrpc(options =>\n    {\n        options.HttpHandler = new HttpClientHandler()\n        {\n            ClientCertificates = { certificate },\n            ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator\n        };\n    });\n});\nIn this code snippet, the config object represents the configuration for the Babel Licensing Service. The ServiceUrl property is set to the URL of the service, which includes the https scheme to indicate the use of SSL/TLS.\nThe certificate variable is created by loading the certificate file (in .pfx format) and providing the corresponding password. The UseGrpc method configures the gRPC channel options through a callback, where the HttpClientHandler is set with the ClientCertificates property. This ensures that the client presents the appropriate certificate during the SSL/TLS handshake."},{"page":108,"heading":"Client","anchor":"client","text":"Additionally, the ServerCertificateCustomValidationCallback is set to HttpClientHandler.DangerousAcceptAnyServerCertificateValidator. This callback bypasses the default server certificate validation, accepting any server certificate presented by the Babel Licensing Service. This is suitable for development and testing purposes but should be handled with caution in production environments.\nBy configuring the client application in this way, you establish a secure gRPC channel using SSL/TLS to communicate with the Babel Licensing Service."},{"page":109,"heading":"","anchor":"","text":"Babel Licensing Service supports gRPC Web because it enables a wide range of applications, including Xamarin and UWP, to interact with gRPC services. By using gRPC-Web, these applications can make direct calls to gRPC services using the gRPC Web client and Protobuf.\nThe significance of gRPC Web lies in its compatibility with HTTP/1.1 and browsers. While traditional gRPC relies on HTTP/2 features, which are not supported by all browsers and technologies, gRPC Web has a slightly different protocol that makes it compatible with HTTP/1. This allows browser applications, including those built with Xamarin and UWP, to benefit from the high performance and low network usage of binary messages provided by gRPC.\ngRPC Web eliminates the need for separate communication mechanisms or workarounds for Xamarin clients, making it easier to integrate Babel Licensing Service into a wide range of applications, including those targeting UWP platforms."},{"page":109,"heading":"Server","anchor":"server","text":"To enable gRPC-Web in Babel Licensing Service, you need to make the following configuration changes:\nUpdate the Kestrel endpoint configuration\nUpdate the Kestrel endpoint configuration in the appsettings.json file. Ensure that the \"Protocols\" property includes \"Http1AndHttp2\" to enable both HTTP/1.1 and HTTP/2 protocols:\n\"Endpoints\": {\n  \"gRPC\": {\n    \"Url\": \"https://localhost:5005\",\n    \"Protocols\": \"Http1AndHttp2\"\n    // other properties...\n  }\n}\nEnable gRPC-Web in the Application section\nSet the \"EnableGrpcWeb\" property in the \"Application\" section of the appsettings.json file to true. This indicates that gRPC-Web should be enabled. For example:\n\"Application\": {\n  \"EnableGrpcWeb\": true,\n  // other properties...\n}\nEnable SSL/TLS support\nEnable SSL/TLS support in the Babel Licensing Service project to ensure protocol negotiation through the ALPN capabilities provided by the TLS layer extension.\n\"Endpoints\": {\n  \"gRPC\": {\n    \"Url\": \"https://localhost:5005\",\n    \"Protocols\": \"Http1AndHttp2\",\n    \"Certificate\": {\n      \"AllowInvalid\": true,\n      \"Path\": \"<cert file>.pfx\",\n      \"Password\": \"<cert password>\"\n    }\n  }\n}"},{"page":109,"heading":"Server","anchor":"server","text":"By configuring Babel Licensing Service with these settings, you enable gRPC-Web support, allowing browser-based client applications, including Xamarin and UWP applications, to communicate with the service using gRPC-Web. This enables seamless integration and efficient communication between the client applications and the Babel Licensing Service, leveraging the benefits of gRPC for secure and high-performance data transmission."},{"page":109,"heading":"Client","anchor":"client","text":"To enable gRPC Web in your client application to connect with Babel Licensing Service, follow these steps:\nAdd the NuGet package reference to your project:\nGrpc.Net.Client.Web\nIn your code, configure the BabelLicensing client using the BabelLicensing.Configure method. Set the ServiceUrl property to the URL of your Babel Licensing Service endpoint.\nBabelLicensing.Configure(config => {\n    config.ServiceUrl = \"https://localhost:5005\";\n    var certificate = new X509Certificate2(\"<cert file>.pfx\", \"<cert password>\");\n\n    config.UseGrpc(options =>\n    {\n        options.HttpHandler = new GrpcWebHandler(new HttpClientHandler()\n        {\n            ClientCertificates = { certificate },\n            ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator\n        });\n    });\n});\nIn the code snippet above, replace <cert file>.pfx with the path to your SSL/TLS certificate file and <cert password> with the password for the certificate.\nThis configuration sets up the gRPC Web client using the UseGrpc callback method and GrpcWebHandler. It allows the client to communicate securely with the Babel Licensing Service using the gRPC Web protocol over HTTPS. The GrpcWebHandler is configured with a custom HttpClientHandler that includes the client certificate and accepts any server certificate for development purposes."},{"page":109,"heading":"Client","anchor":"client","text":"Info: In a production environment, make sure to properly handle and secure certificates by setting AllowInvalid to false and by removing the ServerCertificateCustomValidationCallback in the client code.\nWith this configuration, your client application can now connect to the Babel Licensing Service using gRPC Web, enabling secure and efficient communication between the client and the service."},{"page":110,"heading":"","anchor":"","text":"Configuring the HTTP transport in Babel Licensing client applications\nBabel Licensing supports HTTP as an alternative transport protocol to gRPC. The HTTP transport is useful for platforms or environments where gRPC (HTTP/2) is not available or practical, such as older .NET Framework applications or restricted network environments.\nTo select the HTTP transport, use the UseHttp() method on the configuration object. If UseHttp() is called, the client will communicate with Babel Licensing Service through its REST API instead of gRPC."},{"page":110,"heading":"Basic Configuration","anchor":"basic-configuration","text":"To configure the client to use HTTP transport:\nBabelLicensing.Configure(config =>\n{\n    config.ServiceUrl = \"https://localhost:5005\";\n\n    config.UseHttp();\n});\nCalling UseHttp() without parameters uses the default HTTP client settings."},{"page":110,"heading":"Custom HttpClientHandler","anchor":"custom-httpclienthandler","text":"You can pass a configuration callback to UseHttp() to customize the HTTP client options. The callback receives an HttpClientOptions object with the following properties:\nHandler: Gets or sets the HttpClientHandler used for HTTP requests.\nTimeout: Gets or sets the TimeSpan for the HTTP client timeout.\nSSL/TLS with Self-Signed Certificates\nWhen connecting to a service that uses a self-signed certificate, configure the HttpClientHandler to accept the certificate:\nBabelLicensing.Configure(config =>\n{\n    config.ServiceUrl = \"https://localhost:5005\";\n\n    config.UseHttp(http =>\n    {\n        http.Handler = new HttpClientHandler()\n        {\n            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true\n        };\n    });\n});\nClient Certificates\nTo present a client certificate during the SSL/TLS handshake:\nBabelLicensing.Configure(config =>\n{\n    config.ServiceUrl = \"https://localhost:5005\";\n    var certificate = new X509Certificate2(\"<cert file>.pfx\", \"<cert password>\");\n\n    config.UseHttp(http =>\n    {\n        http.Handler = new HttpClientHandler()\n        {\n            ClientCertificates = { certificate },\n            ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator\n        };\n    });\n});\nCustom Timeout\nYou can specify a custom timeout for HTTP requests:"},{"page":110,"heading":"Custom HttpClientHandler","anchor":"custom-httpclienthandler","text":"BabelLicensing.Configure(config =>\n{\n    config.ServiceUrl = \"https://localhost:5005\";\n\n    config.UseHttp(http =>\n    {\n        http.Timeout = TimeSpan.FromSeconds(10);\n        http.Handler = new HttpClientHandler()\n        {\n            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true\n        };\n    });\n});\nProxy Configuration\nTo route HTTP requests through a proxy:\nBabelLicensing.Configure(config =>\n{\n    config.ServiceUrl = \"https://localhost:5005\";\n\n    config.UseHttp(http =>\n    {\n        http.Handler = new HttpClientHandler()\n        {\n            Proxy = new WebProxy(\"http://proxy-server:8080\")\n            {\n                UseDefaultCredentials = true\n            }\n        };\n    });\n});"},{"page":110,"heading":"UseHttp vs UseGrpc","anchor":"usehttp-vs-usegrpc","text":"The transport protocol is determined by which method you call on the configuration:\nUseHttp(): Uses the REST API over HTTP/1.1. Compatible with all .NET platforms and network configurations.\nUseGrpc(): Uses gRPC over HTTP/2. Offers better performance through binary serialization and multiplexing, but requires HTTP/2 support.\nIf neither method is called, the client defaults to gRPC where supported."},{"page":111,"heading":"","anchor":"","text":"When hosting Babel Licensing Service on Internet Information Services (IIS), you may encounter issues with API callbacks if WebDAV is enabled on your server. This document explains why these conflicts occur and provides configuration steps to resolve them."},{"page":111,"heading":"Understanding the WebDAV Conflict","anchor":"understanding-the-webdav-conflict","text":"WebDAV (Web Distributed Authoring and Versioning) is an extension of HTTP that enables collaborative editing and file management on web servers. When enabled in IIS, WebDAV intercepts certain HTTP methods, including:\nPUT\nDELETE\nPROPFIND\nPROPPATCH\nMKCOL\nCOPY\nMOVE\nLOCK\nUNLOCK\nBabel Licensing Service uses a RESTful API approach that relies on various HTTP methods, particularly PUT and DELETE. When WebDAV is enabled, it processes these requests before they can reach the Babel Licensing Service application, causing API callbacks to fail."},{"page":111,"heading":"Symptoms of WebDAV Interference","anchor":"symptoms-of-webdav-interference","text":"You may be experiencing WebDAV conflicts if:\nAPI callbacks fail with 405 (Method Not Allowed) errors\nPUT and DELETE operations to the API result in unexpected responses\nYou're unable to save or update data through the Babel Licensing Service\nOther API operations work correctly, but certain update and delete operations fail"},{"page":111,"heading":"Resolving WebDAV Conflicts","anchor":"resolving-webdav-conflicts","text":"To ensure Babel Licensing Service functions correctly in IIS, you must disable WebDAV for the application. Add or modify your web.config file with the following configuration:\n<configuration>\n  <location path=\".\" inheritInChildApplications=\"false\">\n    <system.webServer>\n      <modules>\n        <remove name=\"WebDAVModule\" />\n      </modules>\n      <handlers>\n        <remove name=\"WebDAV\" />\n        <add name=\"aspNetCore\" path=\"*\" verb=\"*\" modules=\"AspNetCoreModuleV2\" resourceType=\"Unspecified\" />\n      </handlers>\n      <aspNetCore processPath=\"dotnet\" arguments=\".\\Babel.Licensing.Service.dll\" stdoutLogEnabled=\"false\" stdoutLogFile=\".\\logs\\stdout\" hostingModel=\"inprocess\" />\n    </system.webServer>\n  </location>\n</configuration>\nKey Configuration Elements\nRemoving the WebDAV Module:\n<modules>\n  <remove name=\"WebDAVModule\" />\n</modules>\nThis prevents WebDAV from intercepting HTTP requests at the module level.\nRemoving the WebDAV Handler:\n<handlers>\n  <remove name=\"WebDAV\" />\n  <!-- other handlers here -->\n</handlers>\nThis ensures the ASP.NET Core handler receives all HTTP requests regardless of the HTTP verb used."},{"page":111,"heading":"Web.config Placement","anchor":"webconfig-placement","text":"Ensure this web.config file is placed in the root directory of your Babel Licensing Service application."},{"page":111,"heading":"Site-Specific vs. Global Configuration","anchor":"site-specific-vs-global-configuration","text":"The configuration above disables WebDAV only for the Babel Licensing Service application. If you need WebDAV functionality for other applications on the same server, this approach allows you to selectively disable it only where needed.\nIf you prefer to disable WebDAV globally on your IIS server, you can do so through the IIS Manager:\nOpen IIS Manager\nOpen IIS Manager.\nSelect your server\nSelect your server in the Connections panel.\nOpen WebDAV Authoring Rules\nDouble-click on \"WebDAV Authoring Rules\".\nDisable WebDAV\nIn the Actions panel, click \"Disable WebDAV\"."},{"page":111,"heading":"Verifying the Configuration","anchor":"verifying-the-configuration","text":"After applying the configuration changes:\nRestart the application pool\nRestart the application pool for Babel Licensing Service.\nTest the API callbacks\nTest API callbacks that previously failed.\nVerify data operations\nVerify that data saving and updating functions work correctly."},{"page":111,"heading":"Troubleshooting","anchor":"troubleshooting","text":"If issues persist after implementing these changes:\nEnsure the application pool has restarted\nCheck IIS logs for any error messages\nVerify the web.config syntax is correct\nConfirm the WebDAV module is actually installed on your server (the removal directive is still safe even if it's not)\nExamine application logs for any API-related errors\nFor additional assistance, please contact Babel Licensing Service support with your IIS server version and configuration details."},{"page":112,"heading":"","anchor":"","text":"In the Babel Licensing Service, error codes play a crucial role in efficiently communicating and handling various issues that may arise during interactions with the licensing system. These error codes, along with their corresponding descriptions, are used to construct detailed error messages that provide valuable insights into the nature of encountered problems.\nThis set of error codes is specifically designed to address and classify errors related to three main server features in the Babel Licensing Service: Floating Licenses, License Activation, and Reports. Each error code corresponds to a unique scenario, allowing developers and clients to quickly identify and respond to specific issues.\nBelow is a comprehensive list of error codes, categorized according to their respective features, along with brief descriptions detailing the nature of each error. The StatusCode refer to the corresponding RpcException status raised by the Babel Licensing Service to the client.\nCommon Errors\nThis category encompasses a range of frequently encountered issues that can occur across various functionalities within the Babel Licensing Service. These errors are fundamental in nature and affect both the Floating License and License Activation features."},{"page":112,"heading":"","anchor":"","text":"LicenseKeyNotFound: License key not found (StatusCode.NotFound)\nLicenseRevoked: The license has been revoked (StatusCode.PermissionDenied)\nLicenseExpired: The license has expired (StatusCode.PermissionDenied)\nTokenExpired: The license token has expired (StatusCode.PermissionDenied)\nLicenseTampered: The license has been tampered (StatusCode.DataLoss)\nTokenNotFound: License token not found (StatusCode.NotFound)\nTokenTampered: License token has been tampered (StatusCode.DataLoss)\nServerReachedMaxTokenAllowed: The server has reached the maximum number of license tokens allowed (StatusCode.PermissionDenied). See License Tokens\nFloating License Errors\nThis category pertains specifically to errors related to the usage and management of floating licenses within the Babel Licensing Service.\nLicenseReachedMaxClients: The maximum number of concurrent users for the license has been reached (StatusCode.ResourceExhausted)\nLicenseAlreadyAssigned: The requested floating license has already been assigned (StatusCode.InvalidArgument)\nLicense Activation Errors\nThis category encompasses a range of errors that may occur during license activation, such as the requirement for a valid machine code to activate the license successfully."},{"page":112,"heading":"","anchor":"","text":"MachineCodeRequiredToActivate: The machine code is required for license activation (StatusCode.InvalidArgument)\nLicenseTemplateNotFound: A license template could not be found for the selected license (StatusCode.NotFound)\nLicenseMaxActivationReached: The license has reached the maximum number of activations allowed (StatusCode.ResourceExhausted)\nLicenseAlreadyActivated: The license has already been activated (StatusCode.AlreadyExists). Since 12.0.7 activation no longer returns it: a machine that activates again gets its existing activation back.\nLicenseNotActivated: The license has not been activated (StatusCode.FailedPrecondition)\nLicenseNotActivationMode: Cannot use this license for activation (StatusCode.FailedPrecondition)\nReporting Errors\nThis category pertains to issues specifically related to reporting functionalities within the Babel Licensing Service.\nNotAuthorizedToSendReport: Client is not authorized to send reports.(StatusCode.PermissionDenied)\nThese StatusCode codes indicate the type of GRPC status associated with each error message. They are used along with the error descriptions to construct instances of the Status class for returning GRPC errors of type RpcException in the Babel Licensing Service to client applications."},{"page":113,"heading":"","anchor":"","text":"Babel Licensing Service is a powerful solution designed to streamline the licensing process, enhance software security, and simplify license management for software vendors. With a comprehensive set of features, this service enables efficient license distribution, monitoring, and reporting, while facilitating seamless integration into your software applications."},{"page":113,"heading":"","anchor":"","text":"License Management: Efficiently manage your software licenses with Babel Licensing Service. Create, customize, and distribute licenses effortlessly, tailoring them to meet your specific licensing models and customer requirements. Whether you prefer floating licenses, activation-based licenses, or file-based licenses, this service offers the flexibility to accommodate diverse licensing needs. Validate and activate licenses securely, ensuring only authorized users can access and utilize your software. Set expiration dates and enable automatic license renewal, enabling a smooth experience for your customers.\nReport Management: Babel Licensing Service offers robust report management capabilities, including the ability to monitor and analyze application exception reports. These reports provide valuable insights into the performance and stability of your software applications, enabling you to proactively identify and address any issues that may arise.\nDeployment: Deploying licenses with Babel Licensing Service is a breeze. Seamlessly integrate the service into your software applications using software development kits (SDKs) and APIs. Enjoy the benefits of a scalable infrastructure that can handle high volumes of license requests and activations. Cloud-based deployment options provide flexibility, scalability, and global accessibility, allowing you to reach a broader customer base and deliver licenses with ease."},{"page":113,"heading":"","anchor":"","text":"Experience the convenience and efficiency of Babel Licensing Service as it simplifies license management, streamlines reporting, and facilitates effortless deployment. Take control of your software licensing process, protect your intellectual property, and deliver a seamless experience to your customers."},{"page":114,"heading":"","anchor":"","text":"Babel Licensing Services offer flexibility in terms of deployment options, allowing them to be hosted either on-premises or in the cloud. This flexibility enables software developers and organizations to choose the hosting environment that best suits their needs and preferences. Let's explore both deployment options:"},{"page":114,"heading":"On-Premises Hosting","anchor":"on-premises-hosting","text":"Hosting Babel Licensing Services on-premises refers to deploying the licensing services infrastructure within the organization's data center or local server environment. This deployment approach offers several advantages:\na) Data Control: By hosting the licensing services on-premises, organizations have full control over their license-related data. They can ensure data security, compliance with internal policies, and meet regulatory requirements specific to their industry.\nb) Network Performance: Hosting the services locally allows organizations to have low latency and high network performance, as the licensing operations are processed within the internal network infrastructure.\nc) Customization and Integration: On-premises hosting provides greater flexibility for customization and integration with existing systems and processes within the organization. It allows for seamless integration with internal databases, user management systems, and other enterprise applications.\nd) Privacy and Confidentiality: Some organizations may have strict data privacy and confidentiality requirements that necessitate keeping license-related data within their own infrastructure. On-premises hosting ensures sensitive licensing information remains within the organization's controlled environment."},{"page":114,"heading":"Cloud Hosting","anchor":"cloud-hosting","text":"Babel Licensing Services can also be deployed in a cloud environment, leveraging the infrastructure and services provided by cloud service providers like Amazon Web Services (AWS), Microsoft Azure, or Google Cloud Platform (GCP). Cloud hosting offers several benefits:\na) Scalability and Elasticity: Cloud hosting allows organizations to scale their licensing services infrastructure up or down based on demand. They can easily handle increased license activity during peak periods and scale back during quieter periods. This flexibility ensures optimal resource utilization and cost efficiency.\nb) High Availability: Cloud service providers offer robust infrastructure and redundancy options that ensure high availability of the licensing services. Organizations can leverage the provider's data centers across different regions to ensure uninterrupted access to licensing services.\nc) Managed Services: Cloud hosting often includes managed services, where the cloud provider takes care of infrastructure maintenance, updates, and security patches. This allows organizations to focus on their core business activities rather than managing the underlying infrastructure.\nd) Global Accessibility: Cloud-hosted licensing services can be accessed from anywhere, providing global accessibility to licensed applications. This is particularly beneficial for organizations with a distributed user base or international operations."},{"page":114,"heading":"Cloud Hosting","anchor":"cloud-hosting","text":"e) Cost Savings: Cloud hosting offers cost savings by eliminating the need for upfront hardware investments and ongoing infrastructure maintenance. Organizations can leverage the pay-as-you-go pricing model, where they only pay for the resources they consume, resulting in cost optimization.\nRegardless of the hosting option chosen, Babel Licensing Services provides the same set of functionalities and capabilities for license tracking and management. Organizations can select the deployment option that aligns with their infrastructure strategy, security requirements, scalability needs, and budget considerations.\nIn conclusion, Babel Licensing Services can be hosted either on-premises or in the cloud. Both deployment options offer distinct advantages, enabling organizations to choose the environment that best suits their specific requirements in terms of data control, network performance, customization, scalability, availability, and cost efficiency."},{"page":115,"heading":"","anchor":"","text":"Babel Licensing Service provides comprehensive license management and enforcement capabilities, empowering software developers to protect their intellectual property and ensure compliance with licensing terms. With Babel Licensing Service, developers can implement robust mechanisms to manage, monitor, and enforce software licenses, offering a range of licensing models to choose from and ensuring that they can implement the most suitable approach for their software licensing needs.\nLet's explore the key aspects of license management and the different licensing models offered by Babel Licensing Service."},{"page":115,"heading":"License Validation","anchor":"license-validation","text":"Babel Licensing Service enables the validation of software licenses to ensure their authenticity and validity. When a software application or component is launched, Babel Licensing Service verifies the associated license to determine if it is valid and has not expired. This validation process involves checking the license's digital signature, decoding and examining its content, and verifying additional custom license restrictions. By validating licenses, developers can prevent unauthorized usage and enforce compliance with licensing terms."},{"page":115,"heading":"License Expiration and Renewal","anchor":"license-expiration-and-renewal","text":"Babel Licensing Service allows developers to set expiration dates for licenses, ensuring that software usage is time-limited and compliant with licensing agreements. When a license expires, the associated software application or component can be restricted from further execution or specific functionality based on the defined license terms. Additionally, developers can implement license renewal mechanisms to provide users with the ability to extend their licenses beyond the initial expiration date, enabling ongoing usage of the software."},{"page":115,"heading":"License Revocation","anchor":"license-revocation","text":"In situations where a software license needs to be revoked, Babel Licensing Service offers mechanisms to invalidate and block licenses. This can occur due to various reasons, such as non-compliance with licensing terms, unauthorized distribution or usage, or breach of contractual agreements. By revoking licenses, developers can ensure that only authorized users and systems can access and utilize their software applications or components."},{"page":115,"heading":"Custom License Restrictions","anchor":"custom-license-restrictions","text":"Babel Licensing Service supports the implementation of custom license restrictions based on specific requirements. Developers can define additional constraints and limitations within the license, such as hardware restrictions, domain restrictions, feature-based limitations, or user-specific permissions. These custom license restrictions allow for granular control over software usage and enable developers to tailor the licensing experience to meet their unique needs."},{"page":115,"heading":"Floating License","anchor":"floating-license-","text":"The floating license model allows for the dynamic allocation of licenses across multiple users or machines within a network. With floating licenses, a limited number of licenses are shared among a larger user base, enabling concurrent usage. Babel Licensing Service facilitates the tracking and management of floating licenses by integrating with the Babel Licensing Services component. This ensures that licenses are efficiently allocated and reclaimed, providing flexibility for organizations with varying license usage requirements."},{"page":115,"heading":"License Activation","anchor":"license-activation","text":"License activation involves the process of binding a software license to a specific machine. This model ensures that the software can only be activated and used on authorized systems. Babel Licensing Service supports license activation by verifying and validating license activation requests, ensuring the licenses are activated on authorized machines. The activation process involves a unique hardware fingerprint to ensure the license is tied to the intended machine."},{"page":115,"heading":"License File","anchor":"license-file","text":"The license file model provides a traditional approach to software licensing. In this model, a license file is generated and distributed to the licensee. The license file contains the necessary information and permissions required for the software to run. Babel Licensing Service allows developers to generate digitally signed license files that can be easily distributed to end-users. These license files are typically stored in XML format or encoded strings and can be verified by the licensing system to ensure their authenticity and validity.\nBy supporting these diverse licensing models and enforcement capabilities, Babel Licensing Service caters to a wide range of licensing scenarios. Developers can choose the most appropriate model based on their software distribution and usage requirements. Whether it's floating licenses for enterprise environments, license activation for individual users, or license files for traditional software distribution, Babel Licensing Service provides the necessary tools and components to implement and manage the chosen licensing model effectively."},{"page":116,"heading":"Application Fault Reports","anchor":"application-fault-reports","text":"One of the valuable features of Babel Licensing Services is the capability to collect application fault reports. When integrated into licensed applications, the licensing services can capture and collect detailed information about application crashes, errors, and exceptions. This information includes stack traces, error messages, system configurations, and other relevant data.\na) Improved Application Stability: By collecting application fault reports, organizations can identify and analyze common application crashes and errors. This information helps developers pinpoint areas of their applications that require improvement or bug fixes, leading to enhanced application stability and reliability.\nb) Efficient Bug Resolution: The collected fault reports provide developers with detailed information about the circumstances leading to application failures. This accelerates the bug resolution process by providing valuable insights into the root causes of issues, enabling developers to address them more effectively.\nc) User Experience Enhancement: By actively collecting application fault reports, organizations can gain a better understanding of the challenges users face while using their applications. This knowledge helps in identifying usability issues, user experience bottlenecks, and areas for improvement, leading to a more satisfying user experience."},{"page":116,"heading":"Application Fault Reports","anchor":"application-fault-reports","text":"d) Data-Driven Decision Making: The aggregated data from application fault reports can be analyzed to identify patterns, trends, and recurring issues across different versions or deployments of the application. This data-driven decision-making approach empowers organizations to prioritize development efforts, allocate resources effectively, and make informed decisions regarding application enhancements and bug fixes."},{"page":117,"heading":"","anchor":"","text":"The Health Check feature in Babel Licensing Service provides a comprehensive mechanism to monitor the health and operational status of the service and its components. This feature is essential for ensuring system reliability, facilitating troubleshooting, and enabling integration with infrastructure monitoring tools."},{"page":117,"heading":"Configuration","anchor":"configuration","text":"Health Check behavior is configured through the Application section in the appsettings.json file:\n\"Application\": {\n    \"HealthCheckEndPoint\": \"/health\",\n    \"HealthCheckResponseType\": \"JSON\"\n}\nHealthCheckEndPoint\nThis setting specifies the URL path where the health check endpoint will be accessible. The default value is /health.\nExample: If your service is running at https://licensing.example.com and the HealthCheckEndPoint is set to /health, the full health check URL would be https://licensing.example.com/health.\nHealthCheckResponseType\nThis setting determines the format of the health check response. Two formats are supported:\nJSON: Returns a structured JSON response (default)\nTEXT: Returns a human-readable plain text response\nJSON Response Format\nWhen HealthCheckResponseType is set to \"JSON\", the health check endpoint produces a structured JSON response like this:"},{"page":117,"heading":"Configuration","anchor":"configuration","text":"{\n  \"status\": \"Healthy\",\n  \"duration\": \"00:00:00.2514204\",\n  \"timestamp\": \"2025-03-20T07:26:07.1085160Z\",\n  \"checks\": [\n    {\n      \"name\": \"babel_service_health\",\n      \"status\": \"Healthy\",\n      \"duration\": \"00:00:00.0010617\",\n      \"data\": {\n        \"serverTimeUtc\": \"2025-03-20T07:26:06.8604190Z\",\n        \"activeTokens\": 0\n      }\n    },\n    {\n      \"name\": \"database_health\",\n      \"status\": \"Healthy\",\n      \"duration\": \"00:00:00.1003761\"\n    },\n    {\n      \"name\": \"webhook_processor_health\",\n      \"status\": \"Healthy\",\n      \"duration\": \"00:00:00.0605641\",\n      \"data\": {\n        \"hasFailedEvents\": false\n      }\n    },\n    {\n      \"name\": \"geo_location_health\",\n      \"status\": \"Healthy\",\n      \"duration\": \"00:00:00.2456515\"\n    }\n  ]\n}\nThis format is ideal for:\nAutomated monitoring systems\nIntegration with orchestration platforms like Kubernetes\nProgrammatic health status evaluation\nThird-party monitoring tools that can parse JSON data\nTEXT Response Format\nWhen HealthCheckResponseType is set to \"TEXT\", the health check endpoint produces a human-readable format:"},{"page":117,"heading":"Configuration","anchor":"configuration","text":"Babel Licensing Service v. 11.0.0.0\n\nStatus: Healthy\nDuration: 00:00:00.2586788\nTimestamp: 2025-03-20T07:23:14.0761680Z\nVersion: 11.0.0.0\n\nChecks:\n- Babel Licensing Service: Healthy (00:00:00.0024254)\n    * Server Time Utc: 2025-03-20T07:23:13.8180050Z\n    * Active Tokens: 0\n\n- Database: Healthy (00:00:00.0901153)\n- Webhook Processor: Healthy (00:00:00.0687397)\n    * Has Failed Events: False\n\n- Geo Location: Healthy (00:00:00.2550240)\nThis format is better suited for:\nManual inspection by system administrators\nCommand-line tools and simple status checks\nSituations where the response needs to be easily readable without additional parsing\nLog file entries and console output"},{"page":117,"heading":"Health Check Components","anchor":"health-check-components","text":"The Babel Licensing Service health check monitors several critical components:\nService Health: Provides information about the main service, including server time, license edition, active tokens, and maximum allowed tokens.\nDatabase Health: Verifies connectivity and operational status of the database.\nWebhook Processor: Checks if the webhook processing system is functioning correctly.\nGeo Location Service: Confirms that the configured geolocation service (like IpApiIs) is operational.\nStatus Values\nHealth checks will report one of the following statuses:\nHealthy: The component is functioning normally\nDegraded: The component is operational but with reduced functionality or performance\nUnhealthy: The component is not functioning properly\nIntegration with Monitoring Systems\nThe health check endpoint can be integrated with various monitoring systems:\nLoad Balancers: Can use the health check to determine if the service should receive traffic\nContainer Orchestration: Platforms like Kubernetes can use the endpoint for readiness and liveness probes\nMonitoring Tools: Systems like Prometheus, Nagios, or Zabbix can periodically check the endpoint\nCustom Dashboards: The JSON format can be consumed by custom monitoring dashboards"},{"page":117,"heading":"Best Practices","anchor":"best-practices","text":"Regular Monitoring: Configure your monitoring system to check the health endpoint at regular intervals.\nAlerting: Set up alerts for when the service transitions from Healthy to Degraded or Unhealthy.\nResponse Format Selection: Choose JSON for automated systems and TEXT for human operators.\nCustom Endpoint: Consider changing the default endpoint for security reasons in production environments.\nFirewall Configuration: Ensure your firewall allows access to the health check endpoint from your monitoring systems.\nThe Health Check feature is an essential tool for maintaining the reliability and stability of your Babel Licensing Service deployment by providing real-time insights into the operational status of the system and its components."},{"page":118,"heading":"","anchor":"","text":"The license workflow in Babel Licensing represents the end-to-end process of creating, managing, and deploying software licenses. Understanding this workflow is essential for effectively implementing licensing strategies that protect your intellectual property while providing flexibility to your customers. This guide will walk you through the four key stages of the license workflow in Babel Licensing.\nflowchart LR\n    classDef phase1 fill:#3498db,stroke:#2980b9,color:white\n    classDef phase2 fill:#2ecc71,stroke:#27ae60,color:white\n    classDef phase3 fill:#9b59b6,stroke:#8e44ad,color:white\n    classDef phase4 fill:#f39c12,stroke:#e67e22,color:white\n\n    A[Product Definition] --> B[Sign Key Assignment]\n    B --> C[License Template]\n    C --> D[License Deployment]\n    \n    class A phase1\n    class B phase2\n    class C phase3\n    class D phase4"},{"page":118,"heading":"1. Product Definition","anchor":"1-product-definition","text":"The foundation of the licensing workflow begins with defining your product within Babel Licensing. A product definition encapsulates all the essential information about the software you want to license, creating a digital representation that serves as the basis for all licensing operations.\nKey Components of Product Definition:\nProduct Information: Basic details such as name, version, and description.\nSign Keys: Signature key pair (typically in SNK or PFX format) to sign new licenses. These cryptographic keys enable digital signing of all licenses generated for this product\nProduct definition provides the necessary context for license generation and validation. By properly defining your product, you establish the foundation for all subsequent licensing operations."},{"page":118,"heading":"2. Assignment of Sign Keys to Products","anchor":"2-assignment-of-sign-keys-to-products","text":"Digital signatures play a vital role in the security and integrity of licenses. Each license in Babel Licensing is digitally signed to prevent tampering and unauthorized modifications. Signing keys are cryptographic key pairs that enable this digital signature process.\nSigning Key Process:\nKey Generation: Creating a cryptographic key pair (private and public keys).\nKey Assignment: Associating the key pair with a specific product.\nLicense Signing: Using the private key to sign licenses during generation.\nLicense Validation: Using the public key to verify license authenticity during validation.\nThe private key must be kept secure and should only be accessible to authorized personnel responsible for license generation. The public key, embedded in your application, allows for license validation without compromising security."},{"page":118,"heading":"3. License Template Definition","anchor":"3-license-template-definition","text":"License templates streamline the process of creating multiple licenses with similar configurations. A template serves as a blueprint that defines the common attributes, restrictions, and features of licenses for a specific product or product edition.\nComponents of License Templates:\nTemplate Name: Descriptive identifier for the template.\nLicense Type: Defines the license category (e.g., Standard, Professional, Enterprise).\nLicense Format: Specifies the format of the license (XML, ASCII, BASE32).\nLicense Fields: Pre-configured fields for the licenses.\nFeatures: Enabled product features.\nRestrictions: Limitations such as trial periods, hardware binding, or usage constraints.\nTemplates enable you to maintain consistency across licenses while allowing for customization when needed. They are particularly useful for managing different product editions or implementing trial versions with specific restrictions.\nTypes of License Restrictions\nRestrictions in license templates add conditional logic to license validation, allowing for sophisticated licensing scenarios:\nTrial Restrictions: Limit usage by time (days) or execution count\nHardware Restrictions: Bind licenses to specific hardware identifiers\nDomain Restrictions: Limit usage to specific network domains\nFeature Restrictions: Control access to specific product features\nEdition Restrictions: Define different product editions with varying capabilities"},{"page":118,"heading":"4. License Deployment Models","anchor":"4-license-deployment-models","text":"Babel Licensing offers three primary deployment models, each suited to different distribution and usage scenarios. Selecting the appropriate deployment model depends on factors such as connectivity requirements, license management preferences, and security considerations.\nFile-Based Licenses\nFile-based licenses are traditional license files distributed to users for offline activation. They are ideal for environments with limited or no internet connectivity.\nCharacteristics:\nStored as XML or string-encoded files\nDigitally signed to prevent tampering\nCan be easily distributed via email or download\nNo network connectivity required for validation\nLicense files are validated locally by the application\nBest For: Desktop applications, offline environments, or when centralized license management is not required."},{"page":118,"heading":"Activation Licenses","anchor":"activation-licenses","text":"Activation licenses link a license to a specific machine through a one-time activation process. This model provides a balance between security and convenience.\nCharacteristics:\nRequires internet connectivity during activation\nLicense is tied to a specific machine's hardware ID\nLimited number of activations per license\nSupports deactivation to transfer licenses\nDoes not requires constant connectivity to the license server\nCentralized tracking of license usage\nBest For: Applications that need moderate license security while allowing for some flexibility in deployment."},{"page":118,"heading":"Floating Licenses","anchor":"floating-licenses","text":"Floating licenses enable sharing of licenses across multiple users or machines within a network. They are ideal for optimizing license usage in enterprise environments.\nCharacteristics:\nLicenses are checked out from a central server\nLimited by concurrent usage rather than machine count\nReal-time license allocation and release\nRequires constant connectivity to the license server\nProvides detailed usage analytics\nBest For: Enterprise applications, team environments, or when maximizing license utilization is essential."},{"page":118,"heading":"Complete Licensing Workflow","anchor":"complete-licensing-workflow","text":"The entire license workflow in Babel Licensing encompasses all the stages from product definition to license deployment. The workflow is a continuous cycle of creating, managing, and deploying licenses to meet your business requirements and customer needs."},{"page":119,"heading":"","anchor":"","text":"This diagram illustrates the complete floating license process including request, usage, heartbeat verification, and release:\nThe user launches the application.\nThe application reads the user key from its configuration.\nThe application sends a request to the Babel Licensing Service for a floating license, including the user key and a unique client ID.\nThe service verifies the license exists in the database.\nThe service validates the license, checking expiration and revocation status.\nThe service checks if there are licenses available in the floating pool.\nIf licenses are available:\nThe service allocates a floating token and associates it with the client ID\nThe application receives the license token and enables full functionality\nThe application sends periodic heartbeats to maintain the license\nWhen the user exits or manually releases the license, the token is returned to the pool\nIf no licenses are available:\nThe service returns an error\nThe application displays a message to the user\nThis sequence diagram highlights the dynamic nature of floating licenses, where licenses are temporarily allocated during use and then returned to the pool when released, making them available for other users."},{"page":119,"heading":"","anchor":"","text":"sequenceDiagram\n    participant User as User\n    participant App as Client Application\n    participant BLS as Babel Licensing Service\n    participant DB as License Database\n\n    User->>App: Launch Application\n    App->>App: Read User Key Configuration\n    App->>BLS: Request Floating License\n    Note over App,BLS: UserKey + Client ID\n\n    BLS->>DB: Check License Exists\n    DB->>BLS: Return License Details\n\n    BLS->>BLS: Validate License\n    Note over BLS: Check expiration, revocation, etc.\n\n    BLS->>DB: Check Available Licenses\n    Note over BLS: Verify license count < allowed sites\n    DB->>BLS: Return Available Count\n\n    alt Licenses Available\n        BLS->>DB: Allocate Floating Token\n        Note over BLS,DB: Associate token with client ID\n        DB->>BLS: Confirm Token Allocated\n        BLS->>App: Return Success + License Token\n        App->>User: Enable Full Functionality\n        \n        Note over App,BLS: Heartbeat Validation\n        loop Every N minutes\n            App->>BLS: Send Heartbeat\n            BLS->>DB: Update Last Activity\n            BLS->>App: Confirm License Still Valid\n        end\n        \n        User->>App: Exit Application or Release License\n        App->>BLS: Request License Release\n        BLS->>DB: Release Floating Token\n        DB->>BLS: Confirm Token Released\n        BLS->>App: Confirm Release\n    else No Licenses Available\n        BLS->>App: Return Error - No Licenses Available\n        App->>User: Display Error Message\n    end"},{"page":120,"heading":"","anchor":"","text":"The following diagram shows the entire license activation workflow from when a customer enters their activation code through the periodic validation process that happens after successful activation.\nThe customer enters their activation code in the client application.\nThe application generates a unique hardware ID based on the machine's characteristics.\nThe application sends an activation request to the Babel Licensing Service with both the user key and hardware ID.\nThe service validates the license in the database, checking if it exists and confirming it hasn't expired or been revoked.\nThe service verifies that the maximum number of activations hasn't been reached.\nUpon successful validation, the service creates an activation token in the database, associating it with the specific hardware ID.\nThe service returns a digitally signed license token to the application.\nThe application stores this token locally for future validation.\nThe application displays an activation success message to the customer.\nPeriodically (e.g., every 5 days), the application validates the license with the service to ensure it remains valid."},{"page":120,"heading":"","anchor":"","text":"The key distinction of the activation model is that the license becomes permanently bound to a specific machine through its hardware identifier. Unlike floating licenses that are temporarily allocated, activation licenses remain tied to the machine until explicitly deactivated. This activation process creates a more persistent licensing relationship, suitable for software that will be consistently used on the same device."},{"page":120,"heading":"","anchor":"","text":"sequenceDiagram\n    participant Customer as Customer\n    participant App as Client Application\n    participant BLS as Babel Licensing Service\n    participant DB as License Database\n\n    Customer->>App: Enter Activation Code\n    App->>App: Generate Hardware ID\n    App->>BLS: Send Activation Request\n    Note over App,BLS: UserKey + Hardware ID\n    \n    BLS->>DB: Check License Exists\n    DB->>BLS: Return License Details\n    \n    BLS->>BLS: Validate License\n    Note over BLS: Check expiration, revocation, etc.\n    \n    BLS->>BLS: Verify Available Activations\n    Note over BLS: Check if max activations reached\n    \n    BLS->>DB: Create Activation Token\n    Note over BLS,DB: Associate token with hardware ID\n    DB->>BLS: Confirm Token Created\n    \n    BLS->>App: Return Activation License\n    Note over BLS,App: Digitally signed license token\n    \n    App->>App: Store License Token Locally\n    App->>Customer: Display Activation Success\n    \n    Note over App,BLS: Periodic Validation\n    App->>BLS: Validate License (e.g., every 5 days)\n    BLS->>DB: Verify Token Status\n    DB->>BLS: Return Token Status\n    BLS->>App: Return Validation Result"},{"page":121,"heading":"","anchor":"","text":"The license file model represents the traditional approach to software licensing, where a digitally signed license file is distributed to customers and validated locally by the application without requiring communication with a licensing server. This model is ideal for scenarios where customers may operate in completely offline environments or when you prefer a simpler deployment model without the infrastructure requirements of server-based licensing.\nThe license file process works as follows:"},{"page":121,"heading":"","anchor":"","text":"The software developer creates a license template in the Babel Licensing Service.\nThe developer generates a license file based on the template, digitally signing it with a private key.\nThe Babel Licensing Service returns the generated license file.\nThe developer distributes the license file to the customer through their preferred delivery method (download, email, physical media, etc.).\nThe customer installs the license file in the appropriate location (typically the application directory).\nWhen the application starts, it loads the license file from its location.\nThe application validates the license file's digital signature using an embedded public key.\nThe application verifies the license details, including expiration date, licensed features, and any restrictions.\nIf the license is valid, the application enables the appropriate features as specified in the license.\nIf the license is invalid (expired, tampered with, or otherwise not meeting requirements), the application displays an error message.\nThe application periodically revalidates the license during operation, but this validation occurs entirely locally without requiring any server communication."},{"page":121,"heading":"","anchor":"","text":"Unlike activation and floating licenses, the file-based approach does not consume license tokens and operates independently of the Babel Licensing Service after the initial license generation. The license validation occurs entirely within the client application using the embedded public key to verify the license's authenticity and integrity.\nThe primary advantages of the license file model include simplicity, complete offline operation, and lower infrastructure requirements. However, this approach provides less visibility into license usage and fewer options for remote license management compared to the token-based licensing models."},{"page":121,"heading":"","anchor":"","text":"sequenceDiagram\n    participant Developer as Software Developer\n    participant BLS as Babel Licensing Service\n    participant Customer as Customer\n    participant App as Client Application\n\n    Developer->>BLS: Create License Template\n    Developer->>BLS: Generate License File\n    Note over Developer,BLS: Digitally sign with private key\n    \n    BLS->>Developer: Return License File\n    Developer->>Customer: Distribute License File\n    Note over Developer,Customer: Via download, email, etc.\n    \n    Customer->>App: Install License File\n    Note over Customer,App: Place in application directory\n    \n    App->>App: Load License File\n    App->>App: Validate License Signature\n    Note over App: Using embedded public key\n    \n    App->>App: Verify License Details\n    Note over App: Check expiration, features, restrictions\n    \n    alt License Valid\n        App->>Customer: Enable Application Features\n        Note over App,Customer: Based on licensed features\n    else License Invalid\n        App->>Customer: Display License Error\n        Note over App,Customer: Expired, tampered, etc.\n    end\n\n    Note over App: Periodic Validation\n    loop On application start or feature use\n        App->>App: Revalidate License Locally\n        Note over App: No server communication required\n    end"},{"page":122,"heading":"","anchor":"","text":"License templates are a fundamental component of the Babel Licensing system, serving as blueprints for generating licenses with consistent configurations. These templates streamline the licensing process by defining standard configurations that can be reused across multiple license instances, ensuring consistency and reducing manual effort."},{"page":122,"heading":"Advantages of Using Templates","anchor":"advantages-of--using-templates","text":"License templates have these advantages:"},{"page":122,"heading":"Advantages of Using Templates","anchor":"advantages-of--using-templates","text":"Consistency and Efficiency: License templates allow you to define standard configurations for floating licenses or license activation. By using templates, you ensure consistency in the licensing process and avoid manual entry of the same information for each license. This saves time and minimizes the risk of errors or inconsistencies in license creation.\nStreamlined License Generation: With license templates, generating licenses becomes a streamlined process. Templates pre-fill the relevant information, such as product details, license fields, features, and restrictions. This eliminates the need to manually enter repetitive information and speeds up the license generation process.\nCustomizability: License templates offer flexibility and customization options. You can create multiple templates with different configurations based on your specific licensing needs. For example, you can have templates for different product editions, license types, or feature sets. This allows you to cater to various licensing scenarios and easily adapt to changing licensing requirements.\nReusability: License templates are reusable assets. Once you create a template, you can use it as a blueprint to generate multiple licenses with similar configurations. This is particularly beneficial when issuing floating licenses or activation licenses to multiple customers or users. You can quickly generate licenses based on the template, reducing manual effort and ensuring consistency across licenses."},{"page":122,"heading":"Advantages of Using Templates","anchor":"advantages-of--using-templates","text":"Simplified Updates and Maintenance: License templates make it easier to update and maintain licenses. If there are changes in licensing terms, product details, or restrictions, you can modify the template accordingly. This automatically applies the changes to all licenses generated from that template, ensuring that the updated information is consistently reflected across licenses.\nStandardization and Compliance: License templates help enforce standardization and compliance in license creation. By defining specific fields and configurations in the template, you ensure that all licenses adhere to the required licensing rules, restrictions, and compliance regulations. This promotes license standardization and helps maintain compliance with licensing agreements and legal obligations.\nCentralized Storage: The Babel database provides a centralized store for license templates. This eliminates the need for scattered template files stored across different systems or folders, ensuring a repository for managing and organizing templates.\nIn short, templates make licenses faster to create and more consistent, and you can still adapt them to different licensing scenarios."},{"page":122,"heading":"Template Structure and Components","anchor":"template-structure-and-components","text":"A license template in Babel Licensing consists of several key sections that define various aspects of the license:\nBasic Template Information\nName: A descriptive name for the template that identifies its purpose or the type of license it generates.\nLicense Type: Defines the category of license (e.g., Standard, Professional, Enterprise).\nMode: Specifies the licensing model:\nActivation: Licenses that are activated and bound to specific machine\nFloating: Licenses that can be shared among multiple users with concurrent usage limits\nFile: Traditional license files that are distributed to users\nLicense Configuration\nUser Key Format: Defines the format for generating unique user keys (e.g., STD-{TOKEN:5}-{TOKEN:5}-{TOKEN:5}).\nIssue Date: Toggle to include the date when the license is issued.\nExpire Days: Number of days after which the license will expire.\nSupport Days: Duration of provided support in days.\nLicense File Name: The default filename for generated license files.\nFormat: The format of the license (XML, XML DSig, ASCII, BASE32).\nDescription: Additional information about the template's purpose or usage.\nProduct and Signing\nProduct: Associates the template with a specific product in the Babel Licensing Database.\nSign Keys: Cryptographic keys used to digitally sign licenses generated from the template, ensuring their authenticity and integrity.\nLicense Properties\nThe License Properties section contains four main tabs:"},{"page":122,"heading":"Template Structure and Components","anchor":"template-structure-and-components","text":"Assemblies: Lists the .NET assemblies that the license applies to, including details such as:\nAssembly Name\nVersion\nCulture\nPublic Key Token\nComponents: Specifies components within assemblies that are licensed.\nFields: Custom license fields that can store additional information.\nFeatures: Defines specific features that are enabled by the license.\nRestrictions\nTemplates can include various restrictions that control how the license can be used:\nTrial: Limits usage based on time or number of executions, including:\nExpire Days: Duration of the trial period\nRun Instances: Maximum number of concurrent instances\nRun Count: Total number of allowed executions\nRun Time: Maximum allowed runtime\nTerms: Additional terms and conditions\nHardware: Restricts the license to specific hardware configurations.\nDomain: Limits license usage to specific network domains.\nBeta: Designates the license for beta or pre-release software.\nUsage: Defines specific usage scenarios or environments."},{"page":122,"heading":"License Models and Template Configuration","anchor":"license-models-and-template-configuration","text":"Each licensing model requires specific configuration within the template:\nActivation License Templates\nActivation license templates are designed for licenses that are tied to specific machines. Key configurations include:\nMode set to \"Activation\"\nUser Key format definition\nAllowed sites (number of activations permitted)\nHardware restrictions (optional)\nFloating License Templates\nFloating license templates enable license sharing across multiple users or machines. Important settings include:\nMode set to \"Floating\"\nUser Key format definition\nAllowed sites (maximum concurrent users)\nHeartbeat interval (implicitly defined by the service)\nFile License Templates\nFile license templates generate traditional license files that can be distributed to users. Key aspects include:\nMode set to \"File\"\nLicense file name\nFormat (XML, XML DSig, ASCII, BASE32)\nSign keys for digital signature"},{"page":122,"heading":"Managing Templates in Babel Desktop","anchor":"managing-templates-in-babel-desktop","text":"License templates are stored on the Babel Licensing Service. You can manage them with Babel Desktop, with the Data Center web application, or with the Babel Licensing WordPress plugin.\nTo access license templates in Babel Desktop, open your service profile from the activity bar and choose License templates.\nThe grid lists the license templates with their name, code, type, licensing mode and expiration days. Within the grid, you can:\nSearch: type in the search box to find templates by name or code.\nSort and page: sort the templates by a column and move through the pages of results.\nChoose columns: use the Columns chooser to show or hide columns.\nView details: open a template to see all its settings and the licenses generated from it.\nEdit: change the settings of the selected template with Edit.\nDelete: remove a template that is no longer needed. Deleting asks for confirmation and cannot be undone, so take care not to remove templates still in use.\nUpload and save template files: use Upload template file… to attach a template file (.xml, .txt or .tpl) to the template, and Save template file… to save it to the license export folder.\nCreate and Edit Templates"},{"page":122,"heading":"Managing Templates in Babel Desktop","anchor":"managing-templates-in-babel-desktop","text":"To create a new license template, choose New license template on the License templates toolbar. Creating and editing templates requires a Local test connection profile with Local management, that is, Babel Desktop running on the service machine; profiles of remote services are read-only. The form is organized in these groups:\nTemplate: the Name, Code, Type and Format of the template.\nLicensing: the licensing mode (file, activation or floating), the License file name, Set issue date, Expires after (days), Maintenance (days), Generate key info and the User key format.\nDetails: the Description, the Product, the Release id and the Signature key.\nProperties: the Assemblies, Components, Fields and Features included in the licenses.\nRestrictions: the license restrictions, such as Trial, Usage, Hardware, Beta, Domain or Custom.\nSave the form to store the template on the Babel Licensing Service. The new template then appears in the License templates grid and can be selected when you generate a license. To change an existing template, select it and choose Edit.\nWith the Data Center edition you can also manage templates in the web application."},{"page":123,"heading":"","anchor":"","text":"The License Properties section in a Babel Licensing template defines the specific attributes and constraints of licenses generated from the template. This section is divided into four key categories: Assemblies, Components, Fields, and Features. Each category serves a distinct purpose in defining the scope and characteristics of the license."},{"page":123,"heading":"Assemblies","anchor":"assemblies","text":"The Assemblies tab specifies which .NET assemblies are covered by the license. This is crucial for software composed of multiple assemblies, as it allows you to precisely control which parts of your software are licensed.\nAssembly Properties\nEach assembly entry in a license template includes the following information:\nName: The name of the assembly (e.g., \"MyCompany.ProductName\")\nVersion: The version number of the assembly (e.g., \"1.0.0.0\")\nCulture: The culture information of the assembly (e.g., \"neutral\" or specific culture codes)\nPublic Key Token: The public key token that verifies the assembly's identity\nVersion Wildcards\nBabel Licensing supports wildcard expressions for assembly versions, allowing a single license to cover multiple versions of the same assembly:\nExact Version: 1.0.0.0 (covers only version 1.0.0.0)\nMajor Version Wildcard: 1.* (covers all 1.x.x.x versions)\nMajor and Minor Version Wildcard: 1.2.* (covers all 1.2.x.x versions)\nVersion Range: [1.0.0.0-2.0.0.0] (covers versions from 1.0.0.0 to 2.0.0.0, inclusive)\nExamples"},{"page":123,"heading":"Assemblies","anchor":"assemblies","text":"Single Assembly, Exact Version:\nName: MyCompany.Core\nVersion: 1.5.2.0\nCulture: neutral\nPublic Key Token: a5d85ef2c81d0f8a\nSingle Assembly, All Versions in Major Release:\nName: MyCompany.Core\nVersion: 2.*\nCulture: neutral\nPublic Key Token: a5d85ef2c81d0f8a\nMultiple Assemblies with Different Version Rules:\nName: MyCompany.Core\nVersion: 3.*\nCulture: neutral\nPublic Key Token: a5d85ef2c81d0f8a\n\nName: MyCompany.Extensions\nVersion: [1.0.0.0-2.5.0.0]\nCulture: neutral\nPublic Key Token: a5d85ef2c81d0f8a"},{"page":123,"heading":"Components","anchor":"components","text":"The Components tab allows you to license specific components or modules within an assembly, providing finer granularity in licensing control. Components are represented as string identifiers that your application code can check against.\nComponent Usage\nComponents are typically used in scenarios where:\nYour application has distinct modules that can be licensed separately\nYou want to enable or disable specific functionality based on license level\nYou need to implement feature-based licensing within a single assembly\nProperties\nName: A string identifier for the component (e.g., \"ReportingEngine\", \"AdvancedEditor\")\nExamples\nModule-based Components:\nName: DataAnalysis\nName: Reporting\nName: Visualization\nFeature-tier Components:\nName: BasicFeatures\nName: AdvancedFeatures\nName: EnterpriseFeatures\nIntegration Components:\nName: SqlServerConnector\nName: SapIntegration\nName: RestApiClient\nIn your application code, you can check if a specific component is licensed using the Babel Licensing API:\nif (license.Components.Contains(\"AdvancedFeatures\"))\n{\n    // Enable advanced features\n}"},{"page":123,"heading":"Fields","anchor":"fields","text":"The Fields tab allows you to add custom key-value pairs to the license template. These fields can store additional information that might be relevant for license validation, tracking, or business purposes.\nCommon Uses\nDefine custom license parameters\nStore encrypted passwords for features\nInclude metadata for license management\nProperties\nName: The identifier of the field (e.g., \"Metadata\", \"ContractNumber\")\nValue: The associated value for the field\nExamples\nApplication-specific Fields:\nName: MaxConcurrentProjects\nValue: 10\n\nName: StorageQuota\nValue: 500GB\nFeature Configuration Fields:\nName: EncryptionLevel\nValue: AES256\n\nName: ApiRateLimit\nValue: 1000\nYour application can access these fields through the Babel Licensing API:\nstring encryptionLevel = license.Fields[\"EncryptionLevel\"].Value;\nint apiRateLimit = int.Parse(license.Fields[\"ApiRateLimit\"].Value);\nFeatures\nThe Features tab defines specific features or capabilities that the license enables within your application. Unlike Components, which are simple string identifiers, Features can include additional data that can be used to configure the feature.\nProperties\nName: The identifier of the feature (e.g., \"CloudSync\", \"BatchProcessing\")\nData: Optional binary data associated with the feature, which can store configuration parameters, feature-specific keys, or other data\nExamples"},{"page":123,"heading":"Fields","anchor":"fields","text":"Basic Feature Enablement:\nName: AdvancedReporting\nName: DataExport\nName: CustomBranding\nFeatures with Configuration Data:\nName: SecurityModule\nData: [Encrypted configuration data]\n\nName: DatabaseConnectors\nData: [Serialized list of allowed connectors]\nTiered Features:\nName: UserQuota\nData: [Serialized value representing maximum users]\n\nName: PerformanceTier\nData: [Encoded performance settings]\nYour application can check for feature availability and retrieve associated data:\nif (license.Features.Any(f => f.Name == \"AdvancedReporting\"))\n{\n    // Enable advanced reporting features\n}\n\nvar securityConfig = license.Features\n    .FirstOrDefault(f => f.Name == \"SecurityModule\")?.Data;\nif (securityConfig != null)\n{\n    // Initialize security module with the provided configuration\n}\nIntegration Strategy\nWhen designing your license templates, consider how these four property categories work together:\nAssemblies define the scope of what software components are licensed\nComponents provide modularity within those assemblies\nFields add custom information and parameters\nFeatures enable specific capabilities, potentially with configuration data\nBy carefully structuring these properties, you can create flexible licensing schemes that adapt to different customer needs, business models, and product editions while maintaining control over your software's usage and distribution."},{"page":123,"heading":"Fields","anchor":"fields","text":"This comprehensive approach to license properties in Babel Licensing gives you the tools to implement sophisticated licensing strategies that protect your intellectual property while providing a seamless experience for your customers."},{"page":124,"heading":"","anchor":"","text":"The Restrictions section in a Babel Licensing template allows you to define specific constraints on how licenses can be used. These restrictions provide granular control over license behavior, enabling you to implement various licensing models and enforce usage conditions. Babel Licensing offers several built-in restriction types along with the ability to create custom restrictions."},{"page":124,"heading":"Overview of License Restrictions","anchor":"overview-of-license-restrictions","text":"License restrictions serve as enforceable conditions that determine how, when, and where your software can be used under a specific license. Each restriction type addresses a specific aspect of license control, from time-limited usage to hardware binding. Multiple restrictions can be combined within a single license template to create sophisticated licensing models tailored to your specific requirements.\nInfo: When a license has multiple restrictions, ALL restrictions must be individually validated for the license to be considered valid. If even one restriction fails validation, the entire license validation process will fail. This allows for creating highly specific licensing conditions where all defined constraints must be satisfied simultaneously."},{"page":124,"heading":"Beta Restriction","anchor":"beta-restriction","text":"The Beta restriction is designed for pre-release software, tagging licenses with information that indicates the software is in beta status.\nKey Properties:\nBuild Type: Specifies the build type (e.g., \"Alpha\", \"Beta\", \"RC\") to indicate the development stage of the software.\nRecent Changes: A text field where you can document changes or features specific to this beta release.\nUse Cases:\nDistributing early access versions to testers or select customers\nTime-limited beta programs before full product release\nLimiting liability by clearly identifying software as pre-release\nImplementation Example:\nif (license.Restrictions.OfType<BetaRestriction>().Any())\n{\n    // Show beta warning dialog\n    // Enable telemetry and crash reporting\n}"},{"page":124,"heading":"Hardware Restriction","anchor":"hardware-restriction","text":"The Hardware restriction binds a license to specific hardware, preventing unauthorized use on different machines. This is achieved through a hardware key generated from the target computer's unique characteristics.\nKey Properties:\nHardware Key: A unique identifier generated from hardware components of the machine (can be empty in the template and filled during license activation).\nData: Additional data that can be used to store hardware-specific information.\nUse Cases:\nSingle-machine perpetual licenses\nPreventing license sharing across multiple devices\nHigh-security environments where software must be bound to authorized hardware\nInfo: Note: When using activation licenses, the hardware restriction is automatically applied during the activation process, as the license becomes bound to the specific machine through its hardware ID. Therefore, it is not necessary to explicitly add a hardware restriction to license templates that use the activation licensing mode. The activation process itself handles the hardware binding functionality."},{"page":124,"heading":"Trial Restriction","anchor":"trial-restriction","text":"The Trial restriction limits software usage based on time or execution parameters, making it ideal for implementing free trial versions of your software.\nKey Properties:\nExpire Days: Number of days the trial is valid after first use.\nRun Instances: Maximum number of concurrent instances allowed.\nRun Count: Maximum total number of application executions allowed.\nRun Time: Maximum duration the application can run per session.\nTerms: Special terms and conditions that apply to the trial license.\nUse Cases:\nTime-limited evaluation versions\nFeature-limited trial versions\nUsage-count limited demo versions\nFreemium model implementation\nImplementation Example:\nvar trial = license.Restrictions.OfType<TrialRestriction>().FirstOrDefault();\nif (trial != null)\n{\n    if (trial.IsExpired())\n    {\n        // Show trial expiration message\n        // Prompt for license purchase\n    }\n    else\n    {\n        // Show remaining trial period\n        // Log trial usage\n    }\n}"},{"page":124,"heading":"Domain Restriction","anchor":"domain-restriction","text":"The Domain restriction limits license usage to a specific network domain, ensuring that software can only be used within authorized organizational boundaries.\nKey Properties:\nDomain: The network domain name where the license is valid (e.g., \"example.com\").\nRole: Optional role identifier within the domain (e.g., \"developer\", \"admin\").\nUse Cases:\nEnterprise licensing for specific organizations\nLimiting software use to authorized corporate networks\nDifferent licensing terms for different organizational units"},{"page":124,"heading":"Usage Restriction","anchor":"usage-restriction","text":"The Usage restriction defines the environment where the application is allowed to run, providing control over deployment scenarios and execution contexts.\nKey Properties:\nUsage: Identifies the allowed usage environment or context.\nCan Run In Virtual Environment: When true, allows the software to run in virtualized environments.\nProcess List: A list of processes that must or must not be running for the license to be valid.\nUse Cases:\nPreventing execution in virtual machines for security-sensitive applications\nLimiting software to specific environments (development, staging, production)\nRequiring or prohibiting the presence of specific companion processes"},{"page":124,"heading":"Custom Restrictions","anchor":"custom-restrictions","text":"Beyond the built-in restrictions, Babel Licensing allows you to create custom restrictions to address unique licensing requirements specific to your application. Custom restrictions are powerful extensions that enable you to implement specialized validation logic tailored to your specific business and technical needs.\nImplementing Custom Restrictions\nTo create a custom restriction, you need to implement a class that inherits from Restriction and implements the ILicenseSerializable interface. This gives you complete control over both the validation logic and how the restriction is serialized in the license file.\nKey Components of a Custom Restriction:\nName Property: A unique identifier for your restriction type.\nCustom Properties: Properties specific to your restriction's functionality.\nValidation Logic: Custom code that determines whether the license is valid based on your criteria.\nSerialization Methods: Methods to read and write your restriction data to XML or format.\nExample: Memory Requirements Restriction\nHere's an example of a custom restriction that validates whether a machine meets minimum memory requirements."},{"page":124,"heading":"Custom Restrictions","anchor":"custom-restrictions","text":"/// <summary>\n/// A license restriction that limits usage based on the physical memory (RAM) \n/// of the system.\n/// </summary>\nclass MemoryRestriction : Restriction, ILicenseSerializable\n{\n    /// <summary>\n    /// Gets the name of the restriction.\n    /// </summary>\n    public override string Name => \"Memory\";\n\n    /// <summary>\n    /// Gets or sets the minimum total memory required in megabytes.\n    /// </summary>\n    public long TotalMemory { get; set; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"MemoryRestriction\"/> class.\n    /// </summary>\n    public MemoryRestriction()\n    {\n    }\n\n    /// <summary>\n    /// Validates that the system has at least the required amount of physical memory.\n    /// </summary>\n    /// <param name=\"context\">The license context.</param>\n    /// <param name=\"type\">The type being validated.</param>\n    /// <param name=\"instance\">The instance being validated.</param>\n    /// <returns>A <see cref=\"ValidationResult\"/> indicating whether validation was successful.</returns>\n    public override ValidationResult Validate(ILicenseContext context, Type type, object instance)\n    {\n        ISystemInformation sys = (ISystemInformation)context.GetService(typeof(ISystemInformation));\n\n        // Cannot run on this machine\n        long totalMem = ToMegabytes(sys.TotalPhysicalMemory);\n        if (totalMem < TotalMemory)\n            return ValidationResult.Invalid;\n\n        return base.Validate(context, type, instance);\n    }\n"},{"page":124,"heading":"Custom Restrictions","anchor":"custom-restrictions","text":"    /// <summary>\n    /// Converts bytes to megabytes.\n    /// </summary>\n    /// <param name=\"bytes\">The number of bytes to convert.</param>\n    /// <returns>The equivalent value in megabytes.</returns>\n    private static long ToMegabytes(long bytes)\n    {\n        return bytes / 1024 / 1024;\n    }\n\n    /// <summary>\n    /// Reads the memory restriction data from the specified state.\n    /// </summary>\n    /// <param name=\"state\">The state object, which can be either an <see cref=\"XmlReader\"/> or a <see cref=\"BinaryReader\"/>.</param>\n    public void Read(object state)\n    {\n        if (state is XmlReader xmlReader)\n        {\n            xmlReader.MoveToContent();\n\n            string? totalMemory = xmlReader.GetAttribute(\"totalMemory\");\n            if (totalMemory != null)\n                TotalMemory = XmlConvert.ToInt64(totalMemory);\n\n            bool isEmptyElement = xmlReader.IsEmptyElement;\n            xmlReader.ReadStartElement();\n            if (!isEmptyElement)\n                xmlReader.ReadEndElement();\n        }\n        else if (state is BinaryReader binaryReader)\n        {\n            TotalMemory = binaryReader.ReadInt32();\n        }\n    }\n\n    /// <summary>\n    /// Writes the memory restriction data to the specified state.\n    /// </summary>\n    /// <param name=\"state\">The state object, which can be either an <see cref=\"XmlWriter\"/> or a <see cref=\"BinaryWriter\"/>.</param>\n    public void Write(object state)\n    {\n        if (state is XmlWriter)\n        {"},{"page":124,"heading":"Custom Restrictions","anchor":"custom-restrictions","text":"            XmlWriter writer = (XmlWriter)state;\n            if (TotalMemory != 0)\n                writer.WriteAttributeString(\"totalMemory\", XmlConvert.ToString(TotalMemory));\n        }\n        else if (state is BinaryWriter)\n        {\n            BinaryWriter writer = (BinaryWriter)state;\n            writer.Write(TotalMemory);\n        }\n    }\n}\nFull sample project is available on GitHub:\ngit clone https://github.com/babelfornet/custom_license_restrictions.git\nUsing Custom Restrictions in License Creation\nOnce you've defined your custom restriction class, you can use it when generating licenses:\n// Create a digital signer\nRSASignature signer = RSASignature.CreateFromKeyFile(\"Keys.snk\");\n\n// Requires a minimum of 4GB RAM to validate\nint totalMemory = 4096;\n\nvar license = new XmlLicense()\n              .WithUniqueId()\n              .ForProduct(\"Product\", \"1.0.0.0\")\n              .LicensedTo(\"ACME\", \"devs@acme.com\")\n              .WithRestrictions(new MemoryRestriction(totalMemory))\n              .SignWith(signer);\n              \nlicense.Save(\"Product.licenses\");\nUse Cases for Custom Restrictions\nCustom restrictions can address a wide range of specialized licensing requirements:"},{"page":124,"heading":"Custom Restrictions","anchor":"custom-restrictions","text":"Hardware Requirements: Ensure software only runs on machines meeting minimum specifications.\nNetwork Configuration: Validate specific network configurations or connectivity requirements.\nTime-Zone Restrictions: Limit software use to specific geographic regions based on time zones.\nApplication Co-existence: Verify that required companion applications are installed.\nDatabase Engine Validation: Ensure compatible database systems are present.\nCloud Environment Detection: Apply special rules for cloud-hosted deployments.\nCustom Business Rules: Implement industry-specific or organization-specific licensing rules.\nCustom Restrictions and License Templates\nCustom restrictions can be seamlessly integrated into the Babel Licensing template system, allowing you to save and reuse license configurations that include your custom validation logic. When saved as part of a license template in the Babel Licensing Service, these custom restrictions become reusable components that can be applied consistently across multiple licenses.\nStoring Custom Restrictions in License Templates\nOnce you've implemented a custom restriction, you can incorporate it into a license template through the Babel Licensing Service:\nCreate your license with the custom restriction as shown in the previous example.\nSave this license as a template in the Babel Licensing Database.\nThe template, including the custom restriction, becomes available for generating new licenses.\nBenefits of Template-Based Custom Restrictions"},{"page":124,"heading":"Custom Restrictions","anchor":"custom-restrictions","text":"Storing custom restrictions in license templates offers several advantages:\nConsistency: Ensures that all licenses generated from the template apply the same custom validation rules, maintaining consistency across your licensing strategy.\nCentralized Management: Manage your custom restrictions from a single location within the Babel Licensing Service, making it easier to update or modify licensing rules.\nSimplified License Generation: Generate new licenses with complex custom restrictions without having to reimplement the validation logic each time.\nVersioning and Tracking: Keep track of different versions of your custom restrictions as your licensing requirements evolve.\nIntegration with Licensing Workflows: Incorporate custom restrictions into your existing licensing processes, such as license activation, floating licenses, or file-based licenses.\nExample Workflow\nHere's a typical workflow for utilizing custom restrictions within the Babel Licensing Service template system:"},{"page":124,"heading":"Custom Restrictions","anchor":"custom-restrictions","text":"Development: Create and test your custom restriction class in your development environment.\nTemplate Creation: Develop a license with your custom restriction and save it as a template:\nvar licenseKey = new XmlLicense()\n                 .WithUniqueId()\n                 .ForProduct(\"Product\", \"1.0.0.0\")\n                 .WithRestrictions(new MemoryRestriction(4096))\n                 .SignWith(signer)\n                 .ToReadableString();\n              \n// Store licenseKey in Babel Licensing Service\nLicense Generation: Use the template to generate specific licenses for customers.\nDistribution: Distribute the generated license to the customer using your preferred delivery method (direct download, email, activation code, etc.).\nValidation: When the customer uses your application, the custom restriction validation logic is executed as part of the license validation process.\nImplementing Template-Compatible Custom Restrictions\nTo ensure your custom restrictions work well within the template system, consider these implementation guidelines:"},{"page":124,"heading":"Custom Restrictions","anchor":"custom-restrictions","text":"Parameter Flexibility: Design your custom restriction class to support both parameterized initialization (for programmatic creation) and parameter-less initialization (for template-based creation).\nXML Serialization: Implement the IXmlSerializable interface properly to ensure your custom restriction's configuration can be saved to and loaded from license templates.\nBackward Compatibility: Maintain backward compatibility when updating custom restrictions to ensure that existing templates and licenses continue to function.\nError Handling: Implement robust error handling in both your serialization and validation logic to prevent issues when your custom restriction is used in a template.\nIntegration with Babel Licensing Service Features\nCustom restrictions stored in templates can leverage the full suite of Babel Licensing Service features:\nActivation Licenses: Apply custom restrictions to licenses that require activation, adding your specialized validation to the activation process.\nFloating Licenses: Use custom restrictions with floating licenses to add specialized validation criteria to concurrent license usage.\nFile Licenses: Include custom restrictions in file-based licenses for offline validation scenarios."},{"page":124,"heading":"Custom Restrictions","anchor":"custom-restrictions","text":"By incorporating custom restrictions into your license templates within the Babel Licensing Service, you create a powerful, flexible, and maintainable licensing system that can address even the most unique and specialized licensing requirements while maintaining the benefits of centralized license management.\nBest Practices for Custom Restrictions\nKeep Validation Fast: Custom restriction validation code runs during license checking, so keep it efficient.\nHandle Exceptions: Ensure your validation code handles exceptions gracefully to prevent application crashes.\nProvide Clear Feedback: When validation fails, return meaningful information about why the validation failed.\nSecure Sensitive Logic: Any sensitive validation logic in your custom restriction could be subject to reverse engineering; consider obfuscation for critical code.\nTest Comprehensively: Test your custom restrictions in various environments to ensure consistent behavior.\nDocument Thoroughly: Document your custom restrictions for both internal development and customer-facing materials.\nCustom restrictions extend Babel Licensing's capabilities to address unique licensing requirements, providing a flexible and powerful licensing solution tailored to your specific needs. These specialized validation rules enable you to implement precisely the licensing model your application requires, giving you complete control over how your software is licensed and used."},{"page":124,"heading":"Combining Restrictions","anchor":"combining-restrictions","text":"A powerful feature of Babel Licensing is the ability to combine multiple restrictions to create sophisticated licensing models. For example, you might combine:\nTrial + Hardware: A time-limited trial that's bound to a specific machine\nDomain + Usage: A license valid only within a corporate domain and in non-virtual environments\nBeta + Custom: A beta license with custom restrictions for specific testing scenarios\nWhen multiple restrictions are applied, all restrictions must be satisfied for the license to be considered valid. This allows for precise control over how your software is licensed and used.\nBest Practices for Using Restrictions\nStart Simple: Begin with the minimum restrictions necessary and add more as your licensing needs evolve.\nConsider User Experience: Balance security with usability. Overly restrictive licenses may frustrate legitimate users.\nProvide Clear Feedback: When a restriction causes a license validation failure, ensure your application provides clear information about why the license is invalid.\nTest Thoroughly: Test all restriction combinations to ensure they work as expected in various scenarios.\nDocument for End Users: Clearly document the restrictions applied to each license type so customers understand the limitations.\nImplement Graceful Degradation: Where possible, consider allowing limited functionality rather than complete application failure when certain restrictions are not met."},{"page":124,"heading":"Combining Restrictions","anchor":"combining-restrictions","text":"Effective utilization of license restrictions in your templates creates a flexible licensing system that protects your intellectual property while providing appropriate access to customers based on their licensing level. These restrictions serve as the foundation for implementing sophisticated licensing models that balance security with usability, ensuring that your software is used according to your licensing terms while delivering a seamless experience for legitimate users."},{"page":125,"heading":"","anchor":"","text":"The User Key format in Babel Licensing can be customized using a special syntax that allows you to define the structure, length, and character types of generated keys. This flexibility enables you to create user keys that align with your organization's naming conventions and security requirements.\nFormat Syntax\nWhen configuring the User Key format, you can use the following placeholders:\nPlaceholder | Description\n{TOKEN:NN} | Generates UPPERCASE alphanumeric characters (letters and digits) of length NN\n{token:NN} | Generates lowercase alphanumeric characters (letters and digits) of length NN\n{HEX:NN} | Generates UPPERCASE hexadecimal characters (0-9, A-F) of length NN\n{hex:NN} | Generates lowercase hexadecimal characters (0-9, a-f) of length NN\n{DEC:NN} | Generates decimal digits (0-9) of length NN\nIn each placeholder, NN represents the number of characters to generate. For example, {TOKEN:5} will generate 5 uppercase alphanumeric characters.\nFormat Examples\nHere are some examples of User Key formats and what they might generate:"},{"page":125,"heading":"","anchor":"","text":"Standard Format with Separators:\n{TOKEN:5}-{TOKEN:5}-{TOKEN:5}\nExample output: AB3C7-XY29P-RTK84\nProduct-Specific Prefix:\nPRO-{TOKEN:8}-{HEX:4}\nExample output: PRO-KD83P7LM-E5F2\nMixed Case with Multiple Segments:\n{TOKEN:4}{token:4}-{HEX:6}\nExample output: X5P3ab7c-A7F9D2\nNumeric License with Hyphens:\n{DEC:4}-{DEC:4}-{DEC:4}\nExample output: 7391-2658-9034\nComplex Format with Mixed Types:\nLIC-{TOKEN:3}{hex:4}-{DEC:3}-{HEX:5}\nExample output: LIC-QR5b7a2-847-D39F7\nEnterprise License Format:\nENT-{TOKEN:5}-{DEC:3}-{TOKEN:5}\nExample output: ENT-XC73P-592-KLMNR\nBest Practices\nWhen designing your User Key format, consider the following best practices:\nBalance Readability and Security: Longer keys provide more security, but can be difficult for users to type or communicate. Including separators (like hyphens) can improve readability.\nInclude Identifying Prefixes: Adding prefixes like \"STD-\" or \"ENT-\" can help users and support staff quickly identify license types.\nConsider Key Length: For most applications, a total length of 12-20 characters provides a good balance between security and usability.\nAvoid Ambiguous Characters: When choosing your format, be mindful that some characters like '0' (zero) and 'O' (capital o) can be confused. Using {HEX:NN} can help avoid some of these ambiguities.\nTest Readability: Ensure the key format is easily readable for customer support scenarios, where keys might need to be verbally communicated."},{"page":125,"heading":"","anchor":"","text":"By carefully designing your User Key format, you can create keys that are not only secure but also user-friendly and aligned with your product branding."},{"page":126,"heading":"","anchor":"","text":"In Babel Licensing, licensing modes define how software licenses are distributed, activated, and managed. The licensing mode you choose determines how your customers will interact with your software, how licenses are validated, and what kind of infrastructure is required to support your licensing strategy."},{"page":126,"heading":"Primary Licensing Modes","anchor":"primary-licensing-modes","text":"Babel Licensing offers three primary licensing modes, each designed to address different deployment scenarios and business needs:\nLicense File: Traditional license files distributed directly to customers\nLicense Activation: Licenses that are bound to specific machines through an activation process\nFloating License: Shared licenses that can be used concurrently by multiple users\nEach mode provides distinct advantages and is suitable for different types of applications and customer environments. Understanding these licensing modes is essential for designing an effective licensing strategy that balances security, flexibility, and user experience."},{"page":126,"heading":"Token-Based Extensions","anchor":"token-based-extensions","text":"In addition to the primary licensing modes, Babel Licensing provides token-based extensions that can be applied across licensing modes to enhance functionality:\nLicense Tokens: Track concurrent usage by temporarily allocating tokens to active clients\nConsumption Tokens: Track usage volume by permanently consuming tokens during service operations\nThese token-based approaches can be combined with the primary licensing modes to create sophisticated licensing strategies:\nA floating license may use License Tokens to manage concurrent connections\nAny licensing mode can utilize Consumption Tokens to track and bill for actual usage volume"},{"page":126,"heading":"Documentation Structure","anchor":"documentation-structure","text":"This section explores each licensing mode and token approach in detail, highlighting their characteristics, benefits, implementation considerations, and typical use cases. By understanding the capabilities and limitations of each approach, you can select the most appropriate strategies for your software products and licensing requirements."},{"page":127,"heading":"","anchor":"","text":"A floating license is a pool of licenses shared among the users or machines on a network. With Babel Licensing, you create floating licenses on the Babel Licensing Service using Babel Desktop. This page shows how to create a floating license with Babel Desktop and how to configure a client .NET application to use it with the Babel Licensing library."},{"page":127,"heading":"Prerequisites","anchor":"prerequisites","text":"To enable floating license functionality in Babel Licensing Service, follow these steps. First, ensure that Babel Licensing Service is up and running on your server according to the instructions provided in the Getting Started section. Then, create a test product and a corresponding template license by referring to the instructions provided below. This will establish the foundation for generating floating licenses.\nNext, you'll need to download the floating license client source code from GitHub. This client code will be used to integrate floating license capabilities into your .NET application.\ngit clone https://github.com/babelfornet/floating-license-console-example.git\nThe creation of a floating license for this example requires the creation of a corresponding license template."},{"page":127,"heading":"Creating a Floating License","anchor":"creating-a-floating-license","text":"Babel Desktop connects to the Babel Licensing Service and lets you create and configure floating licenses. You define the size of the license pool, that is the number of users or machines allowed to use the license at the same time. Your application then acquires a license from the pool when it needs one and releases it when it is done. Each checked-out seat is a token that counts against the token limit of the service; see License Tokens.\nTo register a floating license in Babel Desktop, follow these steps:"},{"page":127,"heading":"Creating a Floating License","anchor":"creating-a-floating-license","text":"Connect to the service\nOpen Babel Desktop and click the icon of your Babel Licensing Service profile in the activity bar. Generating licenses requires a Local test profile with Local management, so run Babel Desktop on the service machine; for a remote service use the web application or the Management API.\nGenerate a license\nOpen the Licenses view and choose Generate license on the toolbar.\nSelect the template and signature key\nIn the Template group, select the license Template created in the previous paragraph (see License Templates) and the Signature key. When no signature key is selected, the key of the template, or of its product, is used.\nSet the mode to Floating\nIn the Terms group, set Mode to Floating.\nSet the pool size\nIn Sites, enter the size of the floating pool: the number of licenses that can be in use at the same time.\nGenerate the user key\nIn the License information group, press the Generate button at the right end of the User key field. The client application will use this unique code to request a floating license.\nEnter the licensee and license details\nEnter the licensee information (a licensee name or company is required) and any additional Fields, Features or Restrictions you want for this license.\nSelect the format\nSelect the license Format: XML, XML signature, ASCII or Base32.\nSave the license\nSave the form. The service generates and signs the license."},{"page":127,"heading":"Creating a Floating License","anchor":"creating-a-floating-license","text":"Info: The public key extracted from the Keys.snk file, which is necessary for license validation, is already configured in the example source code.\nThe newly registered floating license will now appear in the licenses grid with a unique license key and other relevant information. With the Data Center edition you can also create floating licenses on the Licenses page of the web application.\nThe Babel Licensing Service limits the concurrent use of the license to the number of floating sites you entered."},{"page":127,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"Once the floating license is created on the Babel Licensing Service, you need to configure your client .NET application to consume the license. This involves integrating the Babel Licensing library into your application and implementing the necessary code to request and release licenses from the floating license pool. The Babel Licensing library provides the APIs for license validation and enforcement.\nTo open the floating license sample project, follow these steps:"},{"page":127,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"Open the solution\nNavigate to the location where the floating license sample project is stored and double-click on the ClientFloating.sln solution file to open it in your preferred Integrated Development Environment (IDE), such as Visual Studio.\nCheck the client library reference\nOnce the project is open, ensure that the Babel Licensing client library is referenced correctly. If the reference is missing, please refer to the Client Components paragraph to configure a local NuGet repository.\nBuild the solution\nAfter ensuring the correct references, build the solution by selecting the \"Build\" or \"Rebuild\" option from the IDE's menu.\nRun the application\nOnce the solution is successfully built, you can run the application in debug configuration by pressing the \"Start Debugging\" button or using the keyboard shortcut specific to your IDE (e.g., F5 in Visual Studio). The floating license sample application will launch, allowing you to interact with the licensing functionality and test the floating license workflow.\nEnter the floating license key\nEnter the floating license key generated for the license and press ENTER.\n\nFloating License Console\nFollows the complete license activation example source code:"},{"page":127,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"using Babel.Licensing;\n\n// Create a new configuration object\nBabelLicensingConfiguration config = new BabelLicensingConfiguration() {\n    // Set the service URL\n    ServiceUrl = \"http://localhost:5005\",\n    \n    // Set the public key used to verify the license signature\n    SignatureProvider = RSASignature.FromKeys(\"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDE1VRiIdr6fiVZKve7NVgjIvGdRiRx0Mjjm+Yzf6tLbzFnxLs0fat5EoRcubxx0QQQDfydsJBE/fc7cwRWSrE2xK6X4Eb4W8O47pCMjqvTQZfDqQywEZJrLlxpp9hlKz6FDYX4SagrjmP1gdw8olo+n+IBz8ubkNxRhvycikxuDQIDAQAB\"),\n    \n    // Set a unique client ID in case multiple instances of the application are running on the same machine\n    ClientId = Guid.NewGuid().ToString()\n};\n\n// Create the client object used to communicate with the server\nBabelLicensing client = new BabelLicensing(config);\n\n// Ask the user to enter the floating license key\nConsole.WriteLine(\"Please enter your floating license key: \");\nstring? userKey = Console.ReadLine();\n\ntry\n{\n    var result = await client.RequestFloatingLicenseAsync(userKey, typeof(Program));\n\n    Console.WriteLine($\"License {result.License.Id} requested.\");\n}\ncatch (Exception ex)\n{\n    Console.WriteLine($\"Could not request floating license: {ex.Message}\");\n    return;\n}\n\ntry\n{\n    // Simulate a long task which requires the allocation of a license\n    for (int i = 0; i < 10; i++)\n    {\n        // Validate the license\n        // This will contact the server to validate the license"},{"page":127,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"        var result = await client.ValidateLicenseAsync(userKey, typeof(Program));\n        Console.WriteLine($\"{i}) License {result.License.Id} valid.\");\n\n        // Wait 1 second\n        await Task.Delay(1000);\n    }\n\n    try\n    {\n        // Release the license to allow other clients to use it\n        await client.ReleaseFloatingLicenseAsync(userKey);\n        Console.WriteLine(\"License released.\");\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"Could not release license: {ex.Message}\");\n    }\n\n}\ncatch (Exception ex)\n{\n    Console.WriteLine($\"License not valid: {ex.Message}\");\n    return;\n}\nThe BabelLicensing class is instantiated to communicate with the licensing server. The public key to validate the license is assigned in the service configuration as well as the URL to communicate with the service.\nThe user is prompted to enter the floating license key. The license key is used by the client to request a floating license by calling the RequestFloatingLicenseAsync method. The user key and the type of the program are passed as parameters. If successful, the method returns a result object containing the requested license information."},{"page":127,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"The code simulates a long-running task that requires the allocated license. In a loop, the license is validated using the ValidateLicenseAsync method. The user key and the type of the program are passed as parameters. If the license is valid, the method returns a result object containing the license information. The loop also includes a delay of one second to simulate the task's duration.\nAfter the task is completed, the client releases the floating license using the ReleaseFloatingLicenseAsync method.\nFloating licenses let you share a limited number of licenses across a network of users or machines, with less administrative work than assigning a license to each one. They suit a growing user base, or licenses shared between departments or teams."},{"page":128,"heading":"","anchor":"","text":"License activation is a commonly used method to control the distribution and usage of software licenses. Babel Licensing uses license activation to distribute and activate licenses for your .NET applications securely. This page shows how to create a license on the Babel Licensing Service with Babel Desktop, and how to configure a client .NET application to activate it with the Babel Licensing library."},{"page":128,"heading":"Prerequisites","anchor":"prerequisites","text":"To enable license activation functionality in Babel Licensing Service, follow these steps. First, ensure that Babel Licensing Service is up and running on your server according to the instructions provided in the Getting Started section. Then, create a test product and a corresponding template license by referring to the instructions provided below. This will establish the foundation for generating activation licenses.\nNext, you'll need to download the license activation client source code from GitHub. This client code will be used to integrate license activation capabilities into your .NET application.\ngit clone https://github.com/babelfornet/license-activation-console-example.git\nThe creation of an activation license for this example requires setting up a proper license template in the Babel Licensing system. This template serves as the blueprint for all licenses you'll generate, ensuring consistency and proper configuration."},{"page":128,"heading":"Creating an Activation License","anchor":"creating-an-activation-license","text":"Babel Desktop connects to the Babel Licensing Service and lets you create and configure licenses for your applications. You can specify various details for the license, such as the licensee, the expiration date, and allowed features. Additionally, you can set activation restrictions, such as the maximum number of activations.\nTo register an activation license in Babel Desktop, follow these steps:"},{"page":128,"heading":"Creating an Activation License","anchor":"creating-an-activation-license","text":"Connect to the service\nOpen Babel Desktop and click the icon of your Babel Licensing Service profile in the activity bar. Generating licenses requires a Local test profile with Local management, so run Babel Desktop on the service machine; for a remote service use the web application or the Management API.\nGenerate a license\nOpen the Licenses view and choose Generate license on the toolbar.\nSelect the template and signature key\nIn the Template group, select the license Template created in the previous paragraph (see License Templates) and the Signature key. When no signature key is selected, the key of the template, or of its product, is used.\nSet the mode to Activation\nIn the Terms group, set Mode to Activation.\nSet the number of activations\nIn Sites, enter the number of activations available for this license.\nGenerate the user key\nIn the License information group, press the Generate button at the right end of the User key field. This user key will be used to activate the license on a specific machine.\nEnter the licensee and license details\nEnter the licensee information (a licensee name or company is required) and any additional Fields, Features or Restrictions you want for this license.\nSelect the format\nSelect the license Format: XML, XML signature, ASCII or Base32.\nSave the license\nSave the form. The service generates and signs the license."},{"page":128,"heading":"Creating an Activation License","anchor":"creating-an-activation-license","text":"Info: The public key extracted from the Keys.snk file, which is necessary for license validation, is already configured in the example source code.\nThe newly registered activation license will now appear in the licenses grid with a unique license key and other relevant information. With the Data Center edition you can also create activation licenses on the Licenses page of the web application.\nOnce the activation license is registered, the customer can activate the license on their machine by providing the user key and, if applicable, the machine ID. The Babel Licensing Service will validate the information and issue a license token tied to that specific machine, allowing the software to run. Each activation counts against the token limit of the service; see License Tokens."},{"page":128,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"Once the license is created on the Babel Licensing Service, you need to configure your client .NET application to activate the license. This involves integrating the Babel Licensing library into your application and implementing the necessary code to activate the license. The Babel Licensing library provides a set of APIs and methods that streamline the license activation workflow and ensure secure license validation.\nTo open the license activation sample project, follow these steps:"},{"page":128,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"Open the solution\nNavigate to the location where the license activation sample project is stored and double-click on the ClientActivation.sln solution file to open it in your preferred Integrated Development Environment (IDE), such as Visual Studio.\nCheck the client library reference\nOnce the project is open, ensure that the Babel Licensing client library is referenced correctly. If the reference is missing, please refer to the Client Components paragraph to configure a local NuGet repository.\nBuild the solution\nAfter ensuring the correct references, build the solution by selecting the \"Build\" or \"Rebuild\" option from the IDE's menu.\nRun the application\nOnce the solution is successfully built, you can run the application in debug configuration by pressing the \"Start Debugging\" button or using the keyboard shortcut specific to your IDE (e.g., F5 in Visual Studio). The license activation sample application will launch, allowing you to interact with the licensing functionality and test the license activation process.\n\nLicense Activation Console\nEnter the activation key\nEnter the activation key generated for the license and press ENTER.\nIf the activation key is valid and matches the one set for the license, the license will be successfully activated.\nYou can now deactivate the license or close the application by pressing \"n\".\nClose or deactivate the application\nPress \"n\" then ENTER to close the application."},{"page":128,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"If you restart the application, you will see that the license is still active. This is because the client has been configured to maintain a local cache of the license information. The client will only contact the server once every 5 days to perform remote license validation. This caching mechanism allows the application to continue functioning even if the connection to the server is temporarily unavailable.\nFollows the complete license activation example source code:"},{"page":128,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"using Babel.Licensing;\n\n// Create a new configuration object\nBabelLicensingConfiguration config = new BabelLicensingConfiguration() {\n    // Set the service URL\n    ServiceUrl = \"http://localhost:5005\",\n\n    // Set the public key used to verify the license signature\n    SignatureProvider = RSASignature.FromKeys(\"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDE1VRiIdr6fiVZKve7NVgjIvGdRiRx0Mjjm+Yzf6tLbzFnxLs0fat5EoRcubxx0QQQDfydsJBE/fc7cwRWSrE2xK6X4Eb4W8O47pCMjqvTQZfDqQywEZJrLlxpp9hlKz6FDYX4SagrjmP1gdw8olo+n+IBz8ubkNxRhvycikxuDQIDAQAB\"),\n    \n    // Set a unique client ID\n    ClientId = \"my app client id\"\n};\n\n// Create the client object used to communicate with the server\nBabelLicensing client = new BabelLicensing(config);\n\n// Use BabelServiceLicenseProvider to cache a local copy of the license for offline use\nBabelServiceLicenseProvider provider = new BabelServiceLicenseProvider(client) {\n    // Refresh the license by contacting the server every 5 days\n    // If set to TimeSpan.Zero, the license will be validated every time on the server\n    LicenseRefreshInterval = TimeSpan.FromDays(5)\n};\n\n// Register the license provider with BabelLicenseManager\nBabelLicenseManager.RegisterLicenseProvider(typeof(Program), provider);\n\n// Check if the user key was set\nif (provider.UserKey == null)\n{\n    // If the user key was not entered, the license has not been activated yet.\n\n    // Ask the user to activate the license\n    Console.WriteLine(\"Please enter your activation license key: \");"},{"page":128,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"    string? userKey = Console.ReadLine();\n\n    try\n    {\n        await client.ActivateLicenseAsync(userKey, typeof(Program));\n\n        Console.WriteLine(\"License activated.\");\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"Could not activate license: {ex.Message}\");\n        return;\n    }\n}\n\ntry\n{\n    // Validate the license\n    // This will contact the server to validate the license if the local copy is expired\n    // You can customize the validation interval using the LicenseValidationInterval property\n    var license = await BabelLicenseManager.ValidateAsync(typeof(Program));\n\n    Console.WriteLine($\"License {license.Id} valid.\");\n\n    // Ask to deactivate the license\n    Console.WriteLine(\"Do you want to deactivate the license? (y/n)\");\n    string? answer = Console.ReadLine();\n\n    if (answer?.ToLower() == \"y\")\n    {\n        try\n        {\n            await client.DeactivateLicenseAsync(provider.UserKey);\n            Console.WriteLine(\"License deactivated.\");\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Could not deactivate license: {ex.Message}\");\n        }\n    }\n}\ncatch (Exception ex)\n{\n    Console.WriteLine($\"License not valid: {ex.Message}\");\n    return;\n}\nThe BabelLicensing class is instantiated to communicate with the licensing server. The public key to validate the license is assigned in the service configuration, as well as the URL to communicate with the service."},{"page":128,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"Then, an instance of the BabelServiceLicenseProvider class is instantiated and registered with the BabelLicenseManager. This is responsible for caching a local copy of the license for offline use. The LicenseRefreshInterval property is set to determine how often the license should be refreshed from the server.\nThe code checks if the user key (activation license key) was entered. If it's not set, it means the license has not been activated yet.\nIf the user key is not set, the code prompts the user to enter the activation license key and attempts to activate the license by contacting the server.\nThe code then proceeds to validate the license using the ValidateAsync method of the BabelLicenseManager. This method checks the validity of the license, and if the local copy of the license is expired, it contacts the server for validation.\nAfter validating the license, the code prompts the user to confirm whether they want to deactivate the license. If the user confirms the deactivation, the code calls the DeactivateLicenseAsync method of the BabelLicensing client to deactivate the license.\nOverall, the provided code demonstrates how to interact with the Babel Licensing client library to handle license activation, validation, and deactivation in a client application."},{"page":128,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"The license activation process provides several benefits, such as enhanced security, as it ensures that only authorized users can activate and use the licensed software. It also enables you to track and manage license activations, providing valuable insights into the usage patterns of your application. By leveraging the License Activation feature in Babel Licensing, you can ensure compliance with licensing terms and maintain control over the distribution and usage of your software.\nTo use license activation, create the licenses with Babel Desktop or the web application and configure your client application to activate them. The service then enforces license compliance and helps protect your intellectual property."},{"page":129,"heading":"","anchor":"","text":"License files control software licenses in disconnected or protected environments, where the application may not be able to reach the Babel Licensing Service. You can create a license file in two ways:\noffline, with the lic command line tool, without any service;\non the Babel Licensing Service, with Babel Desktop or the Data Center web application, and then export it.\nThis page shows how to create a license file and how to validate it in your .NET application."},{"page":129,"heading":"Prerequisites","anchor":"prerequisites","text":"The Babel Licensing Service is needed only if you create the license file on the service. In that case, make sure that the Babel Licensing Service is running on your server as per the instructions provided in the Getting Started section. Then, create a test product and a corresponding license template by referring to the instructions below. If you generate the license file offline with lic, you can skip this step.\nNext, you will need to download the license file client source code from GitHub. This client code enables the integration of license file capabilities into your .NET application. Use the following command to clone the repository:\ngit clone https://github.com/babelfornet/license-file-console-example.git\nWhen you create the license file on the Babel Licensing Service, it is based on a corresponding license template."},{"page":129,"heading":"Creating a License File","anchor":"creating-a-license-file","text":"When generating a license file, you can specify various details such as the licensee, the product, the expiration date, the allowed features, and any custom license fields. The license file is digitally signed to ensure its integrity and authenticity."},{"page":129,"heading":"With Babel Desktop","anchor":"with-babel-desktop","text":"To create a license file with Babel Desktop, follow these steps:\nConnect to the service\nOpen Babel Desktop and click the icon of your Babel Licensing Service profile in the activity bar. Generating licenses requires a Local test profile with Local management, so run Babel Desktop on the service machine; for a remote service use the web application or the Management API.\nGenerate a license\nOpen the Licenses view and choose Generate license on the toolbar.\nSelect the template and signature key\nIn the Template group, select the license Template (see License Templates) and the Signature key. When no signature key is selected, the key of the template, or of its product, is used.\nSet the mode to File\nIn the Terms group, set Mode to File. A user key is not needed for a file license.\nEnter the licensee and license details\nEnter the licensee information (a licensee name or company is required), the issue and expire dates, and any Fields and Features required.\nSave the license\nSave the form. The service generates and signs the license, which appears in the licenses grid.\nExport the license file\nSelect the license and choose Export license key… on the toolbar. The file is saved in the license export folder configured in the Licensing settings, named after the license id. Rename it ClientFile.licenses or ClientFile.lic for this example.\nWith the Data Center edition you can also generate and download the license from the Licenses page of the web application."},{"page":129,"heading":"With the lic Command Line","anchor":"with-the-lic-command-line","text":"To create the license file offline, without the Babel Licensing Service, use the lic command line tool. Sign the license with the same key the application uses to validate it; for this example, the Keys.snk file:\nlic ClientFile.dll --keyfile Keys.snk --sign --licensee name=\"Contoso\" --expiredate 365 --feature Pro=1 --output ClientFile.licenses\nEvery option is described in the Reference.\nYou can now distribute the license file to your customers or use it to deploy the license in disconnected or protected environments where the Babel Licensing Service is not accessible."},{"page":129,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"To enable license validation using a license file, you need to integrate the Babel Licensing library into your .NET application. The library provides a set of APIs and methods that facilitate the license validation process. By referencing the Babel Licensing library and incorporating the necessary code, you can ensure that your application validates the license file correctly.\nTo open the license file console sample project, follow these steps:"},{"page":129,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"Locate the sample project\nNavigate to the location where the license file sample project is stored.\nCopy the license file\nCopy the license file ClientFile.licenses in the project folder.\nOpen the solution\nDouble-click on the ClientFile.sln solution file to open it in your preferred Integrated Development Environment (IDE), such as Visual Studio.\nCheck the client library reference\nOnce the project is open, ensure that the Babel Licensing client library is referenced correctly. If the reference is missing, please refer to the Client Components paragraph to configure a local NuGet repository.\nBuild the solution\nAfter ensuring the correct references, build the solution by selecting the \"Build\" or \"Rebuild\" option from the IDE's menu.\nRun the application\nOnce the solution is successfully built, you can run the application in debug configuration by pressing the \"Start Debugging\" button or using the keyboard shortcut specific to your IDE (e.g., F5 in Visual Studio). The license file console sample application will launch, validating the license file and showing the licensee information.\n\nLicense File Validation Example\nFollow the client application source code:"},{"page":129,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"using System;\nusing Babel.Licensing;\n\nclass Program\n{\n    /// <summary>\n    /// Public key used to validate the license signature.\n    /// </summary>\n    static string PublicKey => \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDE1VRiIdr6fiVZKve7NVgjIvGdRiRx0Mjjm+Yzf6tLbzFnxLs0fat5EoRcubxx0QQQDfydsJBE/fc7cwRWSrE2xK6X4Eb4W8O47pCMjqvTQZfDqQywEZJrLlxpp9hlKz6FDYX4SagrjmP1gdw8olo+n+IBz8ubkNxRhvycikxuDQIDAQAB\";\n    \n    static Program()\n    {\n        // Register the file license provider for the Program class\n        // that will be used by the BabelLicenseManager to locate the license file.\n        // The license file should be named as the assembly name with .licenses extension.        \n        BabelFileLicenseProvider provider = new BabelFileLicenseProvider();\n\n        // Sets the public key used to validate the license signature\n        provider.SignatureProvider = RSASignature.FromKeys(PublicKey);\n\n        // Uncomment the following line to customize the license file path\n        // provider.LicenseFilePath = \"license.xml\";\n\n        // Register the provider for the Program class\n        BabelLicenseManager.RegisterLicenseProvider(typeof(Program), provider);\n    }\n\n    static void Main(string[] args)\n    {\n        var program = new Program();\n\n        try\n        {\n            var license = program.ValidateLicense();\n\n            Console.WriteLine($\"License {license.Id} registered to {license.Licensee?.Company}\");\n        }\n        catch (Exception ex)\n        {"},{"page":129,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"            Console.WriteLine(ex.Message);\n        }\n\n        Console.WriteLine(\"Press any key to exit...\");\n        Console.ReadKey();\n    }\n\n    public ILicense ValidateLicense()\n    {\n        // Uses the registered file license provider for Program class\n        return BabelLicenseManager.Validate(typeof(Program), this);\n    }\n}\nInside the static constructor of the Program class, the file license provider is registered using the BabelFileLicenseProvider. This provider is responsible for locating and validating the license file for the Program class. By default, the license file should have the same name as the assembly with the extension .licenses or .lic.\nExtracting and Securing the Public Key\nIn the provided code, the PublicKey property is used to hold the public key required for validating the license signature. It is set to a specific value extracted from the Keys.snk file.\nvar rsa = RSASignature.CreateFromKeyFile(\"Keys.snk\");\nstring publicKey = rsa.ExportKeys(true);\nTo extract the public key from the Keys.snk file, the code uses the RSASignature.CreateFromKeyFile method, passing the file name as the parameter. This method creates an RSASignature object that represents the key pair stored in the Keys.snk file. Then, the ExportKeys method is called on the RSASignature object with the parameter true to export the public key. This method returns a string representation of the public key."},{"page":129,"heading":"Configuring a Client","anchor":"configuring-a-client","text":"Info: The Keys.snk file contains the private key and should not be deployed with the application. The private key must be kept secure and not exposed to unauthorized access.\nUse license files when the application has limited or no connection to the Babel Licensing Service. You generate them with Babel Desktop or the lic command line, and they are easy to deploy and move between systems. The signed file keeps the licensing terms under your control even offline, and your .NET application validates it without contacting the service."},{"page":129,"heading":"License Validation With License Manager","anchor":"license-validation-with-license-manager","text":"In addition to the BabelFileLicenseProvider, Babel Licensing provides alternative methods for license validation using specific license manager classes. These classes, such as XmlLicenseManager and StringLicenseManager, offer flexibility in handling the loading and validation of license keys without relying on the BabelFileLicenseProvider for finding the license file.\nThe XmlLicenseManager class is designed to work with XML-based license files. It allows users to set the public key used for validating the license signature and provides methods to read the license key from an XML file, validate it, and retrieve the validated license object.\nHere's an expanded explanation of the code snippet provided:\npublic ILicense ValidateLicenseWithXmlLicenseManager()\n{\n    // Uses the Xml license manager\n    XmlLicenseManager manager = new XmlLicenseManager();\n\n    // Sets the public key used to validate the license signature\n    manager.SignatureProvider = RSASignature.FromKeys(PublicKey);\n\n    // Reads the license from the license file\n    string licenseKey = File.ReadAllText(\"ClientFile.lic\");\n\n    // Validates the license\n    return manager.Validate(licenseKey, typeof(Program), this);\n}\nThe StringLicenseManager class is another option that allows users to validate license keys directly from an encoded string. This can be useful when the license information is obtained from a different source, such as a database or an API response."},{"page":129,"heading":"License Validation With License Manager","anchor":"license-validation-with-license-manager","text":"Both the XmlLicenseManager and StringLicenseManager classes provide alternative ways to handle license validation and offer flexibility in controlling the loading and validation process. They allow users to define their own logic for accessing the license key and provide a means to verify the license's authenticity and integrity using the specified public key."},{"page":130,"heading":"","anchor":"","text":"In the context of the Babel Licensing Service, license tokens are used to manage licenses and track their usage. There are two types of license tokens: floating license tokens and license activation tokens.\nInfo: Only activation and floating licenses create tokens. File licenses do not, and neither does the online validation of a file license."},{"page":130,"heading":"Floating License Tokens","anchor":"floating-license-tokens","text":"In the case of floating licenses, a token represents a client that is connected to the server and using a specific license. When a client requests a license, the service creates a token for it. The token is released when the client checks the license back in.\nIf the client stops without releasing the license, for example after a crash or a lost network connection, the token expires after the heartbeat interval (Licensing:HeartbeatInterval in the configuration) and the seat becomes available again."},{"page":130,"heading":"License Activation Tokens","anchor":"license-activation-tokens","text":"In the case of license activation, a token represents a machine that has activated a license. The service creates the token when the machine activates, together with the node-locked license issued for that machine.\nThe token expires on the same date as the license. A perpetual activation never expires on its own. The token stays until the machine is deactivated. Deactivating a machine deletes its token and the node-locked license, and the slot is free immediately."},{"page":130,"heading":"How tokens are counted","anchor":"how-tokens-are-counted","text":"The Babel Licensing Service limits the number of active tokens, not the number of tokens ever issued. The limit comes from the license of the service itself:\nEdition | Active tokens\nServer (Server) | 1,000\nData Center (Data Center) | Unlimited\nA token is active while its license is not revoked and the token has not expired. Revoking a license removes its tokens from the count.\nA trial uses a token only if it is delivered as an activation or floating license. A trial shipped as a signed file license with an expiry date uses none."},{"page":130,"heading":"Freeing tokens","anchor":"freeing-tokens","text":"Tokens are freed in these ways:\nThe client deactivates the machine (activation) or releases the license (floating).\nA floating token expires because the client stopped sending heartbeats.\nThe license is revoked or the token reaches its expiry date.\nAn administrator deletes the token. You can do this from Babel Desktop, from the REST management API or from the Data Center web application. It is the way to free the slot of a machine that died before it could be deactivated."},{"page":130,"heading":"Limits and warnings","anchor":"limits-and-warnings","text":"The service checks the number of active tokens against the limit of its license:\nAt 85% of the limit (850 for Server), the service logs a warning and sends an \"approaching limit\" email to the administrator.\nWhen active tokens reach 105% of the limit (1,050 for Server), the service refuses new activations and floating checkouts. The client receives the ServerReachedMaxTokenAllowed error (StatusCode.PermissionDenied): \"The server has reached the maximum number of license tokens allowed\". At this point the service also deletes expired and revoked tokens, which may bring the count back under the threshold.\nStarting with 12.0, the block is checked against a fresh count at every activation and floating checkout. Earlier versions relied on a count refreshed every 5 minutes, so a burst of requests could briefly exceed the threshold. The warning emails are still evaluated every 5 minutes."},{"page":130,"heading":"Reclaiming inactive activations","anchor":"reclaiming-inactive-activations","text":"Starting with 12.0, the service can free the seat of an activation that is no longer used. It is disabled by default. To turn it on, set ReclaimInactiveActivationDays in the Licensing section of the configuration:\n\"Licensing\": {\n  \"ReclaimInactiveActivationDays\": 90\n}\nThe same setting as an environment variable:\nBABEL_SERVICE_LICENSING__RECLAIMINACTIVEACTIVATIONDAYS=90\nThe default is 0, which disables the feature. When a license has used all its seats (MaxAllowedSites) and a new machine asks to activate, the service looks at the existing activations. It frees the seat of the one that has gone the longest without contacting the service, provided that activation is older than the configured number of days, and then activates the new machine. If no activation is old enough, the request fails as before.\nA machine contacts the service when it validates its license online, which updates the last-seen time of its token, or when it activates. The freed seat is handled like a deactivation: the token and its node-locked license are removed, and the license trace and the LicenseDeactivated webhook event are produced when they are enabled."},{"page":130,"heading":"Reclaiming inactive activations","anchor":"reclaiming-inactive-activations","text":"Warning: An application that validates only offline against its node-locked license file never updates the last-seen time, so its seat looks inactive. Also, reclaiming only frees the seat on the server. The node-locked license file of the old machine keeps working offline, and the old machine fails its next online validation with \"license not activated\".\nEnable this setting only if the protected application validates online periodically."},{"page":130,"heading":"Upgrading from Server to Data Center","anchor":"upgrading-from-server-to-data-center","text":"If the tokens of the Server edition are not enough, upgrade to the Data Center edition. The service package is the same. Replace the service license file with the Data Center license and restart the service. The database and the configuration stay as they are."},{"page":131,"heading":"","anchor":"","text":"Babel Licensing provides a comprehensive reporting framework that enables you to collect, analyze, and monitor critical information about your licensed applications. Through automated reporting capabilities, you gain valuable insights into application health, license usage patterns, security events, and custom business metrics."},{"page":131,"heading":"Why Reporting Matters","anchor":"why-reporting-matters","text":"Reporting is essential for understanding how your software is being used in production environments:\nProactive Issue Resolution: Identify and address application crashes before they impact user experience\nLicense Compliance: Monitor feature usage and validate that licenses are being used as intended\nSecurity Monitoring: Detect and respond to potential security threats or unauthorized access attempts\nUsage Analytics: Make data-driven decisions about feature development and licensing strategy\nCustomer Support: Access detailed diagnostic information to resolve customer issues quickly"},{"page":131,"heading":"Report Types","anchor":"report-types","text":"Babel Licensing offers three types of reports, each designed for specific monitoring and analysis needs:\nException Reports\nException Reports capture detailed information about application crashes and errors, providing the context needed to reproduce and fix bugs efficiently.\nKey Capabilities:\nAutomatic exception capture with full stack traces\nEnvironment information (loaded assemblies, processes, environment variables)\nSystem information (hardware, OS, network configuration)\nCustom properties for additional context\nConfigurable data collection to minimize report size\nCommon Use Cases:\nProduction crash monitoring and analysis\nBug reproduction and debugging\nQuality assurance and testing\nCustomer support diagnostics\nLicense Reports\nLicense Reports provide detailed insights into how license components are accessed and used within your applications.\nKey Capabilities:\nAutomatic tracking of feature, field, and restriction access\nUsage statistics (access counts, timestamps, duration)\nLicense metadata and validation status\nSmart server-side merging for historical analysis\nConfigurable tracking scope\nCommon Use Cases:\nFeature adoption analysis\nLicense compliance monitoring\nIdentifying unused features\nUsage pattern tracking\nData-driven licensing strategy\nCustom Reports\nCustom Reports enable you to send any structured data to your Babel Licensing Service, tailored to your application's specific needs.\nKey Capabilities:"},{"page":131,"heading":"Report Types","anchor":"report-types","text":"Flexible report structure using base Report class\nSupport for any custom properties and data\nEnvironment and system information integration\nReport encryption for sensitive data\nEvent-based customization before sending\nCommon Use Cases:\nSecurity event reporting (hack detection, intrusion attempts)\nApplication performance metrics\nBusiness event tracking\nCustom diagnostic data\nAudit trail creation"},{"page":131,"heading":"How Reporting Works","anchor":"how-reporting-works","text":"The Babel Licensing reporting system follows a simple but powerful workflow:\nEnable Tracking (for License Reports): Activate usage tracking before validating licenses\nUse Your Application: Normal application usage automatically collects data\nCreate Report: Build a report instance with the data you want to send\nCustomize: Add custom properties or modify report content via events\nSend Report: Transmit the report to your Babel Licensing Service\nAnalyze: View and analyze reports through the service API or management interface"},{"page":131,"heading":"Reporting Architecture","anchor":"reporting-architecture","text":"The reporting framework is built on several key components:\nClient-Side Components\nReport Classes: Base classes for exception, license, and custom reports\nBabelReporting Service: Client library for sending reports to the server\nUsage Tracking: Automatic license component access monitoring\nData Collectors: Specialized collectors for environment and system information\nServer-Side Processing\nReport Validation: Ensures reports are properly formatted and authorized\nDecryption: Handles encrypted report content\nReport Parsing: Extracts properties for indexing and searching\nSmart Merging: Combines license reports for comprehensive historical analysis\nWebhook Integration: Dispatches events for external system integration"},{"page":131,"heading":"Configuration and Customization","anchor":"configuration-and-customization","text":"All report types support extensive configuration to balance data richness with privacy and performance:\nData Collection Options\nControl exactly what information gets included in reports:\nreporting.Configuration.ExceptionReportOptions = new ExceptionReportOptions\n{\n    CollectApplicationInformation = true,\n    CollectEnvironmentVariables = false,  // Privacy-sensitive\n    CollectSystemInformation = true,\n    CollectProcessorInformation = true,\n    CollectMemoryInformation = true\n};\nReport Encryption\nProtect sensitive data during transmission:\nreporting.Configuration.EncryptionKey = \"your-secret-key\";\nCustom Properties\nAdd application-specific context to any report:\nreporting.BeforeSendReport += (s, e) =>\n{\n    e.Report.Properties.Add(\"environment\", \"production\");\n    e.Report.Properties.Add(\"deployment_id\", deploymentId);\n    e.Report.Properties.Add(\"user_tier\", \"enterprise\");\n};\nError Handling\nGracefully handle reporting failures:\nreporting.AfterSendReport += (s, e) =>\n{\n    if (e.Error != null)\n    {\n        Logger.Error($\"Failed to send report: {e.Error.Message}\");\n        StoreForRetry(e.Report);\n    }\n};"},{"page":131,"heading":"Getting Started with Reporting","anchor":"getting-started-with-reporting","text":"Initialize the reporting service\nusing Babel.Licensing.Services;\n\nvar reporting = new BabelReporting();\nreporting.Configuration.ServiceUrl = \"https://licensing.example.com\";\nreporting.Configuration.ClientId = \"MyApplication v1.0\";\nSend exception reports\ntry\n{\n    // Your application code\n}\ncatch (Exception ex)\n{\n    await reporting.SendExceptionReportAsync(userKey, ex);\n}\nEnable license tracking\nusing Babel.Licensing.Reports;\n\n// Enable before validation\nLicenseUsageTracking.Enable();\n\n// Validate license\nvar license = licenseManager.Validate(userKey, keyType);\n\n// Use licensed features (automatically tracked)\nvar data = license.Features[\"Reporting\"].Data;\n\n// Send tracking report\nawait reporting.SendLicenseReportAsync(userKey);\nCreate custom reports\npublic class SecurityEventReport : Report\n{\n    public string EventType { get; set; }\n    public string Severity { get; set; }\n\n    public SecurityEventReport() : base(\"SecurityEvent\") { }\n\n    public override void Build()\n    {\n        Properties.Add(\"event_type\", EventType);\n        Properties.Add(\"severity\", Severity);\n        base.Build();\n    }\n}\n\n// Send custom report\nvar report = new SecurityEventReport\n{\n    EventType = \"UnauthorizedAccess\",\n    Severity = \"High\"\n};\nawait reporting.SendAsync(userKey, report);"},{"page":131,"heading":"Best Practices","anchor":"best-practices","text":"Minimize Data Collection\nOnly collect data you actually need to reduce report size and protect privacy:\nreporting.Configuration.ExceptionReportOptions = new ExceptionReportOptions\n{\n    CollectSystemInformation = true,      // Essential\n    CollectDisplayInformation = false,    // Usually not needed\n    CollectProcessInformation = false     // Privacy-sensitive\n};\nSend Reports Periodically\nFor license reports, send at regular intervals rather than continuously:\nvar timer = new Timer(async _ =>\n{\n    await reporting.SendLicenseReportAsync(userKey);\n    LicenseUsageTracking.Clear();  // Reset for next period\n}, null, TimeSpan.FromHours(24), TimeSpan.FromHours(24));\nHandle Offline Scenarios\nStore reports locally when the server is unreachable:\nvar result = await reporting.SendLicenseReportAsync(userKey);\nif (!result.Success)\n{\n    SaveReportForLater(result.Report);\n}\nSanitize Sensitive Data\nNever include passwords, API keys, or personally identifiable information:\nreporting.BeforeSendReport += (s, e) =>\n{\n    // Remove or hash sensitive data\n    e.Report.Properties[\"username\"] = HashUsername(username);\n    // Don't include passwords, credit cards, etc.\n};\nUse Encryption for Sensitive Reports\nEnable encryption for reports containing sensitive information:\nreporting.Configuration.EncryptionKey = Configuration[\"Reporting:EncryptionKey\"];"},{"page":131,"heading":"Report Analysis and Monitoring","anchor":"report-analysis-and-monitoring","text":"Once reports reach your Babel Licensing Service, you can:\nQuery Reports: Search and filter reports through the service API\nView Details: Examine complete report content and metadata\nTrack Trends: Monitor changes in crash rates, usage patterns, or security events\nExport Data: Extract report data for analysis in external tools\nSet Alerts: Configure webhooks to notify external systems of critical events"},{"page":131,"heading":"Integration with Licensing Modes","anchor":"integration-with-licensing-modes","text":"Reporting works seamlessly with all Babel Licensing modes:\nLicense File: Use license data for report authorization\nLicense Activation: Track activation-based licenses\nFloating License: Monitor concurrent usage patterns\nUser keys generated through activation or floating license workflows serve as authorization credentials for sending reports."},{"page":131,"heading":"Performance Considerations","anchor":"performance-considerations","text":"The reporting system is designed for minimal performance impact:\nAsynchronous Operations: All report sending is non-blocking\nConfigurable Collection: Disable expensive collectors you don't need\nEfficient Tracking: Usage tracking uses observer pattern with minimal overhead\nSmart Caching: Environment and system data is cached to avoid repeated collection\nCompression: Reports are compressed during transmission"},{"page":131,"heading":"Documentation Structure","anchor":"documentation-structure","text":"This section provides detailed documentation for each report type:\nException Reports: Comprehensive guide to crash and error reporting\nLicense Reports: Complete license usage tracking documentation\nCustom Reports: Creating and sending custom report types\nEach page includes practical examples, configuration options, best practices, and real-world use cases to help you implement effective reporting in your applications."},{"page":132,"heading":"","anchor":"","text":"Exception reporting is crucial in identifying and addressing application crashes and errors. Babel Licensing Services offers a powerful feature for collecting and analyzing application fault reports.\nIn this article, we will explore an example code console_exception_report_example, which demonstrates the usage of Babel Licensing client library to send application exception reports to Babel Licensing Service. By leveraging this example code, developers can gain insights into the root causes of exceptions and improve the stability and reliability of their applications."},{"page":132,"heading":"Application Exception Report Example","anchor":"application-exception-report-example","text":"To get started with the console_exception_report_example, follow these steps:\nOpen a Git client\nOpen your preferred Git client or the command line.\nClone the repository\nClone the GitHub repository by executing the following command:\ngit clone https://github.com/babelfornet/console-exception-report-example.git\nNavigate to the project directory\nOnce the repository is cloned, navigate to the project directory:\ncd console_exception_report_example\nExplore and run the example\nYou are now ready to explore and run the example code.\nThe console_exception_report_example demonstrates how to integrate the Babel Licensing client library into your application to capture and send exception reports to the Babel Licensing Service. Here's a breakdown of the code:\nBabelReporting Initialization: The example code initializes a BabelReporting object, which serves as the interface to the Babel Licensing client library.\nUser Key: The example code assigns a user key (UserKey) to authorize the client to report exceptions. Make sure to replace it with a valid user key. To generate a user key please refer to the Floating License or License Activation paragraphs.\nConfiguration: The Babel Reporting Service URL is configured to connect to the Babel Licensing Service. Adjust the URL if necessary.\n// Configure Babel Reporting Service URL\nreporting.Configuration.ServiceUrl = \"http://127.0.0.1:5005\";"},{"page":132,"heading":"Application Exception Report Example","anchor":"application-exception-report-example","text":"BeforeSendReport Event: The example code subscribes to the BeforeSendReport event, which allows you to customize the exception report before it is sent. In this event handler, custom properties like cmdline (command line) and username (current user's name) are added to the report.\nreporting.BeforeSendReport += (s, e) => {\n\n   // Set report custom properties\n   e.Report.Properties.Add(\"cmdline\", Environment.CommandLine);\n   e.Report.Properties.Add(\"username\", Environment.UserName);\n};\nException Handling and Reporting: The code presents a menu to simulate different types of exceptions. When an exception occurs, it is caught, and the exception details, including the stack trace, are displayed. The SendExceptionReport method from the BabelReporting object is then invoked to send the exception report to the Babel Licensing Service.\nstatic async void TryThrowException(Action throwException)\n{\n   try\n   {\n      throwException();\n   }\n   catch (Exception ex)\n   {\n      Console.WriteLine(\"Exception thrown:\");\n      Console.WriteLine(ex.StackTrace);\n\n      reporting.SendExceptionReport(UserKey, ex);\n   }\n}\nException Examples: The example code includes four exception scenarios: DivideByZeroException, IndexOutOfRangeException, ArgumentNullException, and OutOfMemoryException. Each scenario demonstrates a specific type of exception being thrown and caught with relevant code snippets."},{"page":132,"heading":"Application Exception Report Example","anchor":"application-exception-report-example","text":"Reports sent by the example can be browsed in the Reports view of Babel Desktop or, with the Data Center edition, on the Reports page of the web application.\nThe console_exception_report_example provides a practical demonstration of how to leverage Babel Licensing Services to collect and analyze application fault reports. By integrating the Babel Licensing client library into your own applications and utilizing the example code, you can gain valuable insights into application crashes, accelerate bug resolution, enhance user experience, and make data-driven decisions for future improvements. Clone the repository, explore the code, and leverage the power of exception reporting to improve the stability and reliability of your applications."},{"page":133,"heading":"","anchor":"","text":"License reporting provides detailed insights into how your application uses licensed features, fields, and restrictions. By enabling license usage tracking, you can monitor feature adoption, validate compliance, and make data-driven decisions about licensing strategy."},{"page":133,"heading":"Overview","anchor":"overview","text":"The Babel Licensing library includes a powerful tracking system that automatically monitors access to license components:\nFeature Usage: Track which features are accessed, how often, and by which members\nField Access: Monitor which license fields are read and their values\nRestriction Validation: Record restriction checks and validation results\nAutomatic Collection: Usage data is captured transparently without code changes\nSmart Merging: Server-side intelligence combines reports for comprehensive analysis"},{"page":133,"heading":"Console Application Example","anchor":"console-application-example","text":"To get started with a practical example, clone the console-licensing-report-example repository which demonstrates how to track license usage and send license reports using Babel Reporting functionality.\nOpen a Git client\nOpen your preferred Git client or the command line.\nClone the repository\nClone the GitHub repository by executing the following command:\ngit clone https://github.com/babelfornet/console-licensing-report-example.git\nNavigate to the project directory\nOnce the repository is cloned, navigate to the project directory:\ncd console-licensing-report-example\nExplore and run the example\nYou are now ready to explore and run the example code.\nThe console-licensing-report-example demonstrates how to integrate the Babel Licensing client library into your application to track license usage and send license reports to the Babel Licensing Service. Here's a breakdown of the code:\nBabelReporting and BabelLicensing Initialization: The example code initializes both a BabelReporting object for sending reports and a BabelLicensing object for license validation."},{"page":133,"heading":"Console Application Example","anchor":"console-application-example","text":"private BabelReporting CreateReportingClient()\n{\n    var reporting = new BabelReporting();\n\n    reporting.Configuration.ClientId = ClientId;\n    reporting.Configuration.ServiceUrl = ServiceUrl;\n    reporting.Configuration.UseHttp(http => {\n        http.Timeout = TimeSpan.FromSeconds(3);\n        http.Handler = new HttpClientHandler() {\n            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true\n        };\n    });\n\n    reporting.BeforeSendReport += (s, e) => {\n        e.Report.Properties.Add(\"cmdline\", Environment.CommandLine);\n        e.Report.Properties.Add(\"username\", Environment.UserName);\n    };\n\n    return reporting;\n}\n\nprivate BabelLicensing CreateLicensingClient()\n{\n    var config = new BabelLicensingConfiguration()\n    {\n        ServiceUrl = ServiceUrl,\n        SignatureProvider = RSASignature.FromKeys(PublicKey),\n        ClientId = ClientId\n    };\n\n    config.UseHttp(http => {\n        http.Timeout = TimeSpan.FromSeconds(10);\n        http.Handler = new HttpClientHandler()\n        {\n            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true\n        };\n    });\n\n    // Register custom license factory to handle MemoryRestriction\n    config.LicenseFactory = new CustomLicenseFactory();\n\n    return new BabelLicensing(config);\n}"},{"page":133,"heading":"Console Application Example","anchor":"console-application-example","text":"User Key and Public Key: The example code uses a user key (UserKey) to authorize the client and a public key (PublicKey) for license signature verification. Make sure to replace these with valid keys. To generate a user key please refer to the Floating License or License Activation paragraphs.\nLicense Validation with Tracking: The example demonstrates how to validate a floating license and access its features, fields, and restrictions. All access is automatically tracked when LicenseUsageTracking is enabled:"},{"page":133,"heading":"Console Application Example","anchor":"console-application-example","text":"private async Task ValidateLicenseAsync()\n{\n    try\n    {\n        // Acquire floating license\n        var requestResult = await _licensing.RequestFloatingLicenseAsync(UserKey, typeof(Program));\n        Console.WriteLine($\"Floating license {requestResult.License.Id} acquired.\");\n\n        try\n        {\n            // Validate the license (this will be tracked)\n            var result = await _licensing.ValidateLicenseAsync(UserKey, typeof(Program));\n            var license = result.License;\n\n            Console.WriteLine($\"License validated: {license.Id}\");\n\n            foreach (var feature in license.Features)\n            {\n                Console.WriteLine($\" Feature: {feature.Name} - {feature.Description}\");\n            }\n\n            foreach (var field in license.Fields)\n            {\n                Console.WriteLine($\" Field: {field.Name} = {field.Value}\");\n            }\n\n            foreach (var restriction in license.Restrictions)\n            {\n                Console.WriteLine($\" Restriction: {restriction.Name}\");\n            }\n\n            // Simulate multiple accesses to demonstrate tracking\n            var reportingFeature = license.Features.FirstOrDefault(f => f.Name == \"Reporting\");\n            var field2Field = license.Fields.FirstOrDefault(f => f.Name == \"field2\");\n\n            for (int i = 0; i < 5; i++)\n            {\n                var _ = reportingFeature?.Data;\n                var __ = field2Field?.Value;\n            }\n"},{"page":133,"heading":"Console Application Example","anchor":"console-application-example","text":"            Console.WriteLine($\"\\nLicense validation completed.\");\n        }\n        finally\n        {\n            // Always release the floating license when done\n            await _licensing.ReleaseFloatingLicenseAsync(UserKey);\n            Console.WriteLine(\"Floating license released.\");\n        }\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"Error validating license: {ex.Message}\");\n    }\n}\nSending the License Report: The SendLicenseReportAsync method sends the accumulated tracking data to the Babel Licensing Service:\nprivate async Task SendLicenseReportAsync()\n{\n    var result = await _reporting.SendLicenseReportAsync(UserKey);\n    if (result.IsError)\n    {\n        Console.WriteLine($\"Error sending LicenseReport: {result.Error}\");\n        return;\n    }\n    Console.WriteLine(\"LicenseReport sent.\");\n}\nCustom License Factory: The example includes a custom MemoryRestriction class and CustomLicenseFactory to demonstrate how to handle custom restriction types in your licenses:"},{"page":133,"heading":"Console Application Example","anchor":"console-application-example","text":"class MemoryRestriction : Restriction, ILicenseSerializable\n{\n    public override string Name => \"Memory\";\n    public long TotalMemory { get; set; }\n\n    public override ValidationResult Validate(ILicenseContext context, Type type, object instance)\n    {\n        ISystemInformation sys = (ISystemInformation)context.GetService(typeof(ISystemInformation));\n\n        long totalMem = ToMegabytes(sys.TotalPhysicalMemory);\n        if (totalMem < TotalMemory)\n            return ValidationResult.Invalid;\n\n        return base.Validate(context, type, instance);\n    }\n\n    private static long ToMegabytes(long bytes)\n    {\n        return bytes / 1024 / 1024;\n    }\n\n    // ILicenseSerializable implementation...\n}\n\nclass CustomLicenseFactory : ILicenseFactory\n{\n    public Restriction CreateRestriction(string type)\n    {\n        string[] tokens = type.Split(':');\n        string restriction = tokens[0];\n\n        switch (restriction)\n        {\n            case \"Memory\":\n                var memory = new MemoryRestriction();\n                if (tokens.Length > 1)\n                    memory.TotalMemory = long.Parse(tokens[1]);\n                return memory;\n            default:\n                return null!;\n        }\n    }\n\n    // Other ILicenseFactory methods...\n}\nLicense Report Example"},{"page":133,"heading":"Console Application Example","anchor":"console-application-example","text":"The console-licensing-report-example provides a practical demonstration of how to track license usage and send reports to the Babel Licensing Service. By integrating license tracking into your applications, you can monitor feature adoption, validate compliance, and make data-driven decisions about your licensing strategy."},{"page":133,"heading":"Enabling License Tracking","anchor":"enabling-license-tracking","text":"To start tracking license usage, enable tracking before validating your license:\nusing Babel.Licensing.Reports;\n\n// Enable tracking (must be called before license validation)\nLicenseUsageTracking.Enable();\n\n// Validate your license as usual\nvar license = licenseManager.Validate(key, type);\n\n// Use licensed features - access is automatically tracked\nvar reportingFeature = license.Features[\"Reporting\"];\nvar data = reportingFeature.Data;\n\nvar versionField = license.Fields[\"Version\"];\nvar version = versionField.Value;"},{"page":133,"heading":"Sending License Reports","anchor":"sending-license-reports","text":"Once you've enabled tracking, you can send reports to your Babel Licensing Service:\nusing Babel.Licensing.Services;\n\n// Initialize the reporting service\nvar reporting = new BabelReporting();\nreporting.Configuration.ServiceUrl = \"https://licensing.example.com\";\nreporting.Configuration.ClientId = \"MyApplication\";\n\n// Send the license report\nvar result = await reporting.SendLicenseReportAsync(userKey);\n\nif (result.Success)\n{\n    Console.WriteLine($\"Report sent successfully: {result.ReportUid}\");\n}\nelse\n{\n    Console.WriteLine($\"Failed to send report: {result.Error?.Message}\");\n}"},{"page":133,"heading":"What Gets Tracked","anchor":"what-gets-tracked","text":"Feature Access Tracking\nFor each feature accessed in your license:\n// This access is automatically tracked\nvar feature = license.Features[\"Reporting\"];\nvar data = feature.Data;  // Tracked: get_Data on Reporting feature\nTracked Information:\nFeature name and ID\nMember accessed (e.g., get_Data, get_IsEnabled)\nNumber of accesses\nFirst access timestamp\nLast access timestamp\nTotal access duration (time between first and last access)\nField Access Tracking\nFor each field read from your license:\n// This access is automatically tracked\nvar field = license.Fields[\"Version\"];\nvar value = field.Value;  // Tracked: get_Value on Version field\nTracked Information:\nField name\nField value (truncated to 12 characters for privacy)\nMember accessed (e.g., get_Value)\nAccess counts and timestamps\nRestriction Validation Tracking\nFor each restriction checked:\n// This validation is automatically tracked\nvar validation = license.Restrictions.Validate();\nTracked Information:\nRestriction name and type\nValidation result (Pass/Fail)\nMember accessed\nAccess counts and timestamps"},{"page":133,"heading":"Report Content","anchor":"report-content","text":"Each license report includes three main sections:\n1. License Metadata\nBasic information about the license being tracked:\n{\n  \"license_id\": \"L-ABC-123\",\n  \"license_type\": \"Standard\",\n  \"issue_date\": \"2025-01-15\",\n  \"expire_date\": \"2026-01-15\",\n  \"support_expire_date\": \"2025-07-15\",\n  \"licensee_name\": \"John Smith\",\n  \"licensee_company\": \"ACME Corporation\",\n  \"product_name\": \"EquiTrack\",\n  \"product_version\": \"2.0\"\n}\n2. Usage Tracking Data\nDetailed access statistics for all tracked components:\n{\n  \"features\": [\n    {\n      \"id\": \"F-001\",\n      \"name\": \"Reporting\",\n      \"members\": [\n        {\n          \"member\": \"get_Data\",\n          \"access_count\": 15,\n          \"first_access\": \"2025-01-20T10:30:00Z\",\n          \"last_access\": \"2025-01-20T14:45:00Z\",\n          \"access_time\": \"04:15:00\"\n        }\n      ]\n    }\n  ],\n  \"fields\": [\n    {\n      \"name\": \"Version\",\n      \"value\": \"2.0.1\",\n      \"members\": [\n        {\n          \"member\": \"get_Value\",\n          \"access_count\": 3,\n          \"first_access\": \"2025-01-20T10:00:00Z\"\n        }\n      ]\n    }\n  ],\n  \"restrictions\": [\n    {\n      \"name\": \"MachineLock\",\n      \"type\": \"Hardware\",\n      \"members\": [\n        {\n          \"member\": \"Validate\",\n          \"access_count\": 1,\n          \"validation_result\": \"Pass\",\n          \"first_access\": \"2025-01-20T10:00:00Z\"\n        }\n      ]\n    }\n  ]\n}\n3. Environment and System Information\nContext about the application and machine (configurable):"},{"page":133,"heading":"Report Content","anchor":"report-content","text":"Application name, version, and loaded assemblies\nOperating system details\nHardware information (CPU, memory, disk)\nNetwork adapters\nEnvironment variables (filtered)\nRunning processes (optional)"},{"page":133,"heading":"Configuration Options","anchor":"configuration-options","text":"Customize what data gets included in your license reports:\nvar reporting = new BabelReporting();\n\n// Configure license report options\nreporting.Configuration.LicenseReportOptions = new LicenseReportOptions\n{\n    // What to track\n    CollectFeaturesAccess = true,\n    CollectFieldsAccess = true,\n    CollectRestrictionsAccess = true,\n\n    // Filter specific members (optional)\n    CollectMembers = new List<string> { \"get_Data\", \"get_IsEnabled\" },\n\n    // Environment information\n    Environment = new EnvironmentReportOptions\n    {\n        CollectApplicationInformation = true,\n        CollectLoadedAssemblies = true,\n        CollectEnvironmentVariables = false,\n        CollectProcessInformation = false\n    },\n\n    // System information\n    System = new SystemReportOptions\n    {\n        CollectSystemInformation = true,\n        CollectOsInformation = true,\n        CollectProcessorInformation = true,\n        CollectMemoryInformation = true,\n        CollectDiskInformation = false,\n        CollectDisplayInformation = false,\n        CollectNetworkInformation = false\n    },\n\n    // Output options\n    Formatted = true,  // Pretty-print JSON\n    EncryptionKey = \"my-secret-key\"  // Optional encryption\n};"},{"page":133,"heading":"Managing Tracked Data","anchor":"managing-tracked-data","text":"Check Tracking Status\nif (LicenseUsageTracking.IsEnabled)\n{\n    Console.WriteLine(\"License tracking is active\");\n}\nAccess Tracked Information\n// Get all tracked licenses\nforeach (var info in LicenseUsageTracking.TrackedLicenses)\n{\n    Console.WriteLine($\"License: {info.LicenseId}\");\n    Console.WriteLine($\"Product: {info.ProductName} v{info.ProductVersion}\");\n\n    // Feature access details\n    foreach (var feature in info.TrackedFeatures)\n    {\n        Console.WriteLine($\"  Feature {feature.Name}:\");\n        Console.WriteLine($\"    Accesses: {feature.AccessCount}\");\n        Console.WriteLine($\"    First: {feature.FirstAccessTime}\");\n        Console.WriteLine($\"    Last: {feature.LastAccessTime}\");\n    }\n\n    // Field access details\n    foreach (var field in info.TrackedFields)\n    {\n        Console.WriteLine($\"  Field {field.Name}: {field.AccessCount} accesses\");\n    }\n\n    // Restriction validation details\n    foreach (var restriction in info.TrackedRestrictions)\n    {\n        Console.WriteLine($\"  Restriction {restriction.Name}: {restriction.AccessCount} checks\");\n    }\n}\nGet Specific License Tracking\nvar trackingInfo = LicenseUsageTracking.GetTrackingInfo(\"L-ABC-123\");\nif (trackingInfo != null)\n{\n    Console.WriteLine($\"Tracking {trackingInfo.TrackedFeatures.Count()} features\");\n}\nClear Tracking Data\n// Clear all tracked data without disabling tracking\nLicenseUsageTracking.Clear();\nDisable Tracking\n// Disable tracking and clear all data\nLicenseUsageTracking.Disable();"},{"page":133,"heading":"Customizing Reports","anchor":"customizing-reports","text":"Add custom properties to your license reports using the BeforeSendReport event:\nreporting.BeforeSendReport += (s, e) =>\n{\n    // Add custom metadata\n    e.Report.Properties.Add(\"application_mode\", \"production\");\n    e.Report.Properties.Add(\"user_count\", activeUsers);\n    e.Report.Properties.Add(\"deployment_id\", deploymentId);\n\n    // Cancel sending if needed\n    if (shouldSkipReport)\n    {\n        e.Cancel = true;\n    }\n};"},{"page":133,"heading":"Report Merging","anchor":"report-merging","text":"The Babel Licensing Service automatically merges license reports from the same client and machine. This provides:\nCumulative Statistics: Access counts are added together\nTimeline Preservation: Earliest first access and latest last access are maintained\nHistorical Analysis: Complete usage patterns over time\nStorage Efficiency: Single comprehensive report per license/machine/client\nWhen a new report arrives, the server:\nIdentifies existing reports for the same license ID, machine ID, and client ID\nMerges tracking data by component name and member\nAccumulates access counts\nUpdates access time ranges\nRefreshes metadata with latest values"},{"page":133,"heading":"Error Handling","anchor":"error-handling","text":"Handle report sending failures gracefully:\nreporting.AfterSendReport += (s, e) =>\n{\n    if (e.Error != null)\n    {\n        // Log the error\n        logger.LogError(e.Error, \"Failed to send license report\");\n\n        // Store report locally for retry\n        SaveReportForRetry(e.Report);\n    }\n    else\n    {\n        logger.LogInformation($\"Report sent: {e.Result.ReportUid}\");\n    }\n};\n\nvar result = await reporting.SendLicenseReportAsync(userKey);"},{"page":133,"heading":"Best Practices","anchor":"best-practices","text":"1. Enable Early\nEnable tracking before validating your license to capture all access from the start:\n// GOOD: Enable before validation\nLicenseUsageTracking.Enable();\nvar license = licenseManager.Validate(key, type);\n\n// BAD: Enable after validation (misses initial access)\nvar license = licenseManager.Validate(key, type);\nLicenseUsageTracking.Enable();\n2. Send Periodically\nSend reports at regular intervals or application shutdown:\n// Option 1: Periodic reporting\nvar timer = new Timer(async _ =>\n{\n    if (LicenseUsageTracking.IsEnabled)\n    {\n        await reporting.SendLicenseReportAsync(userKey);\n        LicenseUsageTracking.Clear();  // Reset for next period\n    }\n}, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1));\n\n// Option 2: On application shutdown\nAppDomain.CurrentDomain.ProcessExit += async (s, e) =>\n{\n    await reporting.SendLicenseReportAsync(userKey);\n};\n3. Minimize Data Collection\nOnly collect data you need to reduce report size and network usage:\nreporting.Configuration.LicenseReportOptions = new LicenseReportOptions\n{\n    CollectFeaturesAccess = true,   // Essential\n    CollectFieldsAccess = false,    // Skip if not needed\n    CollectRestrictionsAccess = true,  // For compliance\n\n    System = new SystemReportOptions\n    {\n        CollectSystemInformation = true,\n        CollectDiskInformation = false,  // Skip to reduce size\n        CollectDisplayInformation = false\n    }\n};\n4. Handle Offline Scenarios\nStore reports locally when the server is unreachable:"},{"page":133,"heading":"Best Practices","anchor":"best-practices","text":"var result = await reporting.SendLicenseReportAsync(userKey);\n\nif (!result.Success)\n{\n    // Serialize and store report\n    var reportJson = JsonSerializer.Serialize(result.Report);\n    await File.WriteAllTextAsync(\"pending-reports/report-\" + Guid.NewGuid() + \".json\", reportJson);\n}\n5. Protect Sensitive Data\nUse encryption for reports containing sensitive information:\nreporting.Configuration.EncryptionKey = Configuration[\"Reporting:EncryptionKey\"];\nreporting.Configuration.LicenseReportOptions.EncryptionKey = reporting.Configuration.EncryptionKey;"},{"page":133,"heading":"Example: Complete License Tracking","anchor":"example-complete-license-tracking","text":"Here's a comprehensive example demonstrating license tracking in a real application:"},{"page":133,"heading":"Example: Complete License Tracking","anchor":"example-complete-license-tracking","text":"using Babel.Licensing;\nusing Babel.Licensing.Reports;\nusing Babel.Licensing.Services;\n\npublic class LicenseManager\n{\n    private readonly BabelReporting _reporting;\n    private readonly Timer _reportTimer;\n\n    public LicenseManager(IConfiguration configuration)\n    {\n        // Initialize reporting service\n        _reporting = new BabelReporting();\n        _reporting.Configuration.ServiceUrl = configuration[\"Licensing:ServiceUrl\"];\n        _reporting.Configuration.ClientId = \"EquiTrack v2.0\";\n        _reporting.Configuration.EncryptionKey = configuration[\"Licensing:EncryptionKey\"];\n\n        // Configure what to track\n        _reporting.Configuration.LicenseReportOptions = new LicenseReportOptions\n        {\n            CollectFeaturesAccess = true,\n            CollectFieldsAccess = true,\n            CollectRestrictionsAccess = true,\n            Environment = new EnvironmentReportOptions\n            {\n                CollectApplicationInformation = true,\n                CollectLoadedAssemblies = true\n            },\n            System = new SystemReportOptions\n            {\n                CollectSystemInformation = true,\n                CollectOsInformation = true,\n                CollectProcessorInformation = true,\n                CollectMemoryInformation = true\n            },\n            Formatted = false  // Compact JSON for network efficiency\n        };\n\n        // Add custom properties before sending\n        _reporting.BeforeSendReport += (s, e) =>\n        {"},{"page":133,"heading":"Example: Complete License Tracking","anchor":"example-complete-license-tracking","text":"            e.Report.Properties.Add(\"environment\", configuration[\"Environment\"]);\n            e.Report.Properties.Add(\"version\", Assembly.GetExecutingAssembly().GetName().Version.ToString());\n        };\n\n        // Handle send results\n        _reporting.AfterSendReport += (s, e) =>\n        {\n            if (e.Error != null)\n            {\n                Logger.Error($\"Failed to send license report: {e.Error.Message}\");\n            }\n            else\n            {\n                Logger.Info($\"License report sent: {e.Result.ReportUid}\");\n            }\n        };\n\n        // Send reports every 24 hours\n        _reportTimer = new Timer(\n            async _ => await SendLicenseReportAsync(),\n            null,\n            TimeSpan.FromHours(24),\n            TimeSpan.FromHours(24)\n        );\n    }\n\n    public ILicense ValidateLicense(string userKey, LicenseKeyTypes keyType)\n    {\n        // Enable tracking before validation\n        LicenseUsageTracking.Enable();\n\n        // Validate license\n        var licenseManager = new BabelLicensing();\n        var license = licenseManager.Validate(userKey, keyType);\n\n        return license;\n    }\n\n    public async Task SendLicenseReportAsync()\n    {\n        if (!LicenseUsageTracking.IsEnabled)\n            return;\n\n        try\n        {\n            var result = await _reporting.SendLicenseReportAsync(_userKey);\n\n            if (result.Success)\n            {\n                // Clear tracking data after successful send"},{"page":133,"heading":"Example: Complete License Tracking","anchor":"example-complete-license-tracking","text":"                LicenseUsageTracking.Clear();\n            }\n        }\n        catch (Exception ex)\n        {\n            Logger.Error($\"Exception sending license report: {ex.Message}\");\n        }\n    }\n\n    public void Shutdown()\n    {\n        // Send final report on shutdown\n        SendLicenseReportAsync().Wait(TimeSpan.FromSeconds(10));\n\n        // Cleanup\n        _reportTimer?.Dispose();\n        LicenseUsageTracking.Disable();\n    }\n}"},{"page":133,"heading":"Server-Side Analysis","anchor":"server-side-analysis","text":"Once reports reach your Babel Licensing Service, you can:\nMonitor Feature Adoption: See which features are used most frequently\nIdentify Unused Features: Find features that are never accessed\nTrack Usage Patterns: Analyze access times and frequencies\nValidate Compliance: Ensure restrictions are being checked\nPlan Licensing Strategy: Make data-driven decisions about feature packaging\nReports are stored with full metadata and can be queried through the Babel Licensing Service API or viewed in the management interface."},{"page":133,"heading":"Related Topics","anchor":"related-topics","text":"Exception Reports - Send crash and error reports\nCustom Reports - Create your own report types\nFloating License - Generate user keys for reporting\nLicense Activation - Activate licenses for tracking"},{"page":134,"heading":"","anchor":"","text":"In addition to built-in exception and license reports, Babel Licensing allows you to create custom reports tailored to your application's specific needs. Custom reports enable you to send any structured data to your Babel Licensing Service for centralized collection, analysis, and monitoring."},{"page":134,"heading":"Overview","anchor":"overview","text":"Custom reports are useful for:\nSecurity Events: Detect and report potential hacking attempts, unauthorized access, or suspicious behavior\nApplication Metrics: Track custom application performance or usage metrics\nBusiness Events: Report significant business events or milestones\nDiagnostics: Send custom diagnostic data for troubleshooting\nAudit Trails: Create audit logs for compliance requirements"},{"page":134,"heading":"Console Application Example","anchor":"console-application-example","text":"To get started with a practical example, clone the console-custom-report-example repository which demonstrates how to create and send custom reports using Babel Reporting functionality.\nOpen a Git client\nOpen your preferred Git client or the command line.\nClone the repository\nClone the GitHub repository by executing the following command:\ngit clone https://github.com/babelfornet/console-custom-report-example.git\nNavigate to the project directory\nOnce the repository is cloned, navigate to the project directory:\ncd console-custom-report-example\nExplore and run the example\nYou are now ready to explore and run the example code.\nThe console-custom-report-example demonstrates how to integrate the Babel Licensing client library into your application to create and send custom reports to the Babel Licensing Service. Here's a breakdown of the code:\nBabelReporting Initialization: The example code initializes a BabelReporting object and configures it with the service URL and client identifier."},{"page":134,"heading":"Console Application Example","anchor":"console-application-example","text":"private BabelReporting CreateReportingClient()\n{\n    var reporting = new BabelReporting();\n\n    reporting.Configuration.ClientId = ClientId;\n    reporting.Configuration.ServiceUrl = ServiceUrl;\n    reporting.Configuration.UseHttp(http => {\n        http.Timeout = TimeSpan.FromSeconds(3);\n        http.Handler = new HttpClientHandler() {\n            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true\n        };\n    });\n\n    reporting.BeforeSendReport += (s, e) => {\n        e.Report.Properties.Add(\"cmdline\", Environment.CommandLine);\n        e.Report.Properties.Add(\"username\", Environment.UserName);\n    };\n\n    return reporting;\n}\nUser Key: The example code uses a user key (UserKey) to authorize the client to send reports. Make sure to replace it with a valid user key. To generate a user key please refer to the Floating License or License Activation paragraphs.\nCustom Report Class: The HackDetectionReport class inherits from Report and defines custom properties for tracking security events. It uses ReportPlot to create interactive charts that are rendered in the web application:"},{"page":134,"heading":"Console Application Example","anchor":"console-application-example","text":"class HackDetectionReport : Report\n{\n    public string HackingType { get; set; } = \"unknown\";\n    public string AttackMethod { get; set; } = \"unknown\";\n    public string HackDetails { get; set; } = \"no_details\";\n\n    public HackDetectionReport() : base(\"HackDetection\") { }\n\n    public override void Build()\n    {\n        // Add custom hack detection information\n        Properties.Add(\"machineName\", Environment.MachineName);\n        Properties.Add(\"hackingType\", HackingType);\n        Properties.Add(\"attackMethod\", AttackMethod);\n        Properties.Add(\"hackDetails\", HackDetails);\n\n        // Add attack distribution pie chart\n        var attackDistribution = new ReportPlot(ReportPlotType.Pie, \"Attack Type Distribution\")\n            .SetHeight(400)\n            .AddSeries(\"Attacks\", new List<object>\n            {\n                new { type = \"SQL Injection\", count = 45 },\n                new { type = \"XSS\", count = 32 },\n                new { type = \"CSRF\", count = 18 },\n                new { type = \"Path Traversal\", count = 12 },\n                new { type = \"Brute Force\", count = 8 }\n            });\n        attackDistribution.Series[0].ArgumentField = \"type\";\n        attackDistribution.Series[0].ValueField = \"count\";\n        Properties.Add(\"attackDistribution\", attackDistribution.ToDictionary());\n\n        // Add attack timeline line chart\n        var attackTimeline = new ReportPlot(ReportPlotType.Line, \"Attack Attempts Over Time\")"},{"page":134,"heading":"Console Application Example","anchor":"console-application-example","text":"            .SetAxisTitles(\"Time\", \"Attack Count\")\n            .SetHeight(350)\n            .AddSeries(\"Today\", new List<object>\n            {\n                new { hour = \"00:00\", attempts = 5 },\n                new { hour = \"04:00\", attempts = 3 },\n                new { hour = \"08:00\", attempts = 15 },\n                new { hour = \"12:00\", attempts = 28 },\n                new { hour = \"16:00\", attempts = 22 },\n                new { hour = \"20:00\", attempts = 18 }\n            })\n            .AddSeries(\"Yesterday\", new List<object>\n            {\n                new { hour = \"00:00\", attempts = 4 },\n                new { hour = \"04:00\", attempts = 2 },\n                new { hour = \"08:00\", attempts = 12 },\n                new { hour = \"12:00\", attempts = 20 },\n                new { hour = \"16:00\", attempts = 25 },\n                new { hour = \"20:00\", attempts = 15 }\n            });\n        attackTimeline.Series[0].ArgumentField = \"hour\";\n        attackTimeline.Series[0].ValueField = \"attempts\";\n        attackTimeline.Series[1].ArgumentField = \"hour\";\n        attackTimeline.Series[1].ValueField = \"attempts\";\n        Properties.Add(\"attackTimeline\", attackTimeline.ToDictionary());\n\n        // Add severity bar chart\n        var severityChart = new ReportPlot(ReportPlotType.Bar, \"Attack Severity Levels\")\n            .SetAxisTitles(\"Severity\", \"Incidents\")\n            .SetHeight(350)\n            .AddSeries(\"Last 24h\", new List<object>\n            {"},{"page":134,"heading":"Console Application Example","anchor":"console-application-example","text":"                new { severity = \"Critical\", incidents = 8 },\n                new { severity = \"High\", incidents = 25 },\n                new { severity = \"Medium\", incidents = 42 },\n                new { severity = \"Low\", incidents = 30 }\n            });\n        severityChart.Series[0].ArgumentField = \"severity\";\n        severityChart.Series[0].ValueField = \"incidents\";\n        Properties.Add(\"severityChart\", severityChart.ToDictionary());\n\n        // Add IP source area chart\n        var ipSourceChart = new ReportPlot(ReportPlotType.Area, \"Attack Sources by Region\")\n            .SetAxisTitles(\"Hour\", \"Unique IPs\")\n            .SetHeight(350)\n            .AddSeries(\"Asia\", new List<object>\n            {\n                new { hour = \"00:00\", ips = 12 },\n                new { hour = \"06:00\", ips = 18 },\n                new { hour = \"12:00\", ips = 25 },\n                new { hour = \"18:00\", ips = 22 }\n            })\n            .AddSeries(\"Europe\", new List<object>\n            {\n                new { hour = \"00:00\", ips = 8 },\n                new { hour = \"06:00\", ips = 15 },\n                new { hour = \"12:00\", ips = 20 },\n                new { hour = \"18:00\", ips = 18 }\n            })\n            .AddSeries(\"Americas\", new List<object>\n            {\n                new { hour = \"00:00\", ips = 5 },\n                new { hour = \"06:00\", ips = 10 },\n                new { hour = \"12:00\", ips = 15 },\n                new { hour = \"18:00\", ips = 12 }\n            });"},{"page":134,"heading":"Console Application Example","anchor":"console-application-example","text":"        ipSourceChart.Series[0].ArgumentField = \"hour\";\n        ipSourceChart.Series[0].ValueField = \"ips\";\n        ipSourceChart.Series[1].ArgumentField = \"hour\";\n        ipSourceChart.Series[1].ValueField = \"ips\";\n        ipSourceChart.Series[2].ArgumentField = \"hour\";\n        ipSourceChart.Series[2].ValueField = \"ips\";\n        Properties.Add(\"ipSourceChart\", ipSourceChart.ToDictionary());\n\n        base.Build();\n    }\n}\nBeforeSendReport Event: The example subscribes to the BeforeSendReport event, which allows you to add additional properties to reports before they are sent. In this event handler, custom properties like cmdline (command line) and username (current user's name) are added.\nSending the Report: The SendAsync method sends the custom report to the Babel Licensing Service:\nprivate async Task SendHackDetectionReportAsync()\n{\n    var hackReport = new HackDetectionReport\n    {\n        HackingType = \"SQL Injection\",\n        AttackMethod = \"Malicious Input\",\n        HackDetails = \"Detected SQL keywords in user input\"\n    };\n    await _reporting.SendAsync(UserKey, hackReport);\n    Console.WriteLine(\"HackDetectionReport sent.\");\n}\nCustom Report Example"},{"page":134,"heading":"Console Application Example","anchor":"console-application-example","text":"The console-custom-report-example provides a practical demonstration of how to create custom report types and send them to the Babel Licensing Service. By integrating custom reports into your applications, you can track security events, application metrics, business events, and any other structured data relevant to your application."},{"page":134,"heading":"Creating a Custom Report","anchor":"creating-a-custom-report","text":"To create a custom report, inherit from the Report base class:\nusing Babel.Licensing.Reports;\n\npublic class HackDetectionReport : Report\n{\n    // Custom properties for your report\n    public string HackingType { get; set; } = \"unknown\";\n    public string AttackMethod { get; set; } = \"unknown\";\n    public string HackDetails { get; set; } = \"no_details\";\n\n    // Constructor: specify report name\n    public HackDetectionReport() : base(\"HackDetection\")\n    {\n    }\n\n    // Build method: populate report properties\n    public override void Build()\n    {\n        // Add custom properties to the report\n        Properties.Add(\"machine_name\", Environment.MachineName);\n        Properties.Add(\"hacking_type\", HackingType);\n        Properties.Add(\"attack_method\", AttackMethod);\n        Properties.Add(\"detection_details\", HackDetails);\n        Properties.Add(\"detected_at\", DateTime.UtcNow);\n\n        // Call base to generate final JSON structure\n        base.Build();\n    }\n}"},{"page":134,"heading":"Report Base Class","anchor":"report-base-class","text":"The Report class provides the foundation for all reports:\nKey Properties\nName: Unique identifier for the report type (e.g., \"HackDetection\", \"PerformanceMetrics\")\nContent: JSON-serialized report data (generated by Build())\nVersion: Report format version (currently \"1.0\")\nDate: Report creation timestamp\nEncrypted: Flag indicating if content is encrypted\nProperties: Dictionary for custom key-value data\nKey Methods\nBuild(): Override this to populate your custom properties\nCreate(string report, string password): Deserialize a report from JSON\nFromException(Exception ex, ExceptionReportOptions options): Factory method for exception reports"},{"page":134,"heading":"Sending Custom Reports","anchor":"sending-custom-reports","text":"Once you've created your custom report class, send it using BabelReporting:\nusing Babel.Licensing.Services;\n\n// Initialize reporting service\nvar reporting = new BabelReporting();\nreporting.Configuration.ServiceUrl = \"https://licensing.example.com\";\nreporting.Configuration.ClientId = \"MyApplication\";\n\n// Create and configure your custom report\nvar hackReport = new HackDetectionReport\n{\n    HackingType = \"SQL Injection\",\n    AttackMethod = \"Malicious Input\",\n    HackDetails = \"Detected SQL keywords in user input: ' OR '1'='1\"\n};\n\n// Send the report\nvar result = await reporting.SendAsync(userKey, hackReport);\n\nif (result.Success)\n{\n    Console.WriteLine($\"Report sent: {result.ReportUid}\");\n}\nelse\n{\n    Console.WriteLine($\"Failed: {result.Error?.Message}\");\n}"},{"page":134,"heading":"Real-World Examples","anchor":"real-world-examples","text":"Example 1: Security Event Report\nDetect and report potential security threats:"},{"page":134,"heading":"Real-World Examples","anchor":"real-world-examples","text":"public class SecurityEventReport : Report\n{\n    public string EventType { get; set; }\n    public string Severity { get; set; }\n    public string SourceIP { get; set; }\n    public string UserAgent { get; set; }\n    public string RequestPath { get; set; }\n    public Dictionary<string, string> AdditionalData { get; set; }\n\n    public SecurityEventReport() : base(\"SecurityEvent\")\n    {\n        AdditionalData = new Dictionary<string, string>();\n    }\n\n    public override void Build()\n    {\n        Properties.Add(\"event_type\", EventType);\n        Properties.Add(\"severity\", Severity);\n        Properties.Add(\"source_ip\", SourceIP);\n        Properties.Add(\"user_agent\", UserAgent);\n        Properties.Add(\"request_path\", RequestPath);\n        Properties.Add(\"timestamp\", DateTime.UtcNow);\n        Properties.Add(\"machine_id\", GetMachineId());\n\n        // Add all additional data\n        foreach (var kvp in AdditionalData)\n        {\n            Properties.Add(kvp.Key, kvp.Value);\n        }\n\n        base.Build();\n    }\n\n    private string GetMachineId()\n    {\n        // Implementation to get unique machine identifier\n        return Environment.MachineName;\n    }\n}\n\n// Usage\npublic async Task ReportSuspiciousLogin(string ipAddress, string userAgent)\n{\n    var report = new SecurityEventReport\n    {\n        EventType = \"SuspiciousLogin\",\n        Severity = \"High\",\n        SourceIP = ipAddress,\n        UserAgent = userAgent,\n        RequestPath = \"/api/auth/login\"\n    };\n"},{"page":134,"heading":"Real-World Examples","anchor":"real-world-examples","text":"    report.AdditionalData.Add(\"failed_attempts\", \"5\");\n    report.AdditionalData.Add(\"time_window\", \"60s\");\n\n    await _reporting.SendAsync(_userKey, report);\n}\nExample 2: Performance Metrics Report\nTrack application performance metrics:"},{"page":134,"heading":"Real-World Examples","anchor":"real-world-examples","text":"public class PerformanceMetricsReport : Report\n{\n    public double AverageResponseTime { get; set; }\n    public double PeakResponseTime { get; set; }\n    public int TotalRequests { get; set; }\n    public int FailedRequests { get; set; }\n    public double CpuUsage { get; set; }\n    public double MemoryUsage { get; set; }\n    public TimeSpan Uptime { get; set; }\n\n    public PerformanceMetricsReport() : base(\"PerformanceMetrics\")\n    {\n    }\n\n    public override void Build()\n    {\n        Properties.Add(\"average_response_time_ms\", AverageResponseTime);\n        Properties.Add(\"peak_response_time_ms\", PeakResponseTime);\n        Properties.Add(\"total_requests\", TotalRequests);\n        Properties.Add(\"failed_requests\", FailedRequests);\n        Properties.Add(\"error_rate\", CalculateErrorRate());\n        Properties.Add(\"cpu_usage_percent\", CpuUsage);\n        Properties.Add(\"memory_usage_mb\", MemoryUsage);\n        Properties.Add(\"uptime_hours\", Uptime.TotalHours);\n        Properties.Add(\"collection_time\", DateTime.UtcNow);\n\n        base.Build();\n    }\n\n    private double CalculateErrorRate()\n    {\n        if (TotalRequests == 0) return 0;\n        return (double)FailedRequests / TotalRequests * 100;\n    }\n}\n\n// Usage with periodic reporting\npublic class MetricsCollector\n{\n    private readonly BabelReporting _reporting;\n    private readonly Timer _timer;\n    private readonly PerformanceMonitor _monitor;\n\n    public MetricsCollector(BabelReporting reporting, string userKey)\n    {"},{"page":134,"heading":"Real-World Examples","anchor":"real-world-examples","text":"        _reporting = reporting;\n        _monitor = new PerformanceMonitor();\n\n        // Report metrics every hour\n        _timer = new Timer(async _ =>\n        {\n            var metrics = _monitor.GetCurrentMetrics();\n            var report = new PerformanceMetricsReport\n            {\n                AverageResponseTime = metrics.AvgResponseTime,\n                PeakResponseTime = metrics.PeakResponseTime,\n                TotalRequests = metrics.TotalRequests,\n                FailedRequests = metrics.FailedRequests,\n                CpuUsage = metrics.CpuUsage,\n                MemoryUsage = metrics.MemoryUsage,\n                Uptime = metrics.Uptime\n            };\n\n            await _reporting.SendAsync(userKey, report);\n        }, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1));\n    }\n}\nExample 3: Business Event Report\nTrack important business events:"},{"page":134,"heading":"Real-World Examples","anchor":"real-world-examples","text":"public class BusinessEventReport : Report\n{\n    public string EventCategory { get; set; }\n    public string EventAction { get; set; }\n    public string UserId { get; set; }\n    public string EntityType { get; set; }\n    public string EntityId { get; set; }\n    public decimal? TransactionAmount { get; set; }\n    public Dictionary<string, object> Metadata { get; set; }\n\n    public BusinessEventReport() : base(\"BusinessEvent\")\n    {\n        Metadata = new Dictionary<string, object>();\n    }\n\n    public override void Build()\n    {\n        Properties.Add(\"event_category\", EventCategory);\n        Properties.Add(\"event_action\", EventAction);\n        Properties.Add(\"user_id\", UserId);\n        Properties.Add(\"entity_type\", EntityType);\n        Properties.Add(\"entity_id\", EntityId);\n        Properties.Add(\"timestamp\", DateTime.UtcNow);\n\n        if (TransactionAmount.HasValue)\n        {\n            Properties.Add(\"transaction_amount\", TransactionAmount.Value);\n        }\n\n        // Add metadata\n        foreach (var kvp in Metadata)\n        {\n            Properties.Add(kvp.Key, kvp.Value);\n        }\n\n        base.Build();\n    }\n}\n\n// Usage\npublic async Task ReportPurchase(string userId, string orderId, decimal amount)\n{\n    var report = new BusinessEventReport\n    {\n        EventCategory = \"Sales\",\n        EventAction = \"Purchase\",\n        UserId = userId,\n        EntityType = \"Order\",\n        EntityId = orderId,\n        TransactionAmount = amount\n    };\n"},{"page":134,"heading":"Real-World Examples","anchor":"real-world-examples","text":"    report.Metadata.Add(\"payment_method\", \"CreditCard\");\n    report.Metadata.Add(\"currency\", \"USD\");\n\n    await _reporting.SendAsync(_userKey, report);\n}\nExample 4: Diagnostic Report\nSend detailed diagnostic information:"},{"page":134,"heading":"Real-World Examples","anchor":"real-world-examples","text":"public class DiagnosticReport : Report\n{\n    public string Component { get; set; }\n    public string Status { get; set; }\n    public string ErrorMessage { get; set; }\n    public Dictionary<string, string> ConfigurationSettings { get; set; }\n    public Dictionary<string, string> HealthChecks { get; set; }\n\n    public DiagnosticReport() : base(\"Diagnostic\")\n    {\n        ConfigurationSettings = new Dictionary<string, string>();\n        HealthChecks = new Dictionary<string, string>();\n    }\n\n    public override void Build()\n    {\n        Properties.Add(\"component\", Component);\n        Properties.Add(\"status\", Status);\n        Properties.Add(\"error_message\", ErrorMessage ?? \"None\");\n        Properties.Add(\"timestamp\", DateTime.UtcNow);\n        Properties.Add(\"application_version\", GetApplicationVersion());\n\n        // Add configuration settings\n        var configJson = JsonSerializer.Serialize(ConfigurationSettings);\n        Properties.Add(\"configuration\", configJson);\n\n        // Add health check results\n        var healthJson = JsonSerializer.Serialize(HealthChecks);\n        Properties.Add(\"health_checks\", healthJson);\n\n        base.Build();\n    }\n\n    private string GetApplicationVersion()\n    {\n        return Assembly.GetExecutingAssembly().GetName().Version.ToString();\n    }\n}\n\n// Usage\npublic async Task ReportDatabaseConnectionIssue()\n{\n    var report = new DiagnosticReport\n    {\n        Component = \"Database\",\n        Status = \"Error\","},{"page":134,"heading":"Real-World Examples","anchor":"real-world-examples","text":"        ErrorMessage = \"Connection timeout after 30 seconds\"\n    };\n\n    report.ConfigurationSettings.Add(\"connection_string\", \"Server=***;Database=***\");\n    report.ConfigurationSettings.Add(\"timeout\", \"30\");\n    report.ConfigurationSettings.Add(\"retry_count\", \"3\");\n\n    report.HealthChecks.Add(\"database_ping\", \"Failed\");\n    report.HealthChecks.Add(\"dns_resolution\", \"Success\");\n    report.HealthChecks.Add(\"network_connectivity\", \"Success\");\n\n    await _reporting.SendAsync(_userKey, report);\n}"},{"page":134,"heading":"Adding Environment and System Information","anchor":"adding-environment-and-system-information","text":"You can enhance your custom reports with environment and system information using the built-in collectors:\nusing Babel.Licensing.Reports;\nusing Babel.Licensing.Reports.Collectors;\n\npublic class EnhancedCustomReport : Report\n{\n    private readonly EnvironmentReportOptions _envOptions;\n    private readonly SystemReportOptions _sysOptions;\n\n    public string CustomData { get; set; }\n\n    public EnhancedCustomReport() : base(\"EnhancedCustom\")\n    {\n        // Configure what environment/system info to collect\n        _envOptions = new EnvironmentReportOptions\n        {\n            CollectApplicationInformation = true,\n            CollectLoadedAssemblies = true,\n            CollectEnvironmentVariables = false\n        };\n\n        _sysOptions = new SystemReportOptions\n        {\n            CollectOsInformation = true,\n            CollectProcessorInformation = true,\n            CollectMemoryInformation = true\n        };\n    }\n\n    public override void Build()\n    {\n        // Add your custom properties\n        Properties.Add(\"custom_data\", CustomData);\n\n        // Add environment information\n        var envCollector = new EnvironmentCollector(Properties, _envOptions);\n        envCollector.Collect();\n\n        // Add system information\n        var sysCollector = new SystemCollector(Properties, _sysOptions);\n        sysCollector.Collect();\n\n        base.Build();\n    }\n}"},{"page":134,"heading":"Adding Charts to Reports","anchor":"adding-charts-to-reports","text":"Custom reports can include interactive charts that are automatically rendered in the Babel Licensing web application. Use the ReportPlot class to create visualizations of your report data.\nChart Types\nThe ReportPlotType enumeration supports four chart types:\nPie: Display distribution data as a pie chart\nLine: Show trends over time with line charts\nBar: Compare categorical data with bar charts\nArea: Visualize cumulative data with area charts\nCreating a Pie Chart\nPie charts are ideal for showing distribution of categories:\nusing Babel.Licensing.Reports;\n\n// Create a pie chart for attack type distribution\nvar attackDistribution = new ReportPlot(ReportPlotType.Pie, \"Attack Type Distribution\")\n    .SetHeight(400)\n    .AddSeries(\"Attacks\", new List<object>\n    {\n        new { type = \"SQL Injection\", count = 45 },\n        new { type = \"XSS\", count = 32 },\n        new { type = \"CSRF\", count = 18 },\n        new { type = \"Path Traversal\", count = 12 },\n        new { type = \"Brute Force\", count = 8 }\n    });\n\n// Configure which fields to use for the chart\nattackDistribution.Series[0].ArgumentField = \"type\";  // Category labels\nattackDistribution.Series[0].ValueField = \"count\";    // Values\n\n// Add to report properties\nProperties.Add(\"attackDistribution\", attackDistribution.ToDictionary());\nCreating a Line Chart\nLine charts are perfect for showing trends over time:"},{"page":134,"heading":"Adding Charts to Reports","anchor":"adding-charts-to-reports","text":"// Create a line chart comparing attack attempts over time\nvar attackTimeline = new ReportPlot(ReportPlotType.Line, \"Attack Attempts Over Time\")\n    .SetAxisTitles(\"Time\", \"Attack Count\")\n    .SetHeight(350)\n    .AddSeries(\"Today\", new List<object>\n    {\n        new { hour = \"00:00\", attempts = 5 },\n        new { hour = \"04:00\", attempts = 3 },\n        new { hour = \"08:00\", attempts = 15 },\n        new { hour = \"12:00\", attempts = 28 },\n        new { hour = \"16:00\", attempts = 22 },\n        new { hour = \"20:00\", attempts = 18 }\n    })\n    .AddSeries(\"Yesterday\", new List<object>\n    {\n        new { hour = \"00:00\", attempts = 4 },\n        new { hour = \"04:00\", attempts = 2 },\n        new { hour = \"08:00\", attempts = 12 },\n        new { hour = \"12:00\", attempts = 20 },\n        new { hour = \"16:00\", attempts = 25 },\n        new { hour = \"20:00\", attempts = 15 }\n    });\n\n// Configure field mappings for each series\nattackTimeline.Series[0].ArgumentField = \"hour\";\nattackTimeline.Series[0].ValueField = \"attempts\";\nattackTimeline.Series[1].ArgumentField = \"hour\";\nattackTimeline.Series[1].ValueField = \"attempts\";\n\nProperties.Add(\"attackTimeline\", attackTimeline.ToDictionary());\nCreating a Bar Chart\nBar charts work well for comparing discrete categories:"},{"page":134,"heading":"Adding Charts to Reports","anchor":"adding-charts-to-reports","text":"// Create a bar chart for severity levels\nvar severityChart = new ReportPlot(ReportPlotType.Bar, \"Attack Severity Levels\")\n    .SetAxisTitles(\"Severity\", \"Incidents\")\n    .SetHeight(350)\n    .AddSeries(\"Last 24h\", new List<object>\n    {\n        new { severity = \"Critical\", incidents = 8 },\n        new { severity = \"High\", incidents = 25 },\n        new { severity = \"Medium\", incidents = 42 },\n        new { severity = \"Low\", incidents = 30 }\n    });\n\nseverityChart.Series[0].ArgumentField = \"severity\";\nseverityChart.Series[0].ValueField = \"incidents\";\n\nProperties.Add(\"severityChart\", severityChart.ToDictionary());\nCreating an Area Chart\nArea charts are useful for showing cumulative data across multiple series:"},{"page":134,"heading":"Adding Charts to Reports","anchor":"adding-charts-to-reports","text":"// Create an area chart for attack sources by region\nvar ipSourceChart = new ReportPlot(ReportPlotType.Area, \"Attack Sources by Region\")\n    .SetAxisTitles(\"Hour\", \"Unique IPs\")\n    .SetHeight(350)\n    .AddSeries(\"Asia\", new List<object>\n    {\n        new { hour = \"00:00\", ips = 12 },\n        new { hour = \"06:00\", ips = 18 },\n        new { hour = \"12:00\", ips = 25 },\n        new { hour = \"18:00\", ips = 22 }\n    })\n    .AddSeries(\"Europe\", new List<object>\n    {\n        new { hour = \"00:00\", ips = 8 },\n        new { hour = \"06:00\", ips = 15 },\n        new { hour = \"12:00\", ips = 20 },\n        new { hour = \"18:00\", ips = 18 }\n    })\n    .AddSeries(\"Americas\", new List<object>\n    {\n        new { hour = \"00:00\", ips = 5 },\n        new { hour = \"06:00\", ips = 10 },\n        new { hour = \"12:00\", ips = 15 },\n        new { hour = \"18:00\", ips = 12 }\n    });\n\n// Configure field mappings for all series\nforeach (var series in ipSourceChart.Series)\n{\n    series.ArgumentField = \"hour\";\n    series.ValueField = \"ips\";\n}\n\nProperties.Add(\"ipSourceChart\", ipSourceChart.ToDictionary());\nReportPlot API Reference\nConstructor\nnew ReportPlot(ReportPlotType type, string title)\nMethods\nMethod | Description\nSetHeight(int height) | Sets the chart height in pixels\nSetAxisTitles(string xAxis, string yAxis) | Sets the X and Y axis labels\nAddSeries(string name, List<object> data) | Adds a data series to the chart\nToDictionary() | Converts the chart to a dictionary for report properties\nSeries Properties"},{"page":134,"heading":"Adding Charts to Reports","anchor":"adding-charts-to-reports","text":"Property | Description\nArgumentField | The field name in data objects to use as X-axis values (categories)\nValueField | The field name in data objects to use as Y-axis values (measurements)\nComplete Example with Multiple Charts\nHere's a complete custom report class that includes multiple visualizations:"},{"page":134,"heading":"Adding Charts to Reports","anchor":"adding-charts-to-reports","text":"public class SecurityDashboardReport : Report\n{\n    public SecurityDashboardReport() : base(\"SecurityDashboard\") { }\n\n    public override void Build()\n    {\n        // Basic properties\n        Properties.Add(\"generated_at\", DateTime.UtcNow);\n        Properties.Add(\"machine_name\", Environment.MachineName);\n\n        // Pie chart: Attack distribution\n        var attackTypes = new ReportPlot(ReportPlotType.Pie, \"Attack Types\")\n            .SetHeight(400)\n            .AddSeries(\"Types\", GetAttackTypeData());\n        attackTypes.Series[0].ArgumentField = \"type\";\n        attackTypes.Series[0].ValueField = \"count\";\n        Properties.Add(\"attackTypes\", attackTypes.ToDictionary());\n\n        // Line chart: Attacks over time\n        var timeline = new ReportPlot(ReportPlotType.Line, \"Attack Timeline\")\n            .SetAxisTitles(\"Time\", \"Attacks\")\n            .SetHeight(350)\n            .AddSeries(\"Attacks\", GetTimelineData());\n        timeline.Series[0].ArgumentField = \"time\";\n        timeline.Series[0].ValueField = \"count\";\n        Properties.Add(\"timeline\", timeline.ToDictionary());\n\n        // Bar chart: Severity breakdown\n        var severity = new ReportPlot(ReportPlotType.Bar, \"Severity Distribution\")\n            .SetAxisTitles(\"Level\", \"Count\")\n            .SetHeight(350)\n            .AddSeries(\"Severity\", GetSeverityData());\n        severity.Series[0].ArgumentField = \"level\";\n        severity.Series[0].ValueField = \"count\";"},{"page":134,"heading":"Adding Charts to Reports","anchor":"adding-charts-to-reports","text":"        Properties.Add(\"severity\", severity.ToDictionary());\n\n        base.Build();\n    }\n\n    private List<object> GetAttackTypeData() => new List<object>\n    {\n        new { type = \"SQL Injection\", count = 45 },\n        new { type = \"XSS\", count = 32 },\n        new { type = \"CSRF\", count = 18 }\n    };\n\n    private List<object> GetTimelineData() => new List<object>\n    {\n        new { time = \"08:00\", count = 15 },\n        new { time = \"12:00\", count = 28 },\n        new { time = \"16:00\", count = 22 }\n    };\n\n    private List<object> GetSeverityData() => new List<object>\n    {\n        new { level = \"Critical\", count = 8 },\n        new { level = \"High\", count = 25 },\n        new { level = \"Medium\", count = 42 }\n    };\n}\nWhen this report is viewed in the Babel Licensing web application, all charts are rendered as interactive visualizations, allowing you to analyze your custom report data visually."},{"page":134,"heading":"Report Encryption","anchor":"report-encryption","text":"Protect sensitive data in your custom reports with encryption:\nvar reporting = new BabelReporting();\nreporting.Configuration.EncryptionKey = \"your-secret-encryption-key\";\n\nvar report = new SecurityEventReport\n{\n    EventType = \"DataBreach\",\n    Severity = \"Critical\",\n    // ... sensitive data\n};\n\n// Report will be automatically encrypted before transmission\nvar result = await reporting.SendAsync(userKey, report);\nThe server must be configured with the same encryption key to decrypt the report."},{"page":134,"heading":"Customizing Before Send","anchor":"customizing-before-send","text":"Modify any report (including custom reports) before it's sent:\nreporting.BeforeSendReport += (s, e) =>\n{\n    // Add global properties to all reports\n    e.Report.Properties.Add(\"environment\", \"production\");\n    e.Report.Properties.Add(\"region\", \"us-east-1\");\n    e.Report.Properties.Add(\"deployment_id\", DeploymentId);\n\n    // Add conditional logic\n    if (e.Report.Name == \"SecurityEvent\")\n    {\n        e.Report.Properties.Add(\"security_version\", SecurityFrameworkVersion);\n    }\n\n    // Validate before sending\n    if (!IsValidReport(e.Report))\n    {\n        e.Cancel = true;  // Don't send invalid reports\n    }\n};"},{"page":134,"heading":"Report Structure","anchor":"report-structure","text":"All reports follow a consistent JSON structure:\n{\n  \"name\": \"HackDetection\",\n  \"version\": \"1.0\",\n  \"date\": \"2025-01-22T10:30:00Z\",\n  \"encrypted\": false,\n  \"content\": {\n    \"properties\": {\n      \"machine_name\": \"DESKTOP-ABC123\",\n      \"hacking_type\": \"SQL Injection\",\n      \"attack_method\": \"Malicious Input\",\n      \"detection_details\": \"Detected SQL keywords in user input\",\n      \"detected_at\": \"2025-01-22T10:30:00Z\"\n    }\n  }\n}"},{"page":134,"heading":"Server-Side Processing","anchor":"server-side-processing","text":"When your custom report arrives at the Babel Licensing Service:\nValidation: Report name and content are validated\nDecryption: Encrypted content is decrypted using the configured key\nParsing: Properties are extracted from the content\nStorage: Report is stored in the database with metadata\nIndexing: Properties are indexed for searchability\nWebhooks: ReportCreated events are dispatched for external integrations\nYou can query custom reports through the Babel Licensing Service API:\nGET /api/reports?name=HackDetection&from=2025-01-01&to=2025-01-31"},{"page":134,"heading":"Best Practices","anchor":"best-practices","text":"1. Choose Meaningful Report Names\nUse descriptive, consistent names for your report types:\n// GOOD: Clear and specific\npublic class UserAuthenticationFailureReport : Report\n{\n    public UserAuthenticationFailureReport() : base(\"UserAuthFailure\") { }\n}\n\n// BAD: Generic and unclear\npublic class CustomReport1 : Report\n{\n    public CustomReport1() : base(\"Report1\") { }\n}\n2. Include Timestamps\nAlways include timestamps for temporal analysis:\npublic override void Build()\n{\n    Properties.Add(\"timestamp\", DateTime.UtcNow);\n    Properties.Add(\"event_time\", eventOccurredAt);\n    base.Build();\n}\n3. Add Context Information\nInclude enough context to make the report actionable:\nProperties.Add(\"user_id\", userId);\nProperties.Add(\"session_id\", sessionId);\nProperties.Add(\"request_id\", requestId);\nProperties.Add(\"correlation_id\", correlationId);\n4. Use Structured Data\nPrefer structured data over freeform text for better analysis:\n// GOOD: Structured\nProperties.Add(\"response_time_ms\", 1250);\nProperties.Add(\"status_code\", 200);\nProperties.Add(\"endpoint\", \"/api/users\");\n\n// BAD: Unstructured\nProperties.Add(\"message\", \"Request to /api/users took 1250ms and returned 200\");\n5. Handle Errors Gracefully\nDon't let report failures impact application functionality:\ntry\n{\n    var report = new CustomReport { /* ... */ };\n    await _reporting.SendAsync(_userKey, report);\n}\ncatch (Exception ex)\n{\n    // Log error but don't throw\n    _logger.LogWarning(ex, \"Failed to send custom report\");\n}"},{"page":134,"heading":"Best Practices","anchor":"best-practices","text":"6. Batch Related Events\nInstead of sending many individual reports, batch related events:\npublic class BatchEventReport : Report\n{\n    public List<EventData> Events { get; set; } = new List<EventData>();\n\n    public BatchEventReport() : base(\"BatchEvent\") { }\n\n    public override void Build()\n    {\n        Properties.Add(\"event_count\", Events.Count);\n        Properties.Add(\"events\", JsonSerializer.Serialize(Events));\n        Properties.Add(\"batch_time\", DateTime.UtcNow);\n        base.Build();\n    }\n}\n7. Sanitize Sensitive Data\nNever include passwords, API keys, or personally identifiable information:\npublic override void Build()\n{\n    // GOOD: Sanitized\n    Properties.Add(\"username\", SanitizeUsername(username));\n    Properties.Add(\"email\", HashEmail(email));\n\n    // BAD: Sensitive data\n    // Properties.Add(\"password\", password);  // NEVER DO THIS\n    // Properties.Add(\"credit_card\", cardNumber);  // NEVER DO THIS\n\n    base.Build();\n}\n\nprivate string SanitizeUsername(string username)\n{\n    // Return first 3 chars + asterisks\n    if (username.Length <= 3) return \"***\";\n    return username.Substring(0, 3) + new string('*', username.Length - 3);\n}"},{"page":134,"heading":"Complete Example","anchor":"complete-example","text":"Here's a complete example combining custom reports with proper error handling and configuration:"},{"page":134,"heading":"Complete Example","anchor":"complete-example","text":"using Babel.Licensing.Reports;\nusing Babel.Licensing.Services;\nusing Microsoft.Extensions.Logging;\n\npublic class ApplicationReportingService\n{\n    private readonly BabelReporting _reporting;\n    private readonly ILogger<ApplicationReportingService> _logger;\n    private readonly string _userKey;\n\n    public ApplicationReportingService(\n        IConfiguration configuration,\n        ILogger<ApplicationReportingService> logger)\n    {\n        _logger = logger;\n        _userKey = configuration[\"Licensing:UserKey\"];\n\n        _reporting = new BabelReporting();\n        _reporting.Configuration.ServiceUrl = configuration[\"Licensing:ServiceUrl\"];\n        _reporting.Configuration.ClientId = \"EquiTrack v2.0\";\n        _reporting.Configuration.EncryptionKey = configuration[\"Licensing:EncryptionKey\"];\n\n        _reporting.BeforeSendReport += OnBeforeSendReport;\n        _reporting.AfterSendReport += OnAfterSendReport;\n    }\n\n    private void OnBeforeSendReport(object sender, BeforeSendReportEventArgs e)\n    {\n        // Add global context to all reports\n        e.Report.Properties[\"application_version\"] = GetApplicationVersion();\n        e.Report.Properties[\"environment\"] = GetEnvironment();\n    }\n\n    private void OnAfterSendReport(object sender, AfterSendReportEventArgs e)\n    {\n        if (e.Error != null)\n        {\n            _logger.LogError(e.Error, \"Failed to send {ReportType} report\", e.Report.Name);\n        }\n        else\n        {"},{"page":134,"heading":"Complete Example","anchor":"complete-example","text":"            _logger.LogInformation(\"Sent {ReportType} report: {ReportId}\",\n                e.Report.Name, e.Result.ReportUid);\n        }\n    }\n\n    public async Task ReportSecurityEvent(\n        string eventType,\n        string severity,\n        string details)\n    {\n        try\n        {\n            var report = new SecurityEventReport\n            {\n                EventType = eventType,\n                Severity = severity,\n                SourceIP = GetClientIpAddress(),\n                UserAgent = GetUserAgent(),\n                RequestPath = GetCurrentRequestPath()\n            };\n\n            report.AdditionalData[\"details\"] = details;\n\n            var result = await _reporting.SendAsync(_userKey, report);\n\n            if (!result.Success)\n            {\n                _logger.LogWarning(\"Security event report failed: {Error}\",\n                    result.Error?.Message);\n            }\n        }\n        catch (Exception ex)\n        {\n            _logger.LogError(ex, \"Exception sending security event report\");\n        }\n    }\n\n    private string GetApplicationVersion() =>\n        Assembly.GetExecutingAssembly().GetName().Version.ToString();\n\n    private string GetEnvironment() =>\n        Environment.GetEnvironmentVariable(\"ASPNETCORE_ENVIRONMENT\") ?? \"Production\";\n\n    private string GetClientIpAddress() => /* implementation */;\n    private string GetUserAgent() => /* implementation */;\n    private string GetCurrentRequestPath() => /* implementation */;\n}"},{"page":134,"heading":"Related Topics","anchor":"related-topics","text":"Exception Reports - Built-in exception reporting\nLicense Reports - Track license usage\nFloating License - Generate user keys for reporting"},{"page":135,"heading":"","anchor":"","text":"Babel Licensing runs on FIPS-enabled Linux hosts, and its license\nvalidation does not rely on any algorithm that FIPS disallows. This page\nexplains how the library behaves on such hosts, a startup issue you may\nencounter in containers, and how to resolve it."},{"page":135,"heading":"Background","anchor":"background","text":"Many customers deploy on hosts where the operating system runs in FIPS\nmode — on Linux this is exposed as\n/proc/sys/crypto/fips_enabled = 1. In this mode the platform crypto\nprovider (OpenSSL on Linux) is expected to service every cryptographic\noperation through a certified FIPS module.\nA common problem arises when a container inherits the host's FIPS\nflag but its base image does not ship a certified OpenSSL FIPS\nprovider. OpenSSL 3 then tries to enter FIPS mode, fails to load the FIPS\nprovider module, and ends up in a broken state where every digest\nand cipher operation fails — not only the ones FIPS would normally\ndisallow. The typical error is:\nInterop+Crypto+OpenSslCryptographicException:\n    error:03000086:digital envelope routines::initialization error\nInfo: This is an environment condition, not a defect in Babel Licensing. It is\ndocumented independently of Babel — see\ndotnet/dotnet-docker#5849\nand dotnet/runtime#87884.\nIt affects any OpenSSL-backed .NET cryptography in the process,\nincluding TLS (HttpClient, gRPC), not just license validation."},{"page":135,"heading":"How it can surface during license validation","anchor":"how-it-can-surface-during-license-validation","text":"Because the whole OpenSSL layer is unusable, the first cryptographic\noperation performed at startup is where the failure appears. When a\nlicense carries an expiration date, Babel Licensing opens a small\nlocal store used for expiry tracking and clock-rollback detection. On\nmodern .NET the store initialization computes an identity hash through\nthe platform provider, which throws on a broken-FIPS host. The failure\nis reported as:\nBabel.Licensing.BabelLicenseException: Internal error\n ---> ...OpenSslCryptographicException: error:03000086:...\nInfo: Hardening (Babel Licensing 11.7.x and later). The license store has\nbeen reworked so that a broken platform crypto stack no longer breaks\nlicense validation: the store transparently falls back to a fully managed\nimplementation, and license validation degrades gracefully instead of\nfailing. On healthy hosts behavior is unchanged. On earlier builds, apply\nthe environment fix below."},{"page":135,"heading":"Resolving it in containers","anchor":"resolving-it-in-containers","text":"Make OpenSSL usable inside the container. Either option resolves the\nlicense-validation symptom and every other OpenSSL-backed operation\nin your process.\nOption 1 — Do not auto-enter FIPS in the container\nOn Ubuntu-based .NET images, OpenSSL honors the\nOPENSSL_FORCE_FIPS_MODE environment variable. Set it to 0 so OpenSSL\ndoes not try to enter FIPS mode with a provider the image does not ship.\nIn docker-compose.yml, add it to the licensing service environment:\nenvironment:\n      # Do not auto-enter FIPS mode using a provider the image doesn't ship\n      OPENSSL_FORCE_FIPS_MODE: 0\nor in a Dockerfile:\nENV OPENSSL_FORCE_FIPS_MODE=0\nUse this when the container itself does not need to be FIPS-validated:\nthe host stays FIPS-enabled and only this container's OpenSSL opts out of\nthe broken auto-FIPS path.\nOption 2 — Use a base image with a certified FIPS provider\nIf FIPS compliance is required inside the container, run on a base\nimage that ships a validated FIPS provider so the crypto layer\ninitializes correctly instead of failing:\nAzure Linux 3.0 .NET images\n(mcr.microsoft.com/dotnet/aspnet:8.0-azurelinux3.0 and similar),\nwhich ship Microsoft's FIPS-certified SymCrypt provider,\nRed Hat UBI 9 based .NET images\n(registry.access.redhat.com/ubi9/dotnet-90 and similar), or\nUbuntu Pro with the FIPS-certified OpenSSL packages."},{"page":135,"heading":"Babel Licensing Service on FIPS hosts","anchor":"babel-licensing-service-on-fips-hosts","text":"The Babel Licensing Service runs on FIPS-enabled hosts as long as the\nimage actually ships a FIPS provider module. The full licensing\nworkflow has been verified on Azure Linux 3.0, whose .NET images ship\nMicrosoft's FIPS-certified SymCrypt provider, with FIPS enforced:\nthe service starts and validates its own license,\nlicense templates and RSA-signed licenses are created,\nclients activate and validate licenses over gRPC,\nnode-locking, activation tokens, heartbeats and deactivation all work.\nWhat happens when the FIPS module is missing\nThe distinction that matters is not \"FIPS on or off\", but whether the\nprovider module that FIPS mode requires is present.\nOpenSSL 3 does not implement algorithms itself: it loads them from\nplug-in providers. In FIPS mode the configuration requires every\nalgorithm to come from the certified FIPS provider (the fips.so\nmodule). If that module is not installed in the image — as is the\ncase for the standard Debian/Ubuntu .NET images — OpenSSL cannot\nsatisfy any request, so every algorithm fails, including the ones\nFIPS itself permits.\nSince .NET on Linux delegates all cryptography to OpenSSL, this takes\ndown more than hashing and ciphers:\n.NET operation | Result when fips.so is missing\nSHA256 / SHA1 | error:03000086 ...initialization error\nAes | error:0308010C ...unsupported\nRandomNumberGenerator | error:12000090 ...unable to fetch drbg"},{"page":135,"heading":"Babel Licensing Service on FIPS hosts","anchor":"babel-licensing-service-on-fips-hosts","text":"Warning: Because even random-number generation fails, an ASP.NET Core\napplication cannot start at all on such a host — it needs\nrandomness during startup (data-protection keys, TLS). This affects every\nASP.NET Core application, not just the Babel Licensing Service, and it is\nan environment misconfiguration: FIPS is being demanded from an image\nthat cannot provide it. Resolve it with Option 1 or Option 2 above."},{"page":135,"heading":"Verifying the environment","anchor":"verifying-the-environment","text":"A quick check from inside the container tells you whether OpenSSL is\nhealthy:\n# Fails on a broken-FIPS host, succeeds once fixed\necho test | openssl dgst -sha1\nFailure with error:03000086 (or a message about fips.so not being\nloadable) — OpenSSL is in the broken state; apply Option 1 or 2.\nA normal SHA1(stdin)= ... line — OpenSSL is healthy and Babel\nLicensing runs normally.\nWarning: Even with the license-validation hardening, we recommend fixing the\nOpenSSL environment anyway: without it, other OpenSSL-backed operations\nin your process (notably TLS to the Babel Licensing Service) will still\nfail."},{"page":136,"heading":"","anchor":"","text":"The lic command line tool generates, signs, updates and verifies Babel\nlicenses from a terminal, a script or a build, on Windows, Linux and macOS.\nlic is the command line counterpart of license generation in Babel Desktop. It takes the assembly you are licensing, or an existing license file, and a set of switches that describe the license: who it is for, which product, when it expires, which features it unlocks, which restrictions apply, and which key signs it. The result is an XML license file or a string license such as a serial. The same tool generates key pairs, exports public keys, computes hardware keys, verifies signatures and updates licenses that already exist.\nThe tool is available in two forms, with identical options:\nlic in the Babel zip packages: lic.exe in babel_net472_<version>.zip and lic.dll (run with dotnet lic.dll) in babel_net80_<version>.zip, babel_net90_<version>.zip and babel_net100_<version>.zip.\nBabel.Licensing.Tool, a .NET tool package that installs the lic command on any operating system with the .NET SDK.\nBoth come with the Babel Licensing editions, Server and Data Center."},{"page":136,"heading":"Quick Start","anchor":"quick-start","text":"Generate a key pair once, keep the private key safe, and embed the public key in your application. The same PEM file signs every license you issue:\nlic --keygen rsa --keysize 2048 --keyfile keys.pem\nlic --publickey --keyfile keys.pem\nGenerate a signed license for an assembly. The licensee, product, dates, features, fields and restrictions are all switches; --sign signs the result with the key in --keyfile:\nlic MyApp.dll --keyfile keys.pem --sign --licensee name=\"Contoso\" --licensee email=info@contoso.com --product name=\"MyApp\" --product version=2.1 --expiredate 365 --feature Pro=1 --field Seats=25 --trial days=30 --output MyApp.licenses --encoding utf-8\nVerify a license file against the public key, update a license in place, or emit a serial instead of an XML file:\nlic MyApp.licenses --verify --keyfile keys.pem\nlic MyApp.licenses --update --keyfile keys.pem --sign --field Seats=50\nlic MyApp.dll --keyfile ecdsa.pem --sign --format serial --product name=\"MyApp\" --expiredate 30 --output MyApp.serial\nInfo: A license is written unsigned unless --sign is on the command line, and an unsigned license fails validation in the application. Pass --sign whenever you pass --keyfile or --keyname, or use the MSBuild task property Sign."},{"page":136,"heading":"What You Can Do","anchor":"what-you-can-do","text":"Task | Switches\nCreate a key pair, export the public key | --keygen, --keysize, --publickey\nDescribe the license | --id, --type, --sites, --issuedate, --expiredate, --supportexpiredate, --licensee, --product, --component, --assembly\nUnlock and carry data | --feature, --field\nRestrict use | --trial, --hardware, --domain, --usage, --beta, --restriction\nSign, verify, update | --keyfile, --keyname, --keypwd, --sign, --verify, --update\nChoose the output | --output, --format, --encoding, --xmldeclaration, --keyinfo, --logfile\nIdentify a machine | --hardwareid, --salt, --showhardwareinfo\nScript and automate | --format json, --quiet, --strict-exit, --project, --makeproject\nEvery switch is described in the Reference. For CI pipelines and AI agents, the AI-Friendly Mode turns the output into a versioned JSON stream with semantic exit codes, and lic --help --format json describes every option in machine-readable form."},{"page":136,"heading":"Licensing the Tool","anchor":"licensing-the-tool","text":"lic needs a Babel Licensing license of its own. It looks for babel.licenses in its installation folder, then in the path held by the BABEL_LICENSE_PATH environment variable; the --license switch overrides both with a file, a folder to search, or env:VARIABLE for a license key stored in an environment variable. lic --license with no argument prints the license in use. See Licensing the Tool for the dotnet tool setup."},{"page":136,"heading":"In This Section","anchor":"in-this-section","text":"Babel Licensing Tool — install lic as a global or local dotnet tool, license it, and run it on a build server.\nReference — every option, grouped as in lic --help, with the key-value pairs each restriction accepts.\nAI-Friendly Mode — the lic.cli.v1 output schema, --quiet, --strict-exit and the exit code table.\nMSBuild Task — the Lic task in Babel.Build, its properties, and the .lcproj project file behind --project and --makeproject."},{"page":137,"heading":"","anchor":"","text":"Babel.Licensing.Tool packages the lic command line as a dotnet tool, so you\ncan generate and manage licenses from a terminal or a script on Windows,\nLinux and macOS with nothing but the .NET SDK installed."},{"page":137,"heading":"What the Package Contains","anchor":"what-the-package-contains","text":"Babel.Licensing.Tool is a .NET tool package that installs the lic command. It is the same command line tool shipped in the Babel zip packages, with the same options, and it comes with the Babel Licensing editions, Server and Data Center. The package ships one build of the tool for each supported runtime, .NET 6.0 through .NET 10.0, and the dotnet CLI picks the build that matches the SDK on the machine.\nLike the other Babel packages, the tool package is not on nuget.org: host it on your own feed as described in Hosting the Package, or add it to a local folder feed as shown in Client Components."},{"page":137,"heading":"When to Use the Tool","anchor":"when-to-use-the-tool","text":"Use the tool wherever licenses are produced by a process rather than by a person in Babel Desktop:\nIssuing licenses from an order pipeline, a support script or a build, on any operating system.\nGenerating and rotating signing key pairs, and exporting the public key to embed in an application.\nVerifying licenses that customers send back, and updating them without re-creating them.\nComputing the hardware key of a machine, to issue a hardware-locked license for it.\nAgent-driven automation through the AI-friendly mode, which the lic tool shares with the obfuscator.\nInfo: The tool generates licenses that the application validates offline, with the Babel.Licensing client library. Licenses managed by the Babel Licensing Service, such as activation and floating licenses, are created through the service tools instead: Babel Desktop, the web application (Data Center), the REST API or the MCP server."},{"page":137,"heading":"Installing the Tool","anchor":"installing-the-tool","text":"Global tool\nA global tool is installed once per user and available from every terminal:\ndotnet tool install Babel.Licensing.Tool -g\nWhen the feed is not listed in a NuGet.config file, pass it explicitly. The source can be a feed URL or a local folder:\ndotnet tool install Babel.Licensing.Tool -g --add-source ~/NuGet\nOn Linux and macOS make sure the tools folder is on the path, or the lic command is not found:\nexport PATH=\"$PATH:$HOME/.dotnet/tools\"\nLocal tool\nA local tool is pinned to a repository through a tool manifest, so every developer and CI agent runs the same version:\ndotnet new tool-manifest\ndotnet tool install Babel.Licensing.Tool\nThis records the tool in .config/dotnet-tools.json, which you commit. On any other machine, dotnet tool restore installs the pinned version. A local tool is invoked through the dotnet CLI:\ndotnet lic --version\nUpdating and removing\ndotnet tool update Babel.Licensing.Tool -g\ndotnet tool list -g\ndotnet tool uninstall Babel.Licensing.Tool -g\nDrop -g for a local tool. dotnet tool list shows the installed package, its version and the lic command it provides, next to babel when the obfuscator tool is installed too. The same commands are described in Install."},{"page":137,"heading":"Licensing the Tool","anchor":"licensing-the-tool","text":"The tool needs a Babel Licensing license. A dotnet tool has no installation folder you can copy babel.licenses into, so give lic the license in one of these ways:\nSet the BABEL_LICENSE_PATH environment variable to the full path of the license file. This is the recommended setup on developer machines and build agents:\nexport BABEL_LICENSE_PATH=~/Babel/babel.licenses\nPass --license on each invocation, with the path of the license file or of a folder to search.\nPass --license env:BABEL_LICENSE, where the variable holds a license key: the right choice on build servers, where the key lives in a secret.\nlic --license with no argument prints the license in use. A license file is valid for one product version: use the file that came with the same version as the tool, and update both together."},{"page":137,"heading":"Using the Tool","anchor":"using-the-tool","text":"The lic command accepts the syntax and the switches documented in Command Line Tools and in the Reference. A typical invocation names the assembly to license, the key, the license content and the output file:\nlic MyApp.dll --keyfile keys.pem --sign --licensee name=\"Contoso\" --product name=\"MyApp\" --expiredate 365 --feature Pro=1 --trial days=30 --output MyApp.licenses --encoding utf-8\nWith a local tool, prefix the command with dotnet.\nScripting and automation\nSince version 11.8 the lic command line has an AI-friendly mode designed for scripts and agents:\nlic MyApp.dll --keyfile keys.pem --sign --licensee name=\"Contoso\" --expiredate 365 --format json --quiet --strict-exit\n--format json or ndjson turns the output into a machine-readable stream and routes human diagnostics to standard error, --quiet removes the banner and makes any interactive prompt fail fast, and --strict-exit returns a distinct exit code for invalid arguments, missing input, license processing, licensing and signing failures. The exit codes are the same as the obfuscator's, so one script can drive both tools with a single table.\nRunning on a build server"},{"page":137,"heading":"Using the Tool","anchor":"using-the-tool","text":"The tool fits pipelines that issue licenses as a step, for example to license the test build of an application before its integration tests run. With a tool manifest committed to the repository and the feed configured in NuGet.config (see the GitHub Actions example for a configuration that authenticates against GitHub Packages), a GitHub Actions job looks like this:\nsteps:\n  - uses: actions/checkout@v4\n  - uses: actions/setup-dotnet@v4\n    with:\n      dotnet-version: '10.0.x'\n  - name: Restore tools\n    run: dotnet tool restore\n    env:\n      PACKAGES_TOKEN: ${{ secrets.PACKAGES_TOKEN }}\n  - name: Write the signing key\n    run: echo \"$SIGNING_KEY\" > keys.pem\n    env:\n      SIGNING_KEY: ${{ secrets.LICENSE_SIGNING_KEY }}\n  - name: Issue the test license\n    run: dotnet lic artifacts/MyApp.dll --license env:BABEL_LICENSE --keyfile keys.pem --sign --licensee name=\"CI\" --expiredate 7 --output artifacts/MyApp.licenses --quiet --strict-exit\n    env:\n      BABEL_LICENSE: ${{ secrets.BABEL_LICENSE_SECRET }}\nKeep the private key in a secret and never in the repository: whoever holds it can issue licenses for your product."},{"page":137,"heading":"Troubleshooting","anchor":"troubleshooting","text":"lic: command not found — the global tools folder is not on the path; add ~/.dotnet/tools to PATH, or use a local tool and run dotnet lic.\nA message asking to install .NET — the selected build of the tool needs the matching .NET runtime, from 6.0 to 10.0. Install that runtime, or set DOTNET_ROLL_FORWARD=Major to run the tool on a newer runtime.\nA valid license could not be found — check BABEL_LICENSE_PATH or the --license argument, then run lic --license to see what the tool loaded. A license file for a different version is reported as not valid.\nThe license is reported as not valid by the application — the license was probably written without --sign, or signed with a key pair whose public key does not match the one embedded in the application. Run lic <file> --verify --keyfile <key> to check the signature with the key you expect.\nUnrecognized option — an older lic on the path is answering; run dotnet tool list -g and lic --version to check which build you are invoking. --format json, --quiet and --strict-exit need version 11.8 or later."},{"page":138,"heading":"","anchor":"","text":"Every option of the lic command line, grouped as in the output of lic --help.\nlic <assembly|licensefile> [<other assemblies>...] [options]\nThe first argument is either the assembly the license is for, from which lic records the assembly name, version, culture and public key token in the license, or an existing license file, XML or string, to update or verify. Further assemblies add their identity to the license as well. Mandatory arguments are shown between angle brackets, optional ones between square brackets; a --[no] prefix marks a switch that can be negated.\nOptions can be abbreviated to their shortest unambiguous prefix, so --comp selects --component, and several have an alias, shown in parentheses in the headings below. Key-value options such as --licensee and --trial are repeated once per pair. Dates accept any date-time string the current culture parses, and ISO 8601 (2027-09-01) always works.\nInfo: Run lic --help <option> for the extended description of one option, or lic --help --format json for the whole option set as a machine-readable document; see AI-Friendly Mode."},{"page":138,"heading":"Miscellaneous","anchor":"miscellaneous","text":"--help [option] (-h, -?)\nDisplays the usage message with every option and a short description. With an option name, displays the extended description of that option. Combined with --format json or ndjson, emits the option schema as JSON.\nlic --help\nlic --help sign\nlic --help --format json\n--[no]logo\nDisplays or suppresses the copyright banner at startup. The banner is on by default and is always suppressed in json and ndjson output mode.\n--license [path]\nWith no argument, displays the license lic is running with and exits. With an argument, tells the tool where its own license is: the path of a license file, a folder to search for babel.licenses, or env:VARIABLE to read a license key from an environment variable. The option can be repeated. Without it, the tool looks for babel.licenses next to its executable and then in the path named by BABEL_LICENSE_PATH.\nlic --license\nlic MyApp.dll --license /opt/babel/babel.licenses ...\nlic MyApp.dll --license env:BABEL_LICENSE ...\n--verbose <n> (-v)\nSets the console verbosity. 0 prints nothing, 1 (default) prints the normal messages, and a value above 10 adds debug output, including a dump of every input variable.\n--version\nDisplays the assembly, product and file version and exits. With --format json, emits the version, runtime and platform as JSON.\n--noconfig\nSkips the default option values stored in the tool's configuration file (lic.exe.config).\n--format <name> (--fmt)\nCLI output formats available since 11.8."},{"page":138,"heading":"Miscellaneous","anchor":"miscellaneous","text":"Selects either the license output format or the command line output format. The two value sets are disjoint, so one option covers both, and the two can appear in the same command line.\nValue | Meaning\nxml | Default. An XML license file (.licenses), the format the Babel.Licensing client validates from a file.\nserial | A string license in the default string encoding, suitable for a serial number the user types.\nbase32 | A string license encoded in Base32 (uppercase letters and digits).\nascii | A string license encoded in readable ASCII, the most compact of the string formats.\ntext | Command line output: the default human-readable console output.\njson | Command line output: one JSON document on standard output, conforming to lic.cli.v1.\nndjson | Command line output: newline-delimited JSON, one event per line, streamed as produced.\nString licenses are written to the --output file as a single line of text. They carry the same content as the XML form and validate the same way, through StringLicense in the client library.\nlic MyApp.dll --keyfile ecdsa.pem --sign --format serial --output MyApp.serial\nlic MyApp.dll --keyfile keys.pem --sign --format json --quiet --strict-exit\nlic MyApp.dll --keyfile ecdsa.pem --sign --format base32 --format ndjson\n--keygen [type] (--kg)"},{"page":138,"heading":"Miscellaneous","anchor":"miscellaneous","text":"Generates a new key pair and writes it in PEM format to the file named by --keyfile. The type is rsa (default) or ecdsa. Use --keysize to choose the strength; the private key in the file signs licenses and must be kept secret, while --publickey extracts the public half for the application.\nlic --keygen rsa --keysize 2048 --keyfile keys.pem\nlic --keygen ecdsa --keysize 256 --keyfile ecdsa.pem\nRSA keys sign XML licenses with the rsa or dsig algorithm; ECDSA keys produce the shortest string licenses and are the usual choice for serials.\n--keysize <size> (--ks)\nSets the key size for --keygen. RSA accepts sizes from 384 to 4096 bits; ECDSA accepts 112, 192, 256, 384 or 521 bits. A larger ECDSA key produces a longer serial.\n--[no]keyinfo\nWhether to include the public key information in the RSA signature element of an XML license. It can be omitted when the licensed assembly has a strong name, because the client extracts the RSA public key from the strong name to validate the license.\n--publickey (--pk)\nPrints the public key of the key pair given with --keyfile, for RSA, ECDSA and XML digital signature keys. Embed this value in the application, which uses it to validate licenses.\nlic --publickey --keyfile keys.pem\n--[no]xmldeclaration\nWhether to write the XML declaration at the top of an XML license file. On by default.\n--encoding <name>"},{"page":138,"heading":"Miscellaneous","anchor":"miscellaneous","text":"Sets the character encoding of the XML license file, by encoding name (utf-8, utf-16, us-ascii, and any other encoding registered on the machine). By default the file is written in UTF-16 with a byte-order mark; pass utf-8 for a file that is easier to inspect and to embed.\n--showhardwareinfo (--show-hardware-info)\nPrints the information the hardware key is computed from on the current machine: system name, UUID, manufacturer, product name, BIOS and motherboard serial numbers, operating system, memory, whether a virtual machine is detected, and the CPU identity. Useful for support cases where a hardware-locked license does not validate.\n--hardwareid <component> (--hardware-id, --hwid)\nComputes the hardware key of the current machine and prints it as HardwareKey=XXXXX-XXXXX-XXXXX-XXXXX-XXXXX. The optional list of components selects what the key is derived from: cpu, ethernet (MAC address), disk (serial number), motherboard, bios, computername (default) or all. The key is what you pass to --hardware key= when issuing a hardware-locked license, and what the application computes with the same components at validation time.\nlic --hardwareid cpu,disk,computername\n--salt [hex string|size] (-s)\nAdds random data to the hardware key computation, so that two products locked to the same machine do not share the same key. Pass a hexadecimal string to use a fixed salt, or a size to generate one; the generated salt is printed as Salt= and must be used again at validation time."},{"page":138,"heading":"Miscellaneous","anchor":"miscellaneous","text":"--register <assembly>\nLoads an extension assembly before processing. An extension can provide custom restriction types for --restriction, custom signature providers for --sign, and services such as an alternative hardware identification. The option can be repeated.\n--[no]quiet (-q)\nAvailable since 11.8.\nSuppresses the copyright banner and every interactive prompt, so the command never blocks waiting for input: a missing --keypwd fails with an explicit error instead of asking for the password. Intended for CI pipelines and unattended runs. See AI-Friendly Mode.\n--[no]strict-exit\nAvailable since 11.8.\nReturns a semantic exit code instead of the default 0 for success and 1 for any failure: 10 invalid arguments, 20 input file not found, 30 license processing failure, 40 licensing failure, 50 key or signing failure. The codes match the obfuscator's. See AI-Friendly Mode."},{"page":138,"heading":"License","anchor":"license","text":"--id [licid]\nSets the license identifier. Without an argument a new identifier is generated. The identifier is what --update and --verify use to address one license inside a file that holds several.\n--type <type>\nSets the license type, a free text such as Standard, Professional or Trial that the application can read to select an edition.\n--sites <number>\nSets the number of sites, or seats, the license covers.\n--issuedate [date]\nSets the issue date. Without an argument, the current date and time is used.\n--expiredate <date>\nSets the expiration date, either as a date-time string or as a number of days from today.\nlic MyApp.dll --expiredate 2027-09-01 ...\nlic MyApp.dll --expiredate 365 ...\n--supportexpiredate <date>\nSets the date on which product support expires, independently from the license itself.\n--[no]assembly <file|name> (--asm, --no-asm)\nAdds the identity of another assembly to the license, from a file or from an assembly name; the option can be repeated and accepts wildcards. --noassembly removes all assembly information, which produces a license that is not tied to a specific assembly.\nlic MyApp.dll --assembly \"MyApp.Core, Version=2.1.0.0\" ...\nlic MyApp.dll --assembly \"*, Version=\" ...\nlic MyApp.dll --noassembly ...\n--licensee <key=value>\nSets the licensee information, one pair per option: id, name, company and email.\nlic MyApp.dll --licensee id=C-1001 --licensee name=\"Contoso\" --licensee company=\"Contoso Ltd\" --licensee email=info@contoso.com ...\n--product <key=value>"},{"page":138,"heading":"License","anchor":"license","text":"Sets the product information, one pair per option: id, name, version, copy (copyright notice), descr (description) and url.\nlic MyApp.dll --product id=MYAPP --product name=\"MyApp\" --product version=2.1 --product url=https://contoso.example ...\n--component <name>\nAdds a licensed component, for products that license individual components or modules of an assembly. The option can be repeated.\n--feature <file|key=value>\nAdds or updates a license feature, the switches the application checks to enable parts of the product. With key=value, the feature takes the key as its name and the value as its data. With a file path or wildcard, each file becomes a feature named after the file, with the file content as data. With def=file, an external XML file supplies the complete feature definition, including expiration dates and description.\nlic MyApp.dll --feature Pro=1 --feature Export=csv,xlsx ...\nlic MyApp.dll --feature \"features/*.txt\" ...\nlic MyApp.dll --feature def=features.xml ...\n--field <file|key=value>\nAdds or updates a license field, a named value the application reads: seat counts, configuration, a code encryption password, and so on. The same three forms as --feature apply: key=value, a file whose name and content become the field, or def=file for an XML definition.\nlic MyApp.dll --field Seats=25 --field Region=EU ...\n--sign [type]"},{"page":138,"heading":"License","anchor":"license","text":"Signs the license with the key pair given by --keyfile or --keyname. The optional type selects the algorithm: rsa (default with an RSA key), ecdsa (with an ECDSA key) or dsig, the XML digital signature standard, with an RSA key. The algorithm must match the key: an RSA key cannot produce an ECDSA signature and vice versa.\nlic MyApp.dll --keyfile keys.pem --sign ...\nlic MyApp.dll --keyfile keys.pem --sign dsig ...\nlic MyApp.dll --keyfile ecdsa.pem --sign ecdsa --format serial ...\nWarning: Without --sign the license is written without a signature, and the client library rejects it. --keyfile alone only makes the key available; it does not sign.\n--[no]verify (--validate)\nVerifies the signature of the input license file with the key given by --keyfile or --keyname; only the public key is needed. The tool reports verified successfully or is not valid, and with --strict-exit a failed verification exits with code 30.\nlic MyApp.licenses --verify --keyfile keys.pem\n--update [licid|all]\nUpdates a license inside the input license file instead of creating a new one: every license switch on the command line replaces the corresponding value, and the file is written back. Without an argument the first license in the file is updated; pass a license identifier to address one license, or all to update every license in the file. Pass --sign again to re-sign the modified license.\nlic MyApp.licenses --update --keyfile keys.pem --sign --licensee company=\"Contoso Ltd\" --field Seats=50"},{"page":138,"heading":"License Restrictions","anchor":"license-restrictions","text":"Each restriction option takes key=value pairs, one per option, and can be repeated. Every restriction accepts id=<id> to set its identifier and expire=<date> to give it an expiration date of its own. See License Restrictions for how the client library evaluates each one.\n--trial <key=value>\nAdds or updates a trial restriction:\nKey | Meaning\ndays=<n> | Number of days the software can be used after the first run.\ntime=<timespan> | Total usage time allowed.\ninstances=<n> | Number of instances that can run at the same time.\nterms=<text> | Terms and conditions text shown for the trial.\nlic MyApp.dll --trial days=30 --trial instances=2 ...\n--hardware <key=value>\nAdds or updates a hardware restriction, locking the license to a machine: key=<key> is the hardware key computed with --hardwareid on the target machine, and data=<data> embeds additional hardware data.\nlic MyApp.dll --hardware key=GPHI6-128DI-6196C-KN5LV-BCDRE ...\n--domain <key=value>\nAdds or updates a domain restriction: name=<name> is the network domain the machine must belong to, and role=<role> the network role.\n--usage <key=value>\nAdds or updates a usage restriction: type=<context> limits the license to the Runtime or Designtime context, vm=<true|false> allows or forbids running in a virtual machine, and processlist=<list> names the processes allowed to use the license.\nlic MyApp.dll --usage processlist=proc1,proc2,proc3 --usage vm=false ...\n--beta <key=value>"},{"page":138,"heading":"License Restrictions","anchor":"license-restrictions","text":"Adds or updates a beta restriction, for pre-release builds: build=<text> sets the beta build type and changes=<text> describes the recent changes.\n--restriction <name:key=value>\nAdds or updates a custom restriction, identified by its name, with the given key-value pairs. The restriction type must be provided by an extension assembly registered with --register; without one the tool reports that no license factory is set.\nlic MyApp.dll --register Contoso.Licensing.dll --restriction \"Region:name=EU\" ..."},{"page":138,"heading":"Output Files","anchor":"output-files","text":"--output <file> (--out)\nSets the output file. By default the license is saved next to the input file as <assembly file>.licenses.\n--logfile [file] (--log)\nRedirects the console output to a log file. Without an argument the log is named after the output file with a .log extension.\n--makeproject [file] (--mp)\nSaves the whole command line as an MSBuild project file that runs the Lic task with the same settings. Without an argument the project is named after the output file with an .lcproj extension. The license is generated as well. See MSBuild Task."},{"page":138,"heading":"Input Files","anchor":"input-files","text":"--keyfile <file> (--kf)\nThe key file used to sign or verify the license. Supported formats are PEM (as written by --keygen), SNK strong-name key files and PFX certificates; a PFX file usually needs --keypwd.\n--keyname <container> (--kn)\nSigns or verifies with a key pair stored in a key container of the operating system, given by container name, instead of a file.\n--keypwd <password> (--kp)\nThe password of a PFX key file. Without it the tool prompts for the password; with --quiet it fails instead of prompting. On a build server, keep the password in an environment variable and expand it on the command line.\n--project <file> (--prj)\nRuns lic with the settings stored in an .lcproj project file, as produced by --makeproject or written by hand. Switches on the command line are applied on top of the project settings."},{"page":138,"heading":"Long and Short Options","anchor":"long-and-short-options","text":"Long options are introduced by two hyphens, short options and single-letter aliases by one: --verbose 2 and -v 2 are equivalent, as are --keyfile and --kf. A long option can be abbreviated to any prefix that is not ambiguous. Switches marked --[no] are turned off with the no or no- prefix, so --nologo, --no-logo and --noassembly are all valid."},{"page":138,"heading":"Exit Codes","anchor":"exit-codes","text":"By default the process returns 0 on success and 1 on any failure. With --strict-exit the failure class is returned instead; the same class is always reported as exitReason in the JSON output, with or without --strict-exit.\nExit code | exitReason | Meaning\n0 | success | The command completed without errors.\n10 | invalidArguments | The command line could not be parsed or contained an invalid value.\n20 | inputNotFound | The assembly, license file or another required input was not found.\n30 | processingFailure | License processing failed, including a signature that did not verify.\n40 | licensingFailure | The tool's own license is missing, invalid or expired.\n50 | keyOrSigningFailure | A key could not be loaded or a cryptographic operation failed."},{"page":139,"heading":"","anchor":"","text":"Starting with Babel Licensing 11.8, the lic command line can emit a\nstructured, machine-readable output stream suited to CI pipelines, order\nsystems and AI agents, matching the mode the obfuscator gained in 11.7.\nThe default text output of lic is unchanged and remains fully backward compatible: existing scripts require no changes.\nThe AI-friendly mode is enabled by three global flags:\n--format=text|json|ndjson selects the output channel format\n--quiet (alias -q) suppresses the logo banner and fails fast on interactive prompts\n--strict-exit opts into semantic exit codes\nWhen --format=json or --format=ndjson is selected, stdout carries the structured stream and the human-readable messages are routed to stderr, so the two channels never interleave.\nInfo: --format is also the option that selects the license output format (xml, serial, base32, ascii). The two value sets are disjoint, so both meanings can appear in one command line: lic MyApp.dll --format base32 --format json."},{"page":139,"heading":"Flags","anchor":"flags","text":"--format <format>\nSelects the output format used on stdout. Allowed values:\nValue | Description\ntext | Default. Legacy human-readable console output.\njson | Buffered single JSON document written when the run completes (or on --help / --version). Best when stdout is captured to a file or piped into a JSON consumer.\nndjson | Newline-delimited JSON. One event per line, flushed as it is produced. Best for streaming consumers, log shippers and live agents.\nlic MyApp.dll --keyfile keys.pem --sign --expiredate 365 --format json > result.json\nlic MyApp.dll --keyfile keys.pem --sign --format ndjson | jq -c 'select(.level==\"error\")'\nWith json or ndjson the logo banner is suppressed regardless of --logo, so that the first byte on stdout is valid JSON.\n--quiet (-q)\nSuppresses the copyright banner and every interactive prompt. The only prompt lic has is the password of a PFX key file: with --quiet, a missing --keypwd fails with an explicit error instead of blocking on input, which makes the flag safe for unattended runs on CI runners, in containers and from agents.\nlic MyApp.dll --quiet --keyfile signing.pfx --keypwd \"$KEY_PWD\" --sign\n--quiet is independent from --format: it can be combined with the text output to keep human-readable logs without the banner.\n--strict-exit\nOpts the process into semantic exit codes. Without this flag, lic preserves the legacy contract where 0 means success and 1 means any failure."},{"page":139,"heading":"Flags","anchor":"flags","text":"Exit code | Constant | Meaning\n0 | success | The command completed without errors.\n10 | invalidArguments | The command line could not be parsed or contained an invalid value (for example an unknown option).\n20 | inputNotFound | The assembly, license file or another required input file was not found.\n30 | processingFailure | License processing failed: generation, update, or a signature that did not verify.\n40 | licensingFailure | The tool's own Babel Licensing license is missing, invalid or expired.\n50 | keyOrSigningFailure | A key file or container could not be loaded, or a cryptographic operation failed.\nThe numbers are the same as the obfuscator's --strict-exit table, so one caller can drive babel and lic from a single exit-code table; the only difference is that code 30 means license processing here and obfuscation there. The classification is also surfaced as exitReason in the JSON result, even when --strict-exit is not active.\nlic MyApp.licenses --verify --keyfile keys.pem --strict-exit --quiet\necho \"exit=$?\""},{"page":139,"heading":"Schema: lic.cli.v1","anchor":"schema-liccliv1","text":"All structured payloads carry \"schema\": \"lic.cli.v1\" and a kind that tells what the document is: event, result, help or version. The schema mirrors the obfuscator's babel.cli.v1 but is versioned separately, because the two tools expose different option sets. Within a major schema version, additive changes are allowed; breaking changes will bump the schema name.\nEvent record\nEvery message emitted while a run is in progress is mapped to an event:\n{\n  \"schema\":  \"lic.cli.v1\",\n  \"kind\":    \"event\",\n  \"ts\":      \"2026-09-03T06:31:54.1686900Z\",\n  \"level\":   \"info\",\n  \"message\": \"License saved to 'MyApp.licenses'\"\n}\nField | Type | Notes\nts | string (ISO 8601, UTC) | Timestamp at which the event was produced.\nlevel | debug | info | warning | error | Severity.\ncode | string | Diagnostic code, present only when the message has one.\nmessage | string | Human-readable message.\ndata | object | Optional structured payload, present only when attached.\nResult envelope\n--format=json\nA single JSON object is written to stdout when the run terminates. It contains the run-level summary and all events buffered during the run:\n{\n  \"schema\":     \"lic.cli.v1\",\n  \"kind\":       \"result\",\n  \"exitCode\":   0,\n  \"exitReason\": \"success\",\n  \"elapsedMs\":  133,\n  \"warnings\":   0,\n  \"errors\":     0,\n  \"events\": [\n    { \"schema\": \"lic.cli.v1\", \"kind\": \"event\", \"ts\": \"2026-09-03T06:31:54.1686900Z\", \"level\": \"info\", \"message\": \"License saved to 'MyApp.licenses'\" }\n  ]\n}"},{"page":139,"heading":"Schema: lic.cli.v1","anchor":"schema-liccliv1","text":"A failed run reports the failure class in exitReason and the error among the events. Here the input assembly did not exist:\n{\n  \"schema\":     \"lic.cli.v1\",\n  \"kind\":       \"result\",\n  \"exitCode\":   20,\n  \"exitReason\": \"inputNotFound\",\n  \"elapsedMs\":  34,\n  \"warnings\":   0,\n  \"errors\":     1,\n  \"events\": [\n    { \"schema\": \"lic.cli.v1\", \"kind\": \"event\", \"ts\": \"2026-09-03T06:30:27.4366510Z\", \"level\": \"error\", \"message\": \"Error: The specified file '/build/missing.dll' was not found.\" }\n  ]\n}\n--format=ndjson\nEach event is flushed as soon as it is produced, on its own line. After the last event, a final result line is appended, without an events array since the events have already been streamed:\n{\"schema\":\"lic.cli.v1\",\"kind\":\"event\",\"ts\":\"2026-09-03T06:31:54.3357790Z\",\"level\":\"info\",\"message\":\"License saved to 'MyApp.licenses'\"}\n{\"schema\":\"lic.cli.v1\",\"kind\":\"result\",\"exitCode\":0,\"exitReason\":\"success\",\"elapsedMs\":141,\"warnings\":0,\"errors\":0}\nField | Type | Notes\nexitCode | integer | Numeric exit code actually returned by the process (legacy or strict, depending on --strict-exit).\nexitReason | string | Stable classification token. Always reflects the semantic class, even without --strict-exit.\nelapsedMs | integer | Total wall-clock duration in milliseconds.\nwarnings | integer | Count of warning-level events.\nerrors | integer | Count of error-level events.\nevents | array | Present in json mode; omitted in ndjson."},{"page":139,"heading":"Machine-readable --help","anchor":"machine-readable---help","text":"lic --help --format=json emits a complete description of every public option, suitable for tooling that needs to introspect the CLI surface: shell completions, AI agents, documentation generators.\n{\n  \"schema\":  \"lic.cli.v1\",\n  \"kind\":    \"help\",\n  \"version\": \"12.0.0.0\",\n  \"usage\":   \"lic.exe <assembly|licensefile> [<other assemblies>...] [options]\",\n  \"options\": [\n    {\n      \"name\":        \"trial\",\n      \"aliases\":     [],\n      \"description\": \"Add or update trial license restriction\",\n      \"args\":        \"<key=value>\",\n      \"argRequired\": true,\n      \"argOptional\": false,\n      \"negatable\":   false,\n      \"incremental\": false,\n      \"container\":   \"hash\",\n      \"type\":        \"string\",\n      \"group\":       \"- License Restrictions -\",\n      \"details\":     \"Set trial restriction properties entering key-value pairs:\\n\\nid=<id>         Restriction id\\nexpire=<date>   Set expiration date\\ndays=<n>        Set number of trial days\\n...\"\n    }\n  ]\n}"},{"page":139,"heading":"Machine-readable --help","anchor":"machine-readable---help","text":"Field | Meaning\nname, aliases | The option name and its alternative spellings, including negated forms and single-letter aliases.\nargs | The argument placeholder as shown in the usage, or empty for a switch.\nargRequired, argOptional | Whether the option takes a mandatory or an optional argument.\nnegatable | Whether the option accepts the no prefix.\ncontainer | scalar for a single value, array for a repeatable option, hash for key=value pairs.\ntype | string or integer.\ngroup | The section of the help output the option belongs to.\ndetails | The extended description, the same text lic --help <option> prints.\nA scoped form is also supported: lic --help trial --format=json emits the same envelope containing only the trial option. Hidden and internal options are never returned."},{"page":139,"heading":"Machine-readable --version","anchor":"machine-readable---version","text":"lic --version --format=json emits product, version, runtime and platform information:\n{\n  \"schema\":      \"lic.cli.v1\",\n  \"kind\":        \"version\",\n  \"product\":     \"Babel Licensing\",\n  \"version\":     \"12.0.0.0\",\n  \"fileVersion\": \"12.0.0.1\",\n  \"runtime\":     \".NET 10.0.0\",\n  \"platform\":    \"osx-arm64\"\n}\nThe platform field uses the .NET runtime identifier (RID) on .NET 5 and later, and a synthetic <os>-<arch> string on legacy targets."},{"page":139,"heading":"Driving lic From an Agent","anchor":"driving-lic-from-an-agent","text":"An agent that has never seen lic can operate it from the JSON help alone: read the option schema, build the command line from the args and container hints, run with --format json --quiet --strict-exit, and branch on exitReason. A typical loop for issuing a license looks like this:\nlic --help --format json > lic-options.json\nlic MyApp.dll --keyfile keys.pem --sign --licensee name=\"Contoso\" --expiredate 365 --output MyApp.licenses --format json --quiet --strict-exit > result.json\njq -r '.exitReason' result.json\nThe same contract, exit codes and flag names apply to the obfuscator command line, documented in AI-Friendly Mode of the obfuscator manual, so one integration covers both tools."},{"page":139,"heading":"Backward compatibility","anchor":"backward-compatibility","text":"The default value of --format is text; the legacy textual output, exit codes and behavior are unchanged when no new flag is specified.\nWithout --strict-exit, the process keeps returning 0 on success and 1 on any failure, so existing gates that branch on $? keep working.\n--quiet is independent and can be opted into without enabling structured output."},{"page":140,"heading":"","anchor":"","text":"The Lic task runs the lic command line from an MSBuild project, so a build\ncan generate and sign licenses with the same properties as the command line.\nThe Lic task lives in Babel.Build.dll, the same assembly that provides the obfuscator's Babel task. It builds a lic command line from its properties and items and runs lic.exe, so everything the Reference describes is available from a project file. Two things use it:\nYour own MSBuild projects, for example to issue a test license for the application under test, or to generate customer licenses from a build server.\n.lcproj project files, which lic --makeproject writes from a command line and lic --project runs again; see Project Files."},{"page":140,"heading":"Registering the Task","anchor":"registering-the-task","text":"Reference the task assembly with a UsingTask element that points to Babel.Build.dll. In the Babel zip packages it is in the MSBuild folder, so with BabelDir set to the folder where babel_net472_<version>.zip was extracted:\n<UsingTask TaskName=\"Lic\" AssemblyFile=\"$(BabelDir)\\MSBuild\\Babel.Build.dll\" />\nThe task runs lic.exe from the folder set by LicDirectory. Without it, the task looks next to Babel.Build.dll and then in the folder named by the BABEL_INSTALL_DIRECTORY environment variable. Because lic.exe sits in the root of the extracted zip package, not in its MSBuild folder, set LicDirectory to that root, as the example below does.\nInfo: With LicDirectory set, the task runs lic.exe, which requires Windows. The babel_net80, babel_net90 and babel_net100 zip packages also contain MSBuild/Babel.Build.dll and lic.dll: when MSBuild runs under the dotnet host and the task finds lic.dll without LicDirectory, it runs it through dotnet. Wherever only the Babel Licensing Tool is available, run lic from an Exec task instead; the switches are the same."},{"page":140,"heading":"A Complete Example","anchor":"a-complete-example","text":"The project below generates a signed license for the built assembly after the build. Licensee, product, features, fields and restrictions are MSBuild items whose metadata become the key=value pairs of the corresponding switches:"},{"page":140,"heading":"A Complete Example","anchor":"a-complete-example","text":"<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <UsingTask TaskName=\"Lic\" AssemblyFile=\"$(BabelDir)\\MSBuild\\Babel.Build.dll\" />\n\n  <PropertyGroup>\n    <BabelDir>C:\\Tools\\babel_net472</BabelDir>\n    <LicenseKeyFile>$(MSBuildProjectDirectory)\\keys\\signing.pem</LicenseKeyFile>\n    <LicenseOutputFile>$(OutDir)MyApp.licenses</LicenseOutputFile>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Licensee Include=\"Contoso\">\n      <Id>C-1001</Id>\n      <Company>Contoso Ltd</Company>\n      <Email>info@contoso.com</Email>\n    </Licensee>\n    <Product Include=\"MyApp\">\n      <Id>MYAPP</Id>\n      <Version>2.1</Version>\n      <Url>https://contoso.example</Url>\n    </Product>\n    <Feature Include=\"Pro\">\n      <Data>1</Data>\n    </Feature>\n    <Field Include=\"Seats\">\n      <Value>25</Value>\n    </Field>\n    <Restriction Include=\"Trial\">\n      <TrialDays>30</TrialDays>\n      <RunInstances>2</RunInstances>\n    </Restriction>\n    <Restriction Include=\"Hardware\">\n      <HardwareKey>GPHI6-128DI-6196C-KN5LV-BCDRE</HardwareKey>\n    </Restriction>\n  </ItemGroup>\n\n  <Target Name=\"MakeLicense\" AfterTargets=\"Build\">\n    <Lic LicDirectory=\"$(BabelDir)\"\n         InputFile=\"$(TargetPath)\"\n         OutputFile=\"$(LicenseOutputFile)\"\n         KeyFile=\"$(LicenseKeyFile)\"\n         Sign=\"rsa\"\n         ExpireDate=\"365\"\n         Encoding=\"utf-8\"\n         Licensee=\"@(Licensee)\"\n         Product=\"@(Product)\"\n         Features=\"@(Feature)\"\n         Fields=\"@(Field)\""},{"page":140,"heading":"A Complete Example","anchor":"a-complete-example","text":"         Restrictions=\"@(Restriction)\" />\n  </Target>\n</Project>\nThis is equivalent to the command line:\nlic MyApp.dll --keyfile keys\\signing.pem --sign rsa --expiredate 365 --encoding utf-8 --licensee name=Contoso --licensee id=C-1001 --licensee company=\"Contoso Ltd\" --licensee email=info@contoso.com --product name=MyApp --product id=MYAPP --product version=2.1 --product url=https://contoso.example --feature def=... --field def=... --trial days=30 --trial instances=2 --hardware key=GPHI6-128DI-6196C-KN5LV-BCDRE --output MyApp.licenses\nSet ProvideCommandLineArgs=\"true\" and read the CommandLineArgs output item to see the exact command line the task built."},{"page":140,"heading":"Task Properties","anchor":"task-properties","text":"Each property maps to the switch of the same meaning in the Reference. Scalar properties take a string; item properties take an item list.\nInput and output\nProperty | Switch | Description\nInputFile | first argument | The assembly to license, or the license file to update or verify.\nProject | --project | An .lcproj project file whose settings are applied first.\nAssemblies | --assembly | Items naming other assemblies, by file or by name, to add to the license.\nOutputFile | --output | The output license file.\nFormat | --format | xml, serial, base32 or ascii; also json or ndjson for the task's console output.\nEncoding | --encoding | Character encoding of the XML license file.\nXmlDeclaration | --[no]xmldeclaration | Whether to write the XML declaration.\nGenerateKeyInfo | --[no]keyinfo | Whether to include the public key information in the RSA signature element.\nMakeProject | --makeproject | Write an .lcproj project file with the effective settings.\nGenerateLogFile, LogFile | --logfile | Redirect the console output to a log file, named by LogFile or by the output file.\nKeys and signature"},{"page":140,"heading":"Task Properties","anchor":"task-properties","text":"Property | Switch | Description\nKeyFile | --keyfile | PEM, SNK or PFX key file.\nKeyContainer | --keyname | Key container name.\nKeyPwd | --keypwd | Password of a PFX key file.\nKeyGen | --keygen | rsa or ecdsa: generate a new key pair into KeyFile.\nKeySize | --keysize | Key size for KeyGen.\nSign | --sign | Sign the license: rsa, ecdsa or dsig. The license is unsigned when this property is empty.\nVerify | --verify | true to verify the signature of InputFile instead of generating a license.\nLicense content\nProperty | Switch | Description\nLicenseId | --id | License identifier.\nLicenseType | --type | License type text.\nIssueDate | --issuedate | Issue date.\nExpireDate | --expiredate | Expiration date, or a number of days.\nLicensee | --licensee | One item: Include is the name; metadata Id, Name, Company, Email.\nProduct | --product | One item: Include is the name; metadata Id, Name, Version, Copyright, Description, Url.\nComponents | --component | Items naming the licensed components.\nFeatures | --feature | Items: Include is a file path, or the feature name with metadata Id, Name, Description, Key, Data, ExpireDate, SupportExpireDate.\nFields | --field | Items: Include is a file path, or the field name with metadata Id, Name, Value.\nRestrictions | restriction switches | Items whose Include selects the restriction type; see Restriction items.\nUpdate | --update | Update the license with the given identifier, or all, in InputFile.\nRestriction items"},{"page":140,"heading":"Task Properties","anchor":"task-properties","text":"The Include value of a Restriction item selects the switch, case-insensitively, and the metadata supply its key=value pairs. Any other Include value is treated as a custom restriction name, passed to --restriction with each metadata as a pair; custom types need an extension assembly listed in Register.\nInclude | Switch | Metadata\nTrial | --trial | TrialDays (or ExpireDays), RunCount, RunInstances (or AllowedInstances), RunTime (or UsageTime), Terms.\nHardware | --hardware | HardwareKey (or Key), Data.\nDomain | --domain | Name, Role.\nUsage | --usage | Type, CanRunOnVirtualMachine (or CanRunInVirtualEnvironment), ProcessList.\nBeta | --beta | BuildType, RecentChanges, Description.\nHardware identification\nProperty | Switch | Description\nHardwareId | --hardwareid | Items naming the components to derive the hardware key from.\nSalt | --salt | Salt for the hardware key.\nShowHardwareInfo | --showhardwareinfo | Print the hardware information of the build machine.\nTool and diagnostics"},{"page":140,"heading":"Task Properties","anchor":"task-properties","text":"Property | Switch | Description\nLicense | --license | Items with the paths of the tool's own license file or search folders.\nLicDirectory |  | Folder containing the lic.exe to run, such as the root of the extracted Babel zip package.\nRegister | --register | Items naming extension assemblies to load.\nShowLogo | --[no]logo | Whether to print the banner.\nVerboseLevel | --verbose | Console verbosity.\nNoConfiguration | --noconfig | Skip the tool's default configuration.\nProvideCommandLineArgs |  | true to expose the generated command line in the CommandLineArgs output item."},{"page":140,"heading":"Project Files","anchor":"project-files","text":"An .lcproj file is an ordinary MSBuild project that registers the Lic task and calls it from a MakeLicense target, with the settings of one license generation. lic --makeproject writes one from the switches of the current command line, next to the output file unless a name is given, and still generates the license. lic --project reads such a file and runs it, applying any further switches on top, without invoking MSBuild; the file can also be built with msbuild or dotnet build on a machine where the task is registered.\nlic MyApp.dll --keyfile keys.pem --sign --licensee name=Contoso --expiredate 365 --output MyApp.licenses --makeproject MyApp.lcproj\nlic --project MyApp.lcproj --licensee name=\"Fabrikam\" --output Fabrikam.licenses\nThe project file keeps a reproducible record of how a license was produced, and gives a customer-specific generation a single file you can version, review and rerun."},{"page":141,"heading":"","anchor":"","text":"The Babel Licensing Service WordPress Plugin enables seamless integration of the Babel Licensing Service with WordPress, facilitating robust license management directly within the WordPress admin interface.\nBabel Licensing WordPress Admin\nThis plugin delivers a streamlined and intuitive interface within the WordPress admin panel, specifically designed for the management of Products, License Templates, Customers and Licenses associated with the Babel Licensing Database.\nKey Features"},{"page":141,"heading":"","anchor":"","text":"WooCommerce Integration: The plugin seamlessly integrates with WooCommerce, enabling automated dispatch of license keys via email to customers immediately after an order is placed. This integration ensures a smooth purchase flow, where licenses are generated and sent without manual intervention when a licensed product is purchased through the WooCommerce shop page.\nDashboard Widget: It includes a dashboard widget that provides administrators with a graphical representation and a table view of licensing data, offering a comprehensive overview of license distributions and statuses.\nEmail Template Management: Administrators can customize email notifications with dedicated interfaces for editing templates. These templates are used for sending out notifications when a license is issued, expires, or when support or trial periods end.\nAPI Connectivity: The plugin offers configuration options to connect with the Babel Licensing Service API, enabling advanced features and external integrations to further extend its functionality.\nAutomated License Management: It automates the entire process of license creation, issuance, and management, reducing the administrative burden and enhancing efficiency.\nCompatibility\nThe Babel Licensing WordPress Plugin is designed to work seamlessly with a variety of WordPress and WooCommerce versions, as well as with the Babel Licensing Service."},{"page":141,"heading":"","anchor":"","text":"Please ensure that your WordPress, WooCommerce, and Babel Licensing Service versions meet these requirements before installing or updating the plugin. This will help to prevent any compatibility issues and ensure that the plugin functions as expected."},{"page":142,"heading":"","anchor":"","text":"Once the Babel Licensing plugin is activated, you configure it from the WordPress dashboard.\nThe plugin's settings are divided into three tabs:\nGeneral\nLicenses\nEmails\neach catering to different aspects of the plugin configuration. Follow the steps below to configure the plugin through its Settings menu."},{"page":142,"heading":"General","anchor":"general","text":"To configure the plugin to connect to the Babel Licensing Service via its web API:\nOpen the Babel Licensing Service section\nUnder the General tab, locate the Babel Licensing Service section.\nEnter the service URL\nIn the Service URL, enter the URL for the Babel Licensing Service included the service port.\nEnter the API key\nInsert the API Key with administrative rights generated in the web application, with the Management API, or in Babel Desktop (API keys view) running on the service machine with a local management profile.\nSave the settings\nPress Save Settings to apply the configuration.\nBabel Licensing Settings General Tab"},{"page":142,"heading":"Enable Debugging","anchor":"enable-debugging","text":"To enable debugging for the Babel Licensing plugin:\nOpen the Debug section\nScroll down to the Debug section in the settings.\nTurn on logging\nToggle the Enable switch to on. This activates logging for all activities performed by the Babel Licensing plugin.\nAll logs are recorded in a dedicated table within your WordPress database named wp_blic_log. Enabling debugging is useful for troubleshooting but can generate a large amount of data. Disable it when not needed to conserve database space."},{"page":142,"heading":"Licenses","anchor":"licenses","text":"This section outlines the steps to integrate Babel Licensing with your WooCommerce extension, enabling automatic license generation upon successful order processing of licensed products.\nCheck the Enable switch to activate the WooCommerce integration\nEnable the Trace Licenses switch to activate the tracing of every new license created through the WooCommerce order management. This ensures every new license is tracked and recorded for auditing and troubleshooting purposes.\nWith these settings configured, Babel Licensing will automatically generate a new license each time a designated product order is successfully completed in WooCommerce.\nBabel Licensing Settings Licenses Tab"},{"page":142,"heading":"Emails","anchor":"emails","text":"Babel Licensing can automatically send emails at different stages of the license lifecycle to inform both the administrator and the customer.\nOpen the Emails tab\nNavigate to the Emails tab in the Babel Licensing settings.\nTurn on email sending\nUnder the Emails section, activate the Enable switch to allow the system to send emails automatically.\nConfigure each email\nConfigure the following settings for each email:\nFrom Email Address: Specify the email address to display in the 'From' field.\nAttach License File: Choose to include the generated license file as an email attachment.\nEnable Zip Attachment: This feature allows the enclosing of the license file within a zip archive. It is beneficial in scenarios where the email server filters out the license file extension. (Requires the PHP Zip module installed)\nBlacklist Recipients: Email addresses that are blocked from receiving any emails. Addresses are listed one per line and may include regular expressions to match entire domains. For example:\n@yahoo.*\n@hotmail.*\nSchedule Notifications\nThis section is designed to manage the automated email notifications for upcoming license or support expirations."},{"page":142,"heading":"Emails","anchor":"emails","text":"Schedule Send (toggle): This option allows you to activate or deactivate the automatic sending of notifications.\nSchedule Time: Specifies the exact UTC time of day when the notification emails are dispatched.\nExpiration Warning Days: Determines how many days in advance users are alerted about their license or support nearing its expiration date.\nBabel Licensing Settings Emails Tab"},{"page":143,"heading":"","anchor":"","text":"The Customers page within the Babel Licensing WordPress Plugin is a central hub for managing customer data that is critical for the licensing process. This page provides administrators with a comprehensive view of all customers who have made purchases, where customer records are automatically generated from WooCommerce transactions whenever a new order arrives. This integration facilitates seamless management of licensees and the issuance of new licenses.\nGrid Columns\nId: Displays a unique identifier for each customer, aiding in quick reference and database management.\nName: Shows the full name of the customer, providing easy identification and personalization options for communication.\nCreated At: Indicates the date and time when the customer was added to the database, which helps track when the customer first entered the system.\nAddress: Lists the physical address provided by the customer. This information can be crucial for compliance with licensing regulations that are region-specific.\nEmail: Displays the customer's email address, which is vital for digital communication, sending receipts, license keys, and support related emails.\nRating: Some systems may include a customer rating system based on their reliability, purchase frequency, or other criteria. This rating can help in prioritizing support and marketing efforts.\nBabel Licensing Customes Page\nFunctionalities and Buttons"},{"page":143,"heading":"","anchor":"","text":"Add: Allows administrators to manually add new customers into the system. This feature is particularly useful for adding customers outside of WooCommerce transactions or for preliminary setups before actual purchases.\nEdit: Each customer record can be edited by clicking the Edit button associated with a specific row. This functionality is essential for updating customer information, correcting errors, or adding additional details.\nDelete: This button enables the removal of customer records from the database. Care should be used with this feature as deleting a customer record could affect the tracking and management of licenses issued to them.\nSearch Box: Located at the top of the page, this tool allows users to quickly find customer records by typing relevant keywords such as names, email addresses, or locations.\nUsage Scenarios\nLicensee Creation: When a new order is placed via WooCommerce, a customer record is automatically created here, which then serves as the licensee for the new license. This ensures that all licenses are linked to a specific customer for better tracking and management.\nCustomer Management: Administrators can manage customer details, which is vital for maintaining accurate licensee information and enhancing customer service.\nData Integrity: Regular reviews and updates of customer information ensure that the database remains accurate and up-to-date, reflecting true customer demographics and details.\nBest Practices for Managing Customers"},{"page":143,"heading":"","anchor":"","text":"Regular Updates: Ensure that customer information is regularly updated, especially contact details, to maintain effective communication.\nData Privacy: Handle customer information with care, adhering to privacy laws and regulations to protect sensitive data.\nCustomer Engagement: Use the information stored in this database to engage with customers effectively, tailoring communications such as marketing emails and support services to meet their specific needs.\nIntegration Checks: Regularly verify that the WooCommerce integration is functioning correctly to ensure that new orders are seamlessly creating new customer entries in the database.\nThe Customers page is a critical tool for the administration of the Babel Licensing WordPress Plugin. It not only helps in managing individual customer details but also provides valuable insights into the customer base as a whole. Effective use of this page supports superior customer service and operational efficiency, underpinning successful license management activities."},{"page":143,"heading":"Customer Edit","anchor":"customer-edit","text":"The \"Edit Customer\" page in the Babel Licensing WordPress Plugin is a comprehensive interface designed for managing detailed customer information. This page allows administrators to update existing customer data or input new customer details, ensuring accurate records for communications, licensing management, and reporting.\nBabel Licensing Customer Edit Page\nFields and Options"},{"page":143,"heading":"Customer Edit","anchor":"customer-edit","text":"Rating: A numeric rating assigned to the customer, typically reflecting their importance, reliability, or value to the organization. This can range from a low to high scale (e.g., 1 to 5).\nReseller: A checkbox that, when ticked, indicates whether the customer is also a reseller. This is crucial for differentiating between direct customers and those who might resell your products or services.\nTitle: A field to enter a courtesy title or professional title for the customer (e.g., Dr., Mr., Ms.).\nFirst Name: The customer's first name.\nLast Name: The customer's last name.\nCompany: The name of the company that the customer represents, if applicable.\nEmail: The customer's email address, used for sending communications such as license information, newsletters, and support correspondences.\nCreation Date: The date when the customer profile was created in the system. This field may be automatically populated based on data entry and can often be locked from editing to preserve historical accuracy.\nNotes: An area to include any relevant notes about the customer, which might include special considerations, preferences, or historical details relevant to customer management.\nAddress Section\nAddress: The primary physical address for the customer.\nPostal Code: The postal code associated with the primary address.\nCity: The city of the customer's primary address.\nRegion: The state or region for the customer's address.\nCountry: The country where the customer is located.\nContacts Section"},{"page":143,"heading":"Customer Edit","anchor":"customer-edit","text":"This section allows the addition of multiple contact records for a customer, enabling the organization to maintain several points of contact, which can be useful for sending notifications or managing different aspects of the customer relationship.\nEach contact can be defined with a title, first name, last name, email, and a checkbox to select whether to send them email notifications regarding scheduled actions or important updates.\nAfter modifying any customer profile details, it's crucial to Save your changes. This step ensures the profile remains current and accurate within the system."},{"page":144,"heading":"","anchor":"","text":"The Babel Licensing Plugin Dashboard provides a comprehensive view of licensing activities and metrics within your WordPress environment. This dashboard is designed to give administrators quick insights into sales performance, license distribution, and token usage across different products and license types. Here’s a detailed breakdown of the various components of the dashboard:\nDashboard"},{"page":144,"heading":"Sales and License Distribution Chart","anchor":"sales-and-license-distribution-chart","text":"The dashboard integrates two dropdown menus, each designed for a unique role in adapting the data visualization. These menus enable users to flexibly change the data's scope and focus to meet particular requirements or explore specific interests.\nLicense Metrics Selection: Allows users to switch the displayed data among 'Licenses by Product', 'License Types', and 'Licenses Trends'.\nTime Frame Selection: Users can select the timeframe for the data, with options such as the last 7, 14, or 30 days.\nLicenses by Products\nProvides a pie chart detailing the distribution of licenses sold over the selected period, grouped by product type.\nThis chart displays a breakdown of licenses sold, grouped by product. Each segment of the pie represents a different product, with the number of licenses sold indicated next to each segment. The total sales value over the selected period is prominently displayed in the center of the pie chart.\nLicenses by Product\nLicense Types\nShows a pie chart of the various types of licenses sold, useful for understanding the mix of license models (e.g., single-user, multi-user, subscription) being purchased.\nLicense Types\nLicense Activity"},{"page":144,"heading":"Sales and License Distribution Chart","anchor":"sales-and-license-distribution-chart","text":"The map displayed represents the geographical tracing of license activities enabled by the Babel Licensing system. When license tracing is activated, the system captures and visualizes the location data associated with each license's activation, deactivation, and floating license transactions such as requests and releases. Each blue dot on the map indicates a specific event, providing a visual representation of where and how often licenses are being utilized globally.\nLicense Activity\nInfo: Users can interact with the map by clicking on any of the blue points. Doing so will redirect them to a dedicated licenses page, which displays detailed information about the licenses associated with the activity at that specific location. This feature allows users to quickly access and review the licensing details relevant to each geographical trace, facilitating efficient management and oversight of software licenses."},{"page":144,"heading":"Sales and License Distribution Chart","anchor":"sales-and-license-distribution-chart","text":"This geolocation tracking feature is particularly valuable for understanding the distribution and usage patterns of software licenses. It helps software providers gauge market penetration and detect any unauthorized use across different regions. By analyzing these patterns, companies can make informed decisions regarding market strategies, customer support, and product development. The map tool includes zoom and pan functionalities, allowing for a detailed and focused view of activity in specific areas, enhancing the ability to monitor license operations effectively and securely.\nLicense Trends\nOffers a bar chart comparing the monthly sales of licenses over the current and previous year, along with an average line that indicates the typical number of licenses sold each month. This is particularly helpful for spotting trends and planning for seasonal variations in sales.\nLicense Trends"},{"page":144,"heading":"License Tokens","anchor":"license-tokens","text":"This graphical representation that shows the distribution and status of license tokens. Easily identify how many tokens are in use, available, nearing expiration, or suitable for revocation, helping in quick visual assessment and management.\nLicense Tokens\nTotal License Tokens (Blue Bar): Represents the total number of license tokens currently allocated within the system.\nActive Tokens (Green Bar): Indicates the number of tokens actively allocated by all floating and activation licenses. These tokens are in use and contribute directly to current license operations. The number of active tokens is also displayed on a label at the far end of the active tokens bar.\nExpired/Revokable Tokens (Yellow Bar): Shows the number of tokens that are expired or associated with revoked licenses. These tokens are scheduled for deletion during normal system operations and do not impact the total number of allocatable tokens."},{"page":144,"heading":"License Summary Stats","anchor":"license-summary-stats","text":"License Stats\nTotal Licenses: Displays the total count of licenses managed within the system including Files, Activation and Floating licenses.\nRevoked Licenses: Indicates the number of licenses that have been revoked.\nActivation Licenses: Shows the number of activation licenses, which are typically tied to a specific device or installation.\nFloating Licenses: Represents the number of floating licenses, which can be used across multiple devices or installations but are limited to a certain number of concurrent uses."},{"page":144,"heading":"Guide to Usage and Interpretation","anchor":"guide-to-usage-and-interpretation","text":"This dashboard serves as an essential instrument for monitoring your licensing business's vitality and trends. By diligently reviewing these metrics, administrators are empowered to craft well-informed decisions regarding:\nPricing Strategies: Adjust prices based on current market demands and performance metrics.\nMarketing Efforts: Tailor marketing strategies that resonate with the detected trends and customer behaviors.\nProduct Development: Innovate or improve products in line with the evolving needs and desires of your market.\nKey Features:\nReal-Time Data & Trends: This dashboard offers immediate insights into the latest movements and patterns within your licensing business, enabling agile decision-making.\nExpired & Revokable Tokens Visibility: Keep track of licenses nearing expiration or those eligible for revocation. This feature aids in maximizing license utilization and maintaining compliance with licensing terms.\nBenefits:\nOptimized License Allocation: Ensure your licenses are allocated efficiently, avoiding underutilization or overcommitment.\nCompliance Assurance: Stay within the bounds of licensing agreements by keeping a vigilant eye on license statuses.\nBy integrating this dashboard into your daily operational review, you lay the groundwork for a data-driven approach to steering your licensing business towards sustained success."},{"page":145,"heading":"","anchor":"","text":"The Emails page of the Babel Licensing WordPress Plugin is designed to manage email templates used for communicating with customers during various events within the WordPress system. This page allows administrators to efficiently create, edit, and manage the templates that facilitate communication related to events such as new orders, license support expirations, trial terminations, and license expirations.\nGrid Columns\nId: Displays a unique identifier for each email template, facilitating easy reference and management.\nName: Shows the name of the email template, which typically indicates its purpose or the specific event it addresses (e.g., \"Trial License Expiration\").\nCreated At: Indicates the date and time when the email template was created, providing a timeline of template development.\nUpdated At: Displays the most recent date and time the template was updated, helping track changes and revisions.\nDescription: Provides a brief overview of the email template's function or the content it includes, assisting in quickly identifying the appropriate template for a given situation.\nBabel Licensing Emails Page\nActionable Buttons\nEach row associated with an email includes a set of actionable buttons that provide the following functionalities:"},{"page":145,"heading":"","anchor":"","text":"Edit (Pencil Icon): Each row includes an edit button, enabling the modification of existing email templates. This feature is crucial for updating the content or adjusting the template's triggers based on evolving communication needs.\nDelete (Trash Can Icon): This button permits the removal of an email template from the system. It should be used with caution, as deleting a template may impact ongoing processes that depend on automated email notifications.\nDownload (Download Icon): Allows for the downloading of the email template's content, useful for backup or for use outside the WordPress environment.\nFunctionalities\nAdd Email: To manually add a new license template, click the Add button located at the top of the page. This action opens a form where you can enter the template name, mode, and other pertinent details.\nSearch and Filter: A search bar along with filtering options is available to quickly locate specific email or narrow down the list based on criteria such as email name, mode or template type.\nSorting: Clicking on the column headers sorts the list by that column, allowing for an organized display according to Id, name, which facilitates easier management.\nUsage Scenarios and Best Practices"},{"page":145,"heading":"","anchor":"","text":"Automated Communications: Set up and maintain email templates for automated communications to ensure customers receive timely updates about their licenses and any related activities.\nTemplate Updates: Regularly review and update templates to align with current business practices, legal requirements, and branding guidelines.\nThe Emails page is a vital tool within the Babel Licensing WordPress Plugin, enabling administrators to oversee and handle the automated email communications sent to customers. By using this page effectively, businesses can ensure consistent and professional communication that enhances customer engagement and supports license management activities."},{"page":145,"heading":"Email Edit","anchor":"email-edit","text":"The Edit Email page serves as an essential tool for tailoring email templates sent to customers after specific actions, such as purchasing a new license or when a license is due to expire. This interface allows administrators to create customized emails that not only improve the overall customer experience but also streamline the process of managing licenses efficiently.\nBabel Licensing Email Edit Page\nThe rich text editor for the email message allows comprehensive formatting options including font size, style, and alignment, making it possible to design emails that align with corporate branding or specific communication standards.\nThe editor supports the insertion of dynamic content variables like {CustomerName}, {ProductName}, {UserKey}, and {ProductDownloadLink}. These placeholders are replaced with actual user and product information when the email is sent, personalizing the message based on the recipient's details and the specific transaction."},{"page":146,"heading":"","anchor":"","text":"Before you can take advantage of the WordPress integration, you'll need to\ninstall and configure the Babel Licensing WordPress Plugin."},{"page":146,"heading":"Installing Babel Licensing in WordPress","anchor":"installing-babel-licensing-in-wordpress","text":"Important: Important Reminder Before Making Changes to Your WordPress Site\n\nBefore modifying the WordPress configuration or updating plugins, back up both your database and website files, so you can restore your site if something goes wrong during the update.\nTo install Babel Licensing into your WordPress site by uploading the plugin file:\nLog in\nLog in to your WordPress admin dashboard.\nGo to Add New Plugin\nNavigate to Plugins, then press Add New Plugin button.\nOpen the upload form\nClick on the Upload Plugin button at the top of the page.\nChoose the plugin file\nChoose the babe_licensing.zip file from your computer.\nInstall\nClick on Install Now.\nActivate the plugin\nAfter the installation is complete, click on Activate Plugin.\nBabel Licensing is now installed and ready for use.\nBabel Licensing WordPress Plugin"},{"page":146,"heading":"Updating Babel Licensing Plugin","anchor":"updating-babel-licensing-plugin-","text":"To update the plugin on your WordPress site:\nDownload the latest version\nDownload the latest version of the plugin, babel-licensing.zip, from the official source.\nGo to Upload Plugin\nNavigate to Plugins > Add New > Upload Plugin.\nChoose the plugin file\nChoose the babel-licensing.zip file from your computer.\nReplace the current version\nWhen asked to confirm the replacement of the current version, click Replace current with uploaded.\nActivate the plugin\nAfter the upload is complete, click on Activate Plugin.\nYour Babel Licensing plugin is now updated and ready for use."},{"page":146,"heading":"Uninstall Babel Licensing Plugin","anchor":"uninstall-babel-licensing-plugin","text":"WordPress lets you either deactivate or delete a plugin, and the two actions are quite different:\nDeactivating a Plugin\nTemporary Disabling: Deactivating a plugin temporarily disables its functionality but does not remove its settings or data. This is useful if you're troubleshooting or need to turn off a plugin temporarily without losing its configuration.\nData Retention: All settings, files, and data related to the plugin remain intact on your server. You can reactivate the plugin at any time to restore its functionality exactly as it was.\nDeleting a Plugin\nPermanent Removal: Deleting a plugin completely removes it and its files from your WordPress site. This action is typically irreversible through the WordPress dashboard.\nData and Settings Removal: Along with the plugin files, deleting a plugin often removes all its settings and data from your website’s database. This cleans your site from the plugin’s footprint but means you cannot recover the plugin settings if you reinstall it.\nNote: Always ensure you have backups of your WordPress site before deleting any plugins, especially those critical to your site's functionality or data management."},{"page":146,"heading":"Deactivate Babel Licensing Plugin","anchor":"deactivate-babel-licensing-plugin","text":"To deactivate the Babel Licensing plugin without deleting it from your WordPress site:\nGo to Installed Plugins\nGo to Plugins > Installed Plugins.\nLocate the plugin\nLocate Babel Licensing in the list.\nDeactivate it\nClick Deactivate beneath the plugin name."},{"page":146,"heading":"Delete Babel Licensing Plugin","anchor":"delete-babel-licensing-plugin","text":"Before deleting the plugin, back up your WordPress database.\nError: Deleting the plugin will remove all tables and data created by Babel Licensing, which may not be recoverable.\nTo delete the plugin after backing up:\nDeactivate the plugin\nEnsure the plugin is deactivated by following the steps in the previous section.\nGo to Installed Plugins\nGo to Plugins > Installed Plugins.\nLocate the plugin\nLocate Babel Licensing.\nDelete it\nClick Delete beneath the plugin name.\nConfirm the deletion\nConfirm the deletion when prompted."},{"page":147,"heading":"","anchor":"","text":"The Licenses page of the Babel Licensing WordPress Plugin provides a detailed interface for managing all software licenses stored in the Babel Licensing Database. This page displays a grid of licenses, each with detailed information and actionable options to efficiently manage licensing activities.\nGrid Columns\nPost ID: The WordPress post number associated with the license.\nLicense ID: Displays the unique identifier for each license.\nOrder: Shows the associated WooCommerce order ID.\nLicensee: Indicates the customer or company name that owns the license.\nCreated At: The original date when the license was created.\nIssue Date: The date the license was issued to the customer.\nEnd Date: The date when the license or support expires.\nMode: Specifies the type of license (Activation, Floating, or File).\nType: Displays the type of license as defined in the License Template.\nFormat: The license data can be in several formats: XML, XML DSig, ASCII, BASE32.\nBabel Licensing Licenses Page\nActionable Buttons\nEach license entry in the grid is accompanied by a set of actionable buttons, detailed as follows:"},{"page":147,"heading":"","anchor":"","text":"Edit (Pencil Icon): Clicking this icon allows you to modify the details of the license. This is useful for extending expiration dates, changing licensee information, or adjusting the license type.\nDelete (Trash Can Icon): This button enables you to permanently remove a license from the database. Use this function with caution as it cannot be undone and might affect the licensee’s access if the license is active.\nDownload (Arrow Down Icon): Available for licenses with the 'File' mode, this icon allows you to download the actual license file. This is typically used when licenses are provided as downloadable files rather than keys.\nShare (Share Icon): This icon is used for licenses categorized under 'Floating' or 'Activation' modes. Clicking this icon navigates to the License Tokens page where you can manage tokens associated with the license. This feature is particularly important for floating licenses, as it allows you to control and distribute access among multiple users.\nRevoke (Lock Icon): This button allows administrators to revoke a license, which effectively disables the license from being used further. When a license is revoked, the lock icon appears closed, signifying that the license is no longer active. If the lock is open, it indicates that the license is currently active and has not been revoked."},{"page":147,"heading":"","anchor":"","text":"License Tracing (Pin Icon): This feature enables administrators to track the usage of a specific license. When the pin icon is filled in color, it indicates that license tracing is enabled for that particular license, allowing for monitoring of how the license is being utilized. If the pin is not filled, tracing is disabled, and no usage data is being collected for that license.\nSend Email (Email Icon): Clicking this icon initiates an email to the customer associated with the license. This function is typically used to send updates or notifications regarding the license status, such as renewal reminders, confirmation of actions taken (like revocation), or providing support and assistance related to the licensed product.\nFunctionalities\nAdd License: The \"Add\" button at the top of the page allows you to manually enter a new license into the system, providing fields to specify order number, licensee details, license type, and expiration.\nSearch and Filter: A search bar along with filtering options is available to quickly locate specific licenses or narrow down the list based on criteria such as licensee name, order ID, or license type.\nSorting: Clicking on the column headers sorts the list by that column, allowing for an organized display according to order ID, licensee, or end date, which facilitates easier management."},{"page":147,"heading":"","anchor":"","text":"This page is designed to give administrators full control over the licensing process, providing essential tools to ensure compliance and customer satisfaction. Regular use of this page is recommended to monitor and adjust licensing arrangements as needed to suit business requirements and customer needs."},{"page":147,"heading":"License Edit","anchor":"license-edit","text":"The \"Edit License\" page of the Babel Licensing WordPress Plugin provides a detailed interface for modifying the parameters of an existing license. This functionality is crucial for administrators who need to update license details as circumstances change, such as extending a license's validity, altering the licensee information, or adding restrictions.\nBabel Licensing License Edit Page\nBelow is an explanation of each field and section within the Edit License page.\nSelection\nOrder: Displays the order number and associated details from WooCommerce, linking the license to a specific purchase. Clicking the drop-down arrow reveals additional order details and allows for switching the license to a different order if necessary.\nLicense Template: Indicates the template used for the license, which defines the predefined settings and parameters. The drop-down menu allows you to change the template if different licensing terms need to be applied.\nProperties"},{"page":147,"heading":"License Edit","anchor":"license-edit","text":"License Id: The unique identifier for the license. This field is typically auto-generated and can be edited if necessary.\nLicense Type: Specifies the type of license (e.g., Single, Enterprise, etc.). The selection can be changed according to the licensing arrangement needed.\nMode: This parameter specifies the deployment method of the license to the end user, with options including Activation, Floating, and File. Each mode dictates a different approach for how the license is accessed and utilized.\nUser Key: A distinctive identifier linked to either a user or system that utilizes the license. It is generally associated with either Activation or Floating licenses and allows the end customer to access and use the licensed software.\nAllowed Sites: Specifies the number of sites where the license can be actively used.\nIssue Date: The date when the license was initially issued. This can be adjusted if there is a change in the start date of the license.\nExpire Date: The date on which the license will expire. This field is crucial for subscription-based services and can be extended as required.\nSupport Expire Date: Indicates the date until which support is available for the product under license.\nFormat: Defines the format of the license key, such as XML, Base 32 or ASCII.\nTrace: A toggle to enable or disable tracing the license's usage, providing insights into how the licensed software is utilized."},{"page":147,"heading":"License Edit","anchor":"license-edit","text":"Revoked Toggle: This feature enables the deactivation or reactivation of a license. When toggled, it restricts or grants access to the content associated with the license. Applicable solely to Activation or Floating licenses.\nDescription: A field for adding any descriptive notes about the license, which can include special conditions or instructions.\nLicensee\nCustomer: Shows the customer's name and a link to their profile. This can be changed if the license is transferred to a new user.\nName, Company, Email: These fields detail the licensee's contact information and can be edited to update records or correct details.\nRestrictions\nAdd Restriction: This dropdown allows to add specific restrictions to a license. Restrictions can define limitations or permissions, such as hardware constraints, specific trial terms, or other conditional use cases.\nAfter making the necessary adjustments, click the \"Save\" button to apply the changes to the license. It is important to verify all changes before saving to ensure that the license parameters correctly reflect the intended use and restrictions.\nThis page serves as a comprehensive tool for managing the lifecycle and compliance of licenses issued through the Babel Licensing WordPress Plugin."},{"page":148,"heading":"","anchor":"","text":"The Log page within the Babel Licensing WordPress Plugin serves as a crucial tool for monitoring and diagnosing interactions with the Babel Licensing Service. This page provides a detailed log of all incoming web requests, system actions, and internal operations, enabling administrators to effectively track and analyze the behavior and performance of the licensing system.\nGrid Columns\nId: Displays a unique identifier for each log entry, facilitating quick reference and issue tracking.\nTime Stamp: Shows the exact date and time when the log entry was recorded, critical for understanding the sequence of events and for troubleshooting purposes.\nLevel: Indicates the severity or level of the log entry (e.g., Information, Warning, Error), helping administrators prioritize issues based on urgency.\nMessage: Provides a detailed description of the event, including actions taken by the system or incoming requests, which is essential for debugging and verifying system operations.\nBabel Licensing Service Log\nFunctionality and Buttons"},{"page":148,"heading":"","anchor":"","text":"From/To Date Filter: Allows administrators to filter log entries within a specific timeframe by setting a start (From) and end (To) date and time, and then clicking the \"Apply\" button to refresh the log entries accordingly.\nDelete: This button enables the removal of selected log entries. It can be used to clear old or irrelevant data, keeping the log concise and focused on relevant entries.\nSearch: A search bar is provided to quickly find specific log entries by keywords, which is useful for isolating incidents or reviewing actions related to particular events or issues.\nAnalyzing Log Entries\nThe Log page is designed to allow in-depth analysis of each entry:\nExpanding Log Entries: By clicking on a log entry, administrators can expand it to view detailed context information and the complete trace of web requests. This expanded view includes protocol details, method, content type, and other pertinent data that can help diagnose issues or confirm operational integrity.\nContext Information: Provides JSON formatted details about the web request, including headers, request URL, IP address, and other metadata that can be vital for advanced troubleshooting and security auditing.\nUsage Scenarios"},{"page":148,"heading":"","anchor":"","text":"Monitoring: Regular review of the log helps in monitoring the health and functionality of the licensing system, ensuring that all processes are running as expected.\nTroubleshooting: In case of errors or unexpected behavior, the log provides indispensable insights that can aid in quick resolution.\nSecurity Audits: By analyzing log entries, particularly those marked with higher severity levels, administrators can identify and respond to potential security threats or breaches.\nBest Practices\nRegular Review: Administrators should regularly review the logs to ensure early detection of anomalies or issues.\nMaintain Clean Logs: Periodically deleting non-essential log entries can help maintain the performance and usability of the log page.\nUtilize Filters and Search: Leveraging the search and filter functionalities helps in managing large volumes of log data effectively.\nIn conclusion, the Log page of the Babel Licensing WordPress Plugin is an essential component for maintaining operational transparency and security, providing detailed insights into every aspect of the licensing system's interactions and internal processes."},{"page":149,"heading":"","anchor":"","text":"When a customer navigates to My Account > Licenses, they will see a list of all purchased licensed products along with relevant details.\nMy Account Page\nThe page is structured into two main sections:\nLicense Key – A unique alphanumeric key representing the product license.\nPurchase Date – The date when the customer acquired the license.\nLicense Status – Displays the current status of the license. If active, it will be marked in green as “Active.”\nExpiration Date – Shows the date until which technical support is available for the license or if any expiration date.\nNumber of Activations (Sites) – Indicates how many times the license has been activated compared to the maximum allowed activations (e.g., “1/1” means one activation is in use, and no additional activations are allowed).\nActivations Management\nBelow the licensed product details, the Activations section lists all devices or clients that have been activated using the license key. This section includes:\nClient Name – The device or system name where the license is currently activated (e.g., “Mac”).\nClient Activation Key – A unique system-generated key tied to the machine where the license has been activated.\nActivation Date – The date when the license was activated on the corresponding client.\nActions (Deactivate Button) – Users can deactivate a license from a specific client by clicking the Deactivate button. This is useful if they need to transfer the license to another device or free up activation slots."},{"page":149,"heading":"","anchor":"","text":"The My Account – Licenses page offers a user-friendly and efficient way to manage purchased licenses, ensuring customers can track, activate, and control their software access seamlessly."},{"page":150,"heading":"","anchor":"","text":"Installing the Babel Licensing WordPress plugin introduces a new custom post type: Licensed Product. It is what connects WordPress to Babel Licensing.\nCreate or assign a licensed product\nWithin WordPress, you can either create a new Licensed Product or assign an existing one. This product will be what you aim to sell in your online shop.\nSelect the product type\nWhen you select \"Licensed Product\" from the Product data combobox, the Babel Licensing tab will become accessible.\nLink the product to Babel Licensing\nTo link a WordPress product with its corresponding entry in the Babel Licensing database, navigate to the Babel Licensing tab. There, locate and select the appropriate product from the dropdown menu labeled \"Babel product.\n\nWordPress Product Edit\nSave\nClick the Update button located within the Publish section to apply your modifications."},{"page":150,"heading":"Licensing Product","anchor":"licensing-product","text":"After linking the Licensed Product to the Babel Product, you gain the ability to directly edit the product from the Licensing > Product menu. Navigate to this page to view a grid of all products stored in the Babel Licensing database. Products that are successfully linked to a WordPress product will have an active 'Edit' button. Conversely, products that are not linked will have the 'Edit' button disabled.\nBabel Licensing Products\nOnce these steps are done, the Babel Licensing product is integrated with your WordPress site and its licenses can be sold through your shop."},{"page":150,"heading":"Product Edit","anchor":"product-edit","text":"To edit a Babel Licensing Product, click the edit icon in the grid. This action opens the Edit Product page. Here, you can:\nAssign an existing license template to the product.\nSign keys for the edited product.\nBind schedule actions to emails, enabling automatic notifications to end customers based on specific events (see: Emails).\nBabel Licensing Product Edit"},{"page":150,"heading":"Bind Email To Actions","anchor":"bind-email-to-actions","text":"You can set up automated email notifications in your system by binding schedule actions to an email template. This means when a specific event occurs, the system automatically compiles and dispatches an email to either the licensee or the customer. This automation ensures timely communication without manual intervention. To learn more about creating email templates, please refer to the Email section.\nTo link an action to an existing email template, click the plus (+) button located above the Actions, then:\nSelect the action\nIn the Action dropdown, select the event you wish to associate with an email.\nSelect the email template\nFrom the Email dropdown, choose your desired email template.\nEnable it\nMark the Enabled checkbox to activate sending.\nSave\nClick the save icon next to the corresponding input row to save your changes.\nActions\nDifferent actions can be connected to specific templates to make notification and response handling more efficient. Use these actions to improve communication and workflow."},{"page":150,"heading":"Bind Email To Actions","anchor":"bind-email-to-actions","text":"License Issued: This action sends a new product license to the customer after purchase.\nLicense Expiring: Reminder sent before the expiration of an existing license.\nLicense Expired: Notification sent when a user's license has expired.\nLicense Revoked: Alert for when a license is terminated by the provider.\nSupport Expiring: Reminder for upcoming expiration of support services.\nSupport Expired: Notification sent when support services have ended.\nTrial Started: Notification sent when a user begins a trial period of a service or product.\nTrial Terminated: Notification for the end of a trial period before conversion to a paid plan.\nEach of these actions is designed to ensure users and administrators are fully informed throughout the lifecycle of service usage and licensing."},{"page":150,"heading":"Product Attributes","anchor":"product-attributes","text":"Within the product data, the Attributes tab allows for further customization of the Licensed Product. Here, you can define attributes for use in email templates. To ensure an attribute does not appear on the product page, uncheck the \"Visible on the product page\" checkbox.\nProduct Attributes"},{"page":151,"heading":"","anchor":"","text":"The Templates page serves as a centralized hub for managing License Templates. These templates define the structure and terms for the licenses that can be issued, ensuring consistency and compliance across all licensing operations. This page allows administrators to efficiently create, modify, and delete templates according to business needs.\nNote: For more detailed information on the conceptual framework and technical implementation of License Templates, including their role in the licensing architecture, please refer to the \"License Templates\" chapter of this manual.\nGrid Columns\nThe grid on the Templates page displays a list of all existing license templates, along with several key details organized into columns:"},{"page":151,"heading":"","anchor":"","text":"Id: Displays a unique identifier for each template, aiding in quick reference and management.\nName: Shows the name of the template, which describes the type or purpose of the licenses it generates.\nType: Specifies the license type that the template will generate, such as Single User, Multi-User, Subscription, etc.\nMode: Indicates the operational mode of the license, such as 'Activation', 'Floating', or 'File', detailing how the license will be used or applied.\nIssue Date: Allows administrators to decide whether to include an issue date in the licenses generated from this template, which can be important for tracking and validity purposes.\nExpire Days: Displays the number of days after which the license will expire, starting from the date of issue.\nSupport Expire Days: Indicates the number of days after which the provided support for the product under the license will expire.\nFormat: Specifies the format of the license key generated by the template, such as ASCII, Base 32, XML. This setting determines how the license keys are structured and encoded.\nUser Key: Represents the blueprint used to generate a unique user key for licenses created with this template, critical for ensuring each license is distinct and verifiable.\nStatus: Shows whether the template is active or inactive, allowing administrators to control which templates are available for use. This helps manage the availability of different types of licenses without deleting historical or infrequently used templates."},{"page":151,"heading":"","anchor":"","text":"Description: Provides additional details about the template, explaining its use case, restrictions, or special conditions that apply to the licenses it generates. This is useful for administrators and sales teams to understand the applications and limitations of a specific license type.\nLicense Templates\nActionable Buttons\nEach row associated with a license template includes a set of actionable buttons that provide the following functionalities:\nEdit (Pencil Icon): Clicking this icon allows you to modify the existing template details. This function is crucial for updating template terms, adjusting license types, or revising the template name and other characteristics as licensing policies change.\nDelete (Trash Can Icon): This button enables you to permanently remove a template from the system. This action should be used with caution as deleting a template may affect the issuance of new licenses based on this template and could impact existing licenses if they rely on template definitions for enforcement of terms.\nFunctionalities"},{"page":151,"heading":"","anchor":"","text":"Add Template: To manually add a new license template, click the Add button located at the top of the page. This action opens a form where you can enter the template name, mode, and other pertinent details.\nSearch and Filter: A search bar along with filtering options is available to quickly locate specific templates or narrow down the list based on criteria such as template name, mode or template type.\nSorting: Clicking on the column headers sorts the list by that column, allowing for an organized display according to Id, name, or mode, which facilitates easier management."},{"page":151,"heading":"Template Edit","anchor":"template-edit","text":"The \"Edit Template\" page within the Babel Licensing WordPress Plugin allows administrators to create or modify the parameters of a license template. These templates dictate the terms under which licenses are issued, including their type, duration, and specific license restrictions. This page provides a user-friendly interface to precisely define these parameters or to upload an existing template file.\nLicense Template Edit\nBelow is an explanation of each field and section within the Edit Template page.\nProperties"},{"page":151,"heading":"Template Edit","anchor":"template-edit","text":"Select Template or Drop a File Here: Administrators can select an existing template file or drag and drop the file directly into the interface. Use it to import templates created outside the plugin, such as in Babel Desktop or the web application.\nTemplate Name: Specifies the name of the template, typically reflecting the license type or the product it is associated with, such as \"ACME Data Enterprise XML Template.\"\nLicense Type: Defines the category of the license (e.g., Enterprise, Individual) that will be issued using this template.\nMode: Describes the method of license utilization, including File for licenses available as downloadable files, Activation or Floating for licenses that necessitate connection to the Babel Licensing Service.\nUser Key: Describes the format or algorithm used to generate a unique key for each license, such as \"PAPP3-{TOKEN-5}-{HEX-5}\".\nIssue Date: A checkbox that, when selected, enables the template to automatically include an issue date for each license generated.\nExpire Days: Allows setting the number of days after which the license will expire from the date of issue.\nSupport Days: Specifies the duration in days for which support is available for the product under this license.\nDescription: Provides space to include any additional information about the template, such as usage guidelines or restrictions that aren't explicitly defined in other fields.\nTemplate"},{"page":151,"heading":"Template Edit","anchor":"template-edit","text":"Product: Links the template to a specific product, such as \"#1 ACME Data,\" ensuring licenses generated are applicable for the intended product.\nSign Keys: Allows the selection of cryptographic keys used for signing the license files, ensuring authenticity and integrity.\nLicense File Name: Defines the default filename for licenses generated from this template, such as \"acme.licenses\".\nFormat: Specifies the format of the license file, such as XML, ASCII, BASE32 which determines how license information is structured and stored.\nRestrictions\nAdd Restriction: This function allows administrators to apply specific conditions or limitations to the use of the license, such as hardware restrictions, trial terms, or other conditional use cases. Restrictions ensure compliance with licensing agreements and can be tailored to meet various business needs.\nAfter making the necessary adjustments, clicking the \"Save\" button will apply the changes to the template. It's important to review all settings to ensure they meet the intended licensing requirements before saving."},{"page":152,"heading":"","anchor":"","text":"The Babel Licensing Data Center edition unlocks an administrative web interface for managing the Babel Licensing Service.\nThe web application is part of the single Babel Licensing Service package. It is unlocked by a Data Center license; with a Server license, opening the service address in a browser shows an upgrade page, and licenses can be managed with Babel Desktop. To upgrade from Server to Data Center, replace the service license file (babel.licenses) and restart the service; there is nothing to reinstall.\nBabel Web Dashboard"},{"page":152,"heading":"Software Application Overview","anchor":"software-application-overview","text":"The web application covers all licensing operations, with role-based access control and live data views.\nDashboard\nThe Dashboard provides at-a-glance insights through customizable widgets. Monitor global license distribution on an interactive map, view sales metrics by product with pie charts, analyze license type distribution, check server status, and manage license tokens. The date range selector limits the data to a chosen period, so you can compare trends over time. Read more\nAPI Keys\nCreate and manage API credentials that allow external applications to securely communicate with your Babel Licensing Service. Control integration permissions, revoke compromised keys, and monitor API usage through this section. Read more\nLicenses\nThe core module of the application where you can view, create, edit, and manage all software licenses. The intuitive grid layout displays key license information including status, type, expiration, and customer details. Perform actions such as revoking licenses, enabling license tracing, generating license files, and managing license tokens directly from this interface. Read more\nTemplates\nStreamline license creation by defining reusable license templates with pre-configured parameters. Set common license terms, features, restrictions, and formats once, then apply them when issuing new licenses. Read more\nProducts"},{"page":152,"heading":"Software Application Overview","anchor":"software-application-overview","text":"Register and organize your software products with detailed information, version tracking, and associated license templates. Upload product images, configure signing keys, and analyze sales performance to effectively manage your product portfolio. Read more\nCustomers\nMaintain comprehensive customer records including contact information, purchase history, and license assignments. The customer management interface helps you track relationships, provide appropriate support, and identify opportunities for renewals or upgrades.\nOrders\nTrack all license purchases and assignments through an organized order management system. View transaction details, process new orders, and generate financial reports to maintain accurate records of license sales and distribution. Read more\nReports (Exception Reports)\nAccess and analyze application exception reports submitted from licensed software. This diagnostic tool helps identify issues in your software by presenting detailed information about crashes and errors experienced by end users. Read more\nResources\nAccess and manage various assets used throughout the Babel Licensing Service including digital signature keys, encryption certificates, email templates and documentation files. Store HTML email templates for customer notifications, manage the signature keys used for license validation, and keep other files the service needs in one place. Read more\nUsers"},{"page":152,"heading":"Software Application Overview","anchor":"software-application-overview","text":"Manage administrative access to the web application by creating user accounts with appropriate role-based permissions. Roles control who can reach sensitive licensing functions and information.\nWebhooks\nConfigure automatic notifications to external systems when specific licensing events occur. Use webhooks to keep your CRM, support system or other business applications in sync with the licensing service. Read more\nLog\nReview detailed activity logs that record all actions performed within the application. Search, filter, and export logs for troubleshooting, security auditing, or compliance purposes. Read more"},{"page":153,"heading":"","anchor":"","text":"The Babel Licensing Service provides an API key management system that allows users to securely generate, manage, and control API keys for accessing the Babel Licensing Service Web API Interface. API keys serve as authentication tokens that grant applications and services controlled access to licensing resources."},{"page":153,"heading":"Listing API Keys","anchor":"listing-api-keys","text":"To begin, navigate to the API Keys section by clicking on the corresponding icon in the left-hand navigation bar. This sidebar provides access to various administrative features, including API Keys.\nThe API Keys section provides an overview of all existing API keys, displaying key details such as:\nAPI Key Name – A user-friendly identifier for the key.\nKey – The generated key used for API authentication.\nCreation Date – When the key was generated.\nExpiration Date – When the key will automatically expire.\nOwner User – The user associated with the API key.\nRevoked Status – Indicates whether the key has been disabled.\nPermissions – Defines the access level (Read, Write, Delete, Create).\nAPI Key Listing"},{"page":153,"heading":"Creating and Editing API Keys","anchor":"creating-and-editing-api-keys","text":"Editing an API key updates its details, permissions, and security settings.\nOpen the key for editing\nLocate the API key in the grid and click the pencil (edit) icon on the corresponding row. This opens the Edit API Key page, where the selected key's information is displayed and ready for modification.\n\nEdit API Key\nUpdate the key's details\nThe Edit API Key page allows you to update the following information:\nOwner – Change the user who owns the API key.\nAPI Key Name – Update the name for easier identification.\nKey – View the generated API key (cannot be manually edited, but can be regenerated).\nClient Secret – Optionally set or update the client secret for additional security.\nCreated Date – Displays when the key was originally generated.\nExpiration Date – Set a new expiration date or extend the key's validity.\nRevocation Toggle – Enable or disable the key's access by toggling its revoked status.\nPermissions – Adjust the key's access level by selecting or removing the following rights:\nRead – Allows retrieval of data.\nWrite – Grants permission to modify data.\nDelete – Enables removal of data.\nCreate – Allows creating new resources.\nDescription – Add a note or explanation for future reference.\nSave or cancel\nClick the SAVE button to update the API key, or click CANCEL to discard the modifications."},{"page":154,"heading":"","anchor":"","text":"The Babel Licensing Dashboard provides a comprehensive and customizable interface for managing licensing operations efficiently. Designed with flexibility in mind, the dashboard allows users to add, organize, and configure widgets to monitor key metrics, track licensing data, and manage product lifecycles with ease.\nKey Features\nCustomizable Widgets – Users can add and arrange widgets to tailor the dashboard to their specific needs.\nReal-Time Analytics – Gain insights into sales, product licenses, and usage statistics through dynamic visualizations.\nInteractive Data Representation – View licensing data through maps, charts, and reports for better decision-making.\nCentralized License Management – Oversee activation, revocation, and floating license distribution from one interface.\nServer & Log Monitoring – Keep track of system logs, warnings, and errors to maintain optimal performance."},{"page":154,"heading":"Widgets","anchor":"widgets","text":"Widgets are modular components that provide insights into various aspects of licensing, product management, and system monitoring.\nLicense Map\nThe Licenses Map is an interactive widget within the Babel Licensing Dashboard that provides a geographical overview of license distribution and usage. It allows administrators to visually track where licenses are being used across different regions, helping to monitor global deployments efficiently.\nLicense activity map — fictional demonstration data\nLicense activity map — fictional demonstration data\nKey Features\nInteractive Navigation – Users can zoom in and out, as well as pan across the map to explore different regions.\nLicense Usage Details – Clicking on a license marker (balloon) reveals key information, including:\nLicense ID\nUser or Company Name\nIP Address\nLocation (City, Country)\nLicense Status & Type\nReal-Time Updates – The map dynamically reflects changes, ensuring accurate and up-to-date license tracking.\nProduct Licenses\nThe Product Licenses widget in the provides a detailed visual representation of license distribution and sales performance across different products. It helps administrators track product adoption, revenue generation, and licensing trends at a glance.\nProduct Licenses Widget\nKey Features"},{"page":154,"heading":"Widgets","anchor":"widgets","text":"Interactive Sales Chart – A dynamic, color-coded donut chart displaying sales performance by product category.\nMonetary Overview – Displays total revenue generated from licensed products.\nProduct-Specific Breakdown – Each product is represented with a unique color and segment in the chart, making it easy to compare sales.\nDynamic Interactivity – Users can hide/show specific products and values by clicking on legend items.\nLicense Types\nThe License Types widget in the Babel Licensing Dashboard provides a comprehensive breakdown of different license categories in a visually intuitive format. This widget helps administrators track the distribution of licenses across various types, offering insights into how licenses are allocated and utilized.\nLicense Types Widget\nKey Features\nDonut Chart Visualization – Displays the total number of licenses and their distribution across different categories.\nColor-Coded License Segments – Each license type is represented with a distinct color for easy identification.\nDynamic Interactivity – Users can hide/show specific license types and values by clicking on legend items.\nQuick Overview of Licensing Trends – Helps identify the most used and least used license categories.\nServer"},{"page":154,"heading":"Widgets","anchor":"widgets","text":"The Server widget in the Babel Licensing Dashboard provides critical real-time system information and log analysis, ensuring smooth operation and proactive monitoring of the Babel Licensing Service. It allows administrators to track server performance, licensing details, and log activity for troubleshooting and maintenance.\nServer Widget\nKey Features\nServer Version & Licensing Information – Displays the installed version of Babel.Licensing.Service and licensing details, including the licensed entity and token availability.\nServer Time Synchronization – Shows the current server timestamp, ensuring time-based operations such as license activation, expiration, and logging function correctly.\nLog Monitoring & Categorization – Provides an overview of system logs, categorized into:\nError (Red) – Critical issues that require immediate attention (e.g., failed license validations, system crashes).\nWarning (Orange) – Non-critical alerts that may indicate potential issues (e.g., network latency, high resource usage).\nInfo (Green) – General system information and status updates (e.g., successful operations, user activities).\nDebug (Blue) – Low-level system debugging logs for in-depth analysis (currently none recorded).\nTokens\nDate Range Controller\nAt the top of the Babel Licensing Dashboard, the Date Range Control allows users to define the time period for which data is displayed across all widgets.\nDate Range Controller"},{"page":154,"heading":"Widgets","anchor":"widgets","text":"This feature ensures that users can analyze historical trends, monitor current performance, and generate custom reports based on specific timeframes."},{"page":154,"heading":"If the map is empty","anchor":"if-the-map-is-empty","text":"The map displays license activity traces with geographic coordinates within the selected date range. Customer postal addresses do not create markers. Check that activity was recorded, that its geolocation contains latitude and longitude, and that Start Date and End Date include the event timestamps. Localhost activity may have no geolocation. Refresh the page after adding activity or changing its location data."},{"page":155,"heading":"","anchor":"","text":"The Licenses page in the Babel Licensing Web Application is where you manage and monitor all software licenses in your system. This page displays licensing information in a tabular format, with each row representing a unique license entry. The interface allows you to view license details, track license activities, and perform various license management operations.\nList Licenses"},{"page":155,"heading":"Main Features","anchor":"main-features","text":"The main section of the page displays a grid of licenses with the following columns:\nLicense Id: A unique identifier for each license (e.g., lic929CEF...)\nLicensee: The name of the organization or individual who holds the license (e.g., Lumenbyte)\nIssue Date: The date when the license was issued (format: YYYY-MM-DD)\nType: Indicates the deployment environment (Server, Cloud, Enterprise, Corporate)\nMode: Shows the license type (Activation, Floating, File)\nSites: The number of allowed installations or activations (e.g., 50, 1)\nUser Key: A unique key associated with the license (for Activation and Floating licenses)\nRevoked: Indicates whether the license has been revoked or is still active (shown with a lock icon)\nFormat: The format of the license (not shown in current view, but available in the filter panel)\nExpire Date: The date when the license expires (not visible in the current view)\nSupport Expire Date: The date when technical support for the license expires\nEnd Date: The final date when the license becomes invalid\nCreated At: The timestamp when the license was initially created in the system\nUpdated At: The timestamp when the license was last modified\nCustomer: The customer account associated with the license\nOrder: The purchase order reference linked to this license\nTemplate: The license template used to generate this license"},{"page":155,"heading":"Action Buttons","anchor":"action-buttons","text":"Each license entry has several action buttons that allow you to:\nEdit (pencil icon): Modify license details\nDelete (trash can icon): Remove the license\nDownload (download icon): Download the license file (for File type licenses)\nView Details (double arrow icon): Expand to see additional license information\nRevocation Toggle (lock icon): Revoke or activate a license\nTracing (pin icon): Enable or disable activity tracking for a license"},{"page":155,"heading":"License Details and Activity","anchor":"license-details-and-activity","text":"When you select a license, the system displays two tabs:\nLICENSE: Shows detailed information about the selected license\nACTIVITY: Displays a map and details about license usage, including:\nGeographic location (Latitude/Longitude)\nIP address\nClient name\nMachine ID\nPhysical address\nDate and time of activities\nNumber of activities"},{"page":155,"heading":"Viewing Licenses","anchor":"viewing-licenses","text":"All licenses are displayed in the main grid by default\nUse the search fields at the top of each column to filter licenses by that specific criterion\nUse the more comprehensive filter panel on the right for advanced filtering\nClick on column headers to sort the list by that column\nUse the refresh button (circular arrow) to update the license list"},{"page":155,"heading":"Create a License","anchor":"create-a-license","text":"Open the new license form\nClick the \"+ ADD\" button at the top of the grid.\nFill in the license information\nFill in the required license information in the form that appears.\nSave the license\nSave the new license."},{"page":155,"heading":"Managing Licenses","anchor":"managing-licenses","text":"Editing a license:\nClick the edit (pencil) icon on the license row you want to modify\nUpdate the license details in the form that appears\nSave your changes\nDeleting a license:\nClick the delete (trash can) icon on the license row\nConfirm the deletion when prompted\nViewing license details:\nClick on a license row to see its detailed information in the bottom panel\nThe LICENSE tab shows the license properties\nThe ACTIVITY tab shows usage information and geographic data\nDownloading a license file:\nFor File type licenses, click the download icon to obtain the license file\nRevoking a license:\nClick the lock icon to toggle the revocation status of a license\nA closed lock indicates a revoked license that cannot be used\nAn open lock indicates an active license\nTracking license activity:\nClick the pin icon to enable or disable activity tracking for a license"},{"page":155,"heading":"Monitoring License Activity","anchor":"monitoring-license-activity","text":"Viewing activity data:\nSelect a license and navigate to the ACTIVITY tab\nView the map showing the geographic locations where the license has been used\nReview the detailed activity log showing:\nIP address of the client\nMachine ID of the device using the license\nClient name identifier\nPhysical location (city, country)\nPrecise latitude and longitude coordinates\nManaging activity records:\nUse the refresh button (circular arrow) in the activity panel to update the data\nUse the trash icon to delete activity records\nNavigate between activity records using the arrow buttons"},{"page":155,"heading":"Search and Filter Capabilities","anchor":"search-and-filter-capabilities","text":"The Licenses page offers powerful search and filtering options:\nQuick column filters: Each column has a search field that filters the list based on that column's values\nDate filters: Date columns have calendar pickers to select date ranges\nDropdown filters: Columns like Mode and Type have dropdown selectors for their values\nAdvanced filter panel: The right sidebar contains comprehensive filtering options for all license attributes"},{"page":155,"heading":"Editing a License","anchor":"editing-a-license","text":"The Edit License screen allows you to create or modify an existing license's details and settings. This screen is divided into several sections that control different aspects of the license.\nLicense Template\nAt the top of the form, you can select the license template that will define the base parameters for this license. In the example, \"ACME Charting 1.8.0.0 Template\" is selected. A template provides predefined settings that serve as a starting point for the license.\nLicense Information\nThis section contains the core license identifiers:\nLicense Id: The unique identifier for this license (e.g., \"lic929CEF80\")\nUser Key: The activation key that end-users will enter to activate their software (e.g., \"PSLGJ-QF7WM-I6JWK-UWCTK\").\nTerms\nThis section defines the operational parameters of the license:"},{"page":155,"heading":"Editing a License","anchor":"editing-a-license","text":"Mode: Determines how the license is deployed:\nActivation: The license is activated on specific machines\nFloating: Multiple machines can share the license\nFile: The license is distributed as a file\nSites: The number of installations or activations permitted (50 in the example)\nLicense Type: Categorizes the license (e.g., \"Server\")\nFormat: The format in which the license is issued (e.g., \"Ascii\")\nIssue Date: When the license was created (2024-11-14 17:12:58)\nExpire Date: When the license will expire (2024-12-14 17:13:00)\nSupport Expire Date: When technical support for this license ends\nRevoked: Toggle to revoke the license, preventing further use\nTrace: Toggle to enable tracking of license usage and activities\nDescription: An optional field for additional notes about the license\nLicensee\nThis section captures information about the license holder:\nSelect a customer: Dropdown to choose from existing customers\nName: The individual's name associated with the license\nCompany: The organization name (Lumenbyte)\nEmail: Contact email for the licensee (contact@lumenbyte.example.com)\nProperties\nThis tabbed section includes details about the components covered by the license:\nASSEMBLIES Tab\nLists the software assemblies included in this license with their details:\nName: Assembly name (analysis, charting, web)\nVersion: Software version (1.8.0.0)\nCulture: Localization setting (neutral)\nPublic Key Token: Cryptographic identifier (45cd17b5db21e42)\nOther available tabs include:"},{"page":155,"heading":"Editing a License","anchor":"editing-a-license","text":"COMPONENTS\nFIELDS\nFEATURES\nRestrictions\nThis section allows you to add and configure limitations for the license:\nTRIAL: Restricts the license to a trial period\nExpire Days: How many days the trial will last (30)\nRun Instances: Limits simultaneous installations\nRun Count: Maximum number of times the software can be launched\nRun Time: Maximum duration the software can be used\nUSAGE: (Available but not currently configured)\nTerms: Additional licensing terms and conditions\nAction Buttons\nSAVE: Commits all changes to the license\nCANCEL: Discards changes and returns to the previous screen\nThis screen provides comprehensive control over license configuration, allowing administrators to precisely define how software can be used, for how long, and by whom.\nEdit License"},{"page":155,"heading":"Tips for Efficient License Management","anchor":"tips-for-efficient-license-management","text":"Use the filter panel to quickly locate licenses by customer, expiration date, or license mode\nEnable activity tracking (pin icon) for important licenses to monitor their usage\nRegularly review the activity logs to detect any unusual or unauthorized usage patterns\nCheck the Sites column to ensure you're not exceeding your licensed capacity\nUse the Type filter to group licenses by environment (Server, Cloud, Enterprise, Corporate)\nMonitor Expire Date and Support Expire Date to plan for renewals\nUse the Revoke function to immediately disable licenses when needed\nThe Babel Licensing Web Application makes it easy to maintain control over your software licenses while providing valuable insights into how they are being utilized across your organization."},{"page":155,"heading":"Template defaults","anchor":"template-defaults","text":"When creating a license from a template, its licensing mode (File, Activation or Floating) is applied along with the template dates. Review the mode and the issue, expiry and support dates before saving; changing the mode does not reset the populated dates."},{"page":156,"heading":"","anchor":"","text":"The Log section of the Babel Licensing Web Application provides a comprehensive monitoring and troubleshooting tool that records all system activities and events. This page displays detailed information about application requests, actions, and processes, enabling administrators to track system behavior and diagnose issues.\nLog"},{"page":156,"heading":"Overview","anchor":"overview","text":"The Log page presents a visual and tabular representation of system events with the following key components:"},{"page":156,"heading":"Activity Graph","anchor":"activity-graph","text":"At the top of the page, a histogram displays log activity frequency over time. This graph:\nShows activity levels across multiple days\nIndicates time intervals with higher activity\nProvides time markers for precise temporal reference\nGroups data by day with clear date labels"},{"page":156,"heading":"Date Selection","anchor":"date-selection","text":"The date selection controls allow you to define the time period for log analysis:\nStart Date: Set the beginning of your analysis period\nEnd Date: Set the end of your analysis period\nCalendar Icon: Opens a date picker for easier date selection"},{"page":156,"heading":"Log Management Controls","anchor":"log-management-controls","text":"DELETE button: Remove selected log entries\nSearch field: Filter log entries by specific text or criteria\nRefresh button: Update the log display with the latest entries\nOptions menu (three dots): Access additional log management functions"},{"page":156,"heading":"Log Entry Table","anchor":"log-entry-table","text":"The main table displays detailed information about each log entry with sortable columns:\nCheckbox: Select entries for bulk actions\nId: Unique identifier for each log entry (e.g., 252469, 252468)\nTimestamp: Date and time when the event occurred (format: YYYY-MM-DD HH:MM:SS)\nLevel: Severity or type of the log entry (e.g., Debug, Information, Warning, Error, Fatal)\nMessage: Brief description of the event or action"},{"page":156,"heading":"Detailed Entry View","anchor":"detailed-entry-view","text":"When an entry is selected (highlighted in blue in the example), additional details appear below the table:\nMessage: Full text of the log message\nContext: Structured JSON data providing comprehensive details about the event, including:\nEndpointName\nEventId\nRequestId\nRequestPath\nConnectionId\nMachineName\nThreadId\nOther relevant technical information\nCommon Log Entry Types\nThe example shows several types of log entries you might encounter:\nRequest starting/finished events\nEndpoint execution events\nAction execution events\nRoute matching information\nUsing the Log Effectively\nTroubleshooting: Use the log to investigate issues by filtering for specific time periods when problems occurred\nSecurity Monitoring: Review logs for unusual activity or potential security breaches\nPerformance Analysis: Identify performance bottlenecks by examining request execution times\nAudit Trail: Maintain records of all system activities for compliance and administrative purposes\nThe Log page provides essential visibility into the operation of your Babel Licensing Service, helping you maintain system health and quickly resolve any issues that arise."},{"page":157,"heading":"","anchor":"","text":"The Orders page in Babel Licensing Service provides a comprehensive view of all purchase orders in the system. This interface allows administrators to track, manage, and process orders efficiently.\nOrders"},{"page":157,"heading":"Key Features","anchor":"key-features","text":"Order Listing and Navigation\nView a paginated list of all orders with 10 orders displayed per page by default\nCustomize items per page (5, 10, or 20 entries)"},{"page":157,"heading":"Search and Filter","anchor":"search-and-filter","text":"Use the search field in the top right to find specific orders\nApply column-specific filters to narrow down results based on criteria like order number, payment type, or date ranges\nReset filters using the refresh button"},{"page":157,"heading":"Column Information","anchor":"column-information","text":"Order Number: Unique identifier for each order (format: WP #xxxx)\nProcessed By: The system or user that processed the order (WordPress in this case)\nTotal: The monetary value of the order in Euros\nCreated At: Date and time when the order was created\nPayment Type: The payment processing method (stripe_cc, ppcp-gateway)\nPayment Number: Transaction reference ID from the payment processor\nPayment Date: Date and time when the payment was processed"},{"page":157,"heading":"Order Management Actions","anchor":"order-management-actions","text":"Edit (pencil icon): Modify order details\nDelete (trash can icon): Remove an order from the system\nAdding New Orders\nUse the \"ADD\" button in the top right to create a new order manually in the system.\nPagination Controls\nNavigate through pages using numbered pagination (1, 2, 3, 4, 5, ...)\nJump to the first or last page\nSelect specific page numbers"},{"page":157,"heading":"Tips for Effective Order Management","anchor":"tips-for-effective-order-management","text":"Use the search functionality to quickly locate specific orders\nApply column filters to identify orders by date ranges or payment methods\nRegularly review recent orders to ensure proper processing\nUse the edit function to update order information when necessary\nMonitor payment types and totals to track your revenue streams\nThis comprehensive order management system helps administrators maintain accurate records of all transactions within the Babel Licensing Service."},{"page":157,"heading":"Customer and products","anchor":"customer-and-products","text":"Open ADD or the edit icon of an existing order. Use Customer to search and select a customer; clearing the field removes the association when saved.\nIn Products, search by product name or code and select one or more products. Click Save to persist the order and its associations, or Cancel to leave the form.\nExisting product quantities and unit prices remain unchanged when those products remain selected; a newly associated product starts with quantity 1.\nThis selector does not edit quantities, unit prices or automatically calculate the order total. Enter the total, currency and payment information separately.\nFor an unpaid order, leave Payment Date and payment references empty. Completed or paid orders and orders with dependent records may be protected from deletion by the service.\nOrder customer — fictional demonstration data\nOrder customer — fictional demonstration data\nOrder products and Save/Cancel — fictional demonstration data\nOrder products and Save/Cancel — fictional demonstration data"},{"page":158,"heading":"","anchor":"","text":"The Products view lists every software product that can be licensed through Babel Licensing. Administrators use it to create, edit and manage product entries, which templates and licenses are built on.\nProducts"},{"page":158,"heading":"Overview","anchor":"overview","text":"The Products view displays a tabular list of all software products registered in your Babel Licensing system. Each row represents a unique product with its key properties displayed across multiple columns."},{"page":158,"heading":"Action Buttons","anchor":"action-buttons","text":"At the top of the Products view, you'll find several important action buttons:\nADD: Creates a new product entry\nSearch: Allows you to search for specific products\nColumn Chooser: Enables adding or removing column information (button with document icon)\nRefresh: Updates the product list to reflect the latest changes"},{"page":158,"heading":"Product List Columns","anchor":"product-list-columns","text":"The product grid displays the following information for each product:\nCode: The unique product code/SKU (e.g., BPU01, B0030)\nName: The full name of the product (e.g., ACME TradeSphere Standard Upgrade)\nCreated At: The date and time when the product was created in the system\nPrice: The product's price in the configured currency (e.g., €250.00)\nDescription: A brief description of the product"},{"page":158,"heading":"Row Actions","anchor":"row-actions","text":"Each product row includes action buttons:\nEdit (pencil icon): Opens the product editor to modify the product details\nDelete (trash can icon): Removes the product from the system\nAt the bottom of the page, a pagination control allows you to navigate between pages of products."},{"page":158,"heading":"Creating a New Product","anchor":"creating-a-new-product","text":"Open the new product form\nClick the ADD button at the top of the product list.\nFill in the product details\nFill in the product details, including:\nProduct code\nFull product name\nPrice information\nDescription\nChoose the sign keys\nChoose the Sign Keys which will be used to sign all the licenses.\nConfigure additional properties\nConfigure any additional product properties.\nSave the product\nSave the product."},{"page":158,"heading":"Managing Existing Products","anchor":"managing-existing-products","text":"Use the search functionality to locate specific products\nClick the edit (pencil) icon to modify a product\nUse the delete (trash can) icon to remove products that are no longer offered"},{"page":158,"heading":"Product-Template Relationship","anchor":"product-template-relationship","text":"Products defined in this view serve as the foundation for license templates. When creating license templates, you'll select products from this list to associate with the template. This relationship ensures that licenses are properly tied to specific products with their respective features and restrictions."},{"page":159,"heading":"","anchor":"","text":"The Reports page in Babel Licensing Web Application lists all the reports submitted by licensed applications and lets you manage them. Use it to track application health, license usage patterns, security events and custom metrics.\nReports list — fictional demonstration data\nReports list — fictional demonstration data"},{"page":159,"heading":"Overview","anchor":"overview","text":"The Babel Licensing reporting system supports three distinct report types, each designed for specific monitoring and analysis needs:\nException Reports: Track application errors, crashes, and exceptions with detailed diagnostic information\nLicense Reports: Monitor how licensed features, fields, and restrictions are being used in your applications\nCustom Reports: Collect application-specific data such as security events, performance metrics, or business events\nThe Reports page displays all submitted reports in a unified interface, allowing you to filter, search, and analyze data across all report types."},{"page":159,"heading":"Report Types","anchor":"report-types","text":"Understanding Report Names\nThe Name column in the reports grid identifies the type of report:\nExceptionReport: Application crash and error reports\nLicenseReport: License usage tracking reports\nHackDetection, SecurityEvent, PerformanceMetrics, etc.: Custom report types defined by your application"},{"page":159,"heading":"Interface Components","anchor":"interface-components","text":"The central element of the Reports page is a data grid displaying all submitted reports with the following columns:\nName: Identifies the type of report (e.g., \"ExceptionReport\", \"LicenseReport\", \"SecurityEvent\")\nDate: Shows the timestamp when the report was generated (format: YYYY-MM-DD HH:MM:SS)\nAddress: Displays the IP address of the client machine that generated the report\nUser Key: Contains the license key associated with the application instance\nMachine Id: Shows a unique identifier for the client machine\nClient Name: Indicates the client device type or name (e.g., \"Mac\", \"Windows PC\")"},{"page":159,"heading":"Search and Filtering","anchor":"search-and-filtering","text":"At the top of the page, you'll find:\nA global search bar for quickly finding specific reports\nColumn-specific filter icons (magnifying glass) for filtering by individual fields\nA date picker for filtering reports by specific time periods"},{"page":159,"heading":"Actions","anchor":"actions","text":"Each report row includes action buttons:\nEdit (pencil icon): Opens the report details view for examining the full exception information\nDelete (trash icon): Removes the report from the system"},{"page":159,"heading":"Using the Reports Page","anchor":"using-the-reports-page","text":"By default, newly received reports appear first by record ID. Click Date to sort by the time reported by the application, which can differ from arrival order. Use the Name column filter to select a report type."},{"page":159,"heading":"Filtering by Report Type","anchor":"filtering-by-report-type","text":"To view only specific types of reports:\nOpen the Name column filter\nClick the filter icon in the Name column header.\nEnter the report type\nEnter the report type name (e.g., \"ExceptionReport\", \"LicenseReport\").\nApply the filter\nPress Enter to apply the filter.\nThis allows you to focus on exception reports for debugging, license reports for usage analysis, or custom reports for application-specific monitoring."},{"page":159,"heading":"Analyzing Report Details","anchor":"analyzing-report-details","text":"To view detailed information about any report:\nLocate the report of interest in the list\nClick the edit (pencil) icon on the left side of the report row\nThe details view will display different information depending on the report type.\nException Reports\nException Reports capture comprehensive information about application crashes and errors, providing the diagnostic context needed to reproduce and fix bugs efficiently."},{"page":159,"heading":"What Gets Reported","anchor":"what-gets-reported","text":"Exception reports include three main categories of information:\n1. Exception Details\nException type, message, and source\nComplete stack trace with line numbers\nInner exceptions (nested errors)\n2. Environment Information\nApplication name and version\nLoaded assemblies with file versions\nEnvironment variables (filtered for privacy)\nRunning processes (optional)\nVirtual machine detection\nSystem clock rollback detection\n3. System Information\nOperating system details (name, version, architecture)\nProcessor information (cores, speed, manufacturer)\nMemory (total and available)\nDisk drives (capacity, free space)\nDisplay adapters\nNetwork adapters"},{"page":159,"heading":"Exception Report Details View","anchor":"exception-report-details-view","text":"The Exception Report Details view provides an in-depth analysis of individual exception reports. When you select an exception report from the main Reports page, you'll be presented with this comprehensive view.\nException Report Details"},{"page":159,"heading":"Report Information Section","anchor":"report-information-section","text":"At the top of the page, the \"Report Information\" panel displays essential identifying details about the exception:\nUid: A unique identifier for the report (e.g., \"f9b30aeb-6d9b-4556-bb0e-8521b7ba2368\")\nDate: The timestamp when the exception occurred (e.g., \"3/16/2025, 8:26:50 PM\")\nUser Key: The license key associated with the application instance, displayed as a clickable link\nClient Name: The type of client machine (e.g., \"Mac\")\nAddress: IP address of the client machine that generated the report (e.g., \"192.168.65.1\")\nMachine ID: A unique hardware identifier for the client device (e.g., \"ADSQH-89GGJ-J7CJY-3FQFK-DF48H\")\nApplication ID: The identifier of the application that generated the report (e.g., \"ACME EquiTrack\")"},{"page":159,"heading":"Properties Grid","anchor":"properties-grid","text":"The \"Properties\" section provides a tabular view of additional metadata related to the exception:\nsource: Identifies the source of the exception (e.g., \"console_exception_report_example\")\ntype: The exact exception type that occurred (e.g., \"System.OutOfMemoryException\")\nmessage: The error message associated with the exception (e.g., \"Array dimensions exceeded supported range.\")\nstack_trace: A truncated preview of the stack trace showing where the exception occurred\ncmdline: The command line used to launch the application that generated the exception\nThe Properties grid includes pagination controls at the bottom, allowing you to navigate through multiple pages of properties if present."},{"page":159,"heading":"Detailed Exception Information","anchor":"detailed-exception-information","text":"The bottom section of the page contains detailed information about the exception, organized into multiple tabs:\nEXCEPTION (Active Tab)\nThis tab displays:\nMessage: The complete error message (e.g., \"Array dimensions exceeded supported range.\")\nType: The exception class name (e.g., \"System.OutOfMemoryException\")\nSource: The source of the exception (e.g., \"console_exception_report_example\")\nSTACK TRACE: The full stack trace showing the exact execution path that led to the exception, including:\nMethod names\nFile paths\nLine numbers\nClass names"},{"page":159,"heading":"Additional Tabs","anchor":"additional-tabs","text":"The interface also provides several other tabs for contextual information:\nPROCESS: Information about the process in which the exception occurred\nENVIRONMENT: Details about the system environment at the time of the exception\nSYSTEM: System configuration information\nASSEMBLIES: List of loaded assemblies/libraries at the time of the exception"},{"page":159,"heading":"Navigation and Actions","anchor":"navigation-and-actions","text":"At the bottom of the page, you'll find:\nBACK: A button to return to the main Reports list view"},{"page":159,"heading":"Using the Report Details View","anchor":"using-the-report-details-view","text":"This detailed view enables developers and support teams to:\nDiagnose Issues: Pinpoint the exact cause and location of exceptions\nReproduce Problems: Understand the context in which errors occur\nTrack Patterns: Identify recurring issues across applications\nPrioritize Fixes: Determine the severity and impact of reported exceptions\nValidate Fixes: Verify that implemented solutions have resolved the reported issues\nBy examining the stack trace and environmental context, developers can quickly identify the root cause of the exception and implement appropriate fixes, ultimately improving the stability and reliability of their applications."},{"page":159,"heading":"Exception Report Benefits","anchor":"exception-report-benefits","text":"Exception reports offer several advantages for software providers:\nQuickly identify recurring issues in your applications\nUnderstand the context of exceptions to aid troubleshooting\nMonitor the stability of different application versions\nTrack exception patterns across various client configurations\nStreamline the bug fixing process with detailed error information\nClient-Side Implementation\nTo send exception reports from your application, see Exception Reports in the Reporting documentation.\nLicense Reports\nLicense Reports provide detailed insights into how your application uses licensed features, fields, and restrictions. These reports help you understand feature adoption, validate compliance, and make data-driven decisions about licensing strategy.\nLicense Report Details View"},{"page":159,"heading":"What Gets Tracked","anchor":"what-gets-tracked","text":"License reports automatically capture usage information when license tracking is enabled in the client application. The tracking system monitors all interactions with license components, including feature access, field reads, and restriction validations:\nFeature Usage\nFeature name and ID\nAccess counts per member (e.g., get_Data, get_IsEnabled)\nFirst and last access timestamps\nTotal access duration\nField Access\nField name and value (truncated for privacy)\nAccess patterns per member\nRead frequency\nRestriction Validation\nRestriction name and type\nValidation results (Pass/Fail)\nAccess times and counts"},{"page":159,"heading":"License Report Details View","anchor":"license-report-details-view","text":"When you view a License Report in the web application, you'll see a comprehensive dashboard that displays all tracked license usage data. The view organizes feature access, field reads, and restriction validations into easy-to-analyze sections with detailed statistics.\nReport Information Section\nUid: Unique report identifier\nDate: When the report was generated\nUser Key: License key associated with the report\nClient Name: Client device type\nAddress: IP address of the client machine\nMachine ID: Unique hardware identifier\nApplication ID: Application that generated the report\nProperties Grid\nThe Properties section includes license-specific metadata:\nlicense_id: The ID of the tracked license\nproduct_name: Product associated with the license\nlicensee_name: Name of the licensee\nlicensee_company: Company name\nfeatures: Comma-separated list of tracked features\nfields: Comma-separated list of tracked fields\nrestrictions: Comma-separated list of tracked restrictions\nDetailed Tracking Information\nThe bottom section contains multiple tabs with tracking data:\nFEATURES Tab\nDisplays detailed feature usage statistics:\nFeature name and ID\nMember access counts (e.g., get_Data: 15 accesses)\nFirst access timestamp\nLast access timestamp\nTotal access duration\nFIELDS Tab\nShows field access patterns:\nField name\nField value (truncated)\nMember access counts\nAccess timestamps\nRESTRICTIONS Tab\nLists restriction validation history:"},{"page":159,"heading":"License Report Details View","anchor":"license-report-details-view","text":"Restriction name and type\nValidation results\nCheck frequency\nAccess timestamps\nENVIRONMENT Tab\nContains environment information:\nApplication name and version\nLoaded assemblies\nEnvironment variables (filtered)\nProcess information\nSYSTEM Tab\nShows system configuration:\nOperating system details\nHardware information\nMemory and disk statistics"},{"page":159,"heading":"Report Merging","anchor":"report-merging","text":"License reports are automatically merged on the server when multiple reports arrive for the same license, machine, and client. This provides:\nCumulative Statistics: Access counts are added together\nTimeline Preservation: Earliest first access and latest last access\nHistorical Analysis: Complete usage patterns over time\nThis means each unique combination of license + machine + client has a single comprehensive report that grows over time."},{"page":159,"heading":"License Report Benefits","anchor":"license-report-benefits","text":"License reports help you:\nMonitor Feature Adoption: See which features are used most frequently\nIdentify Unused Features: Find features that are never accessed\nTrack Usage Patterns: Analyze when and how often features are used\nValidate Compliance: Ensure restrictions are being checked properly\nPlan Licensing Strategy: Make data-driven decisions about feature packaging\nClient-Side Implementation\nTo enable license tracking and send license reports from your application, see License Reports in the Reporting documentation.\nCustom Reports\nCustom Reports allow you to collect any application-specific data that doesn't fit into the standard exception or license report categories. By creating custom report classes that inherit from the Report base class, you can send structured data tailored to your application's needs. Common examples include security events, performance metrics, business events, and diagnostic information.\nCustom Report Details View"},{"page":159,"heading":"Common Custom Report Types","anchor":"common-custom-report-types","text":"Security Event Reports\nTrack potential security threats and attack patterns:\nHackDetection: Unauthorized access attempts, SQL injection, XSS, CSRF, and other attack types with detailed statistics including attack distribution, severity levels, and geographic sources\nSecurityEvent: Suspicious activities, intrusion detection, and anomaly tracking\nAuthenticationFailure: Failed login attempts, brute force detection, and suspicious credential usage\nPerformance Metrics Reports\nMonitor application performance:\nPerformanceMetrics: Response times, throughput, resource usage\nApiMetrics: API endpoint performance statistics\nBusiness Event Reports\nTrack important business events:\nBusinessEvent: Purchases, registrations, milestones\nAuditLog: User actions for compliance\nDiagnostic Reports\nCustom diagnostic information:\nDiagnostic: Component health checks, configuration issues"},{"page":159,"heading":"Custom Report Details View","anchor":"custom-report-details-view","text":"When you view a custom report in the web application, the details view displays:\nReport Information Section\nStandard metadata for all reports:\nUnique identifier (Uid)\nTimestamp\nUser key\nClient information\nMachine ID\nProperties Grid\nCustom reports have flexible properties based on the report type. Common properties include:\nFor Security Event Reports (e.g., HackDetection):\nhackingType: Type of attack detected (e.g., SQL Injection, XSS, CSRF)\nattackMethod: Method used in the attack (e.g., Malicious Input, Parameter Tampering)\nhackDetails: Detailed description of the detected threat\nmachineName: Machine where the attack was detected\nattackDistribution: Breakdown of attack types with counts (SQL Injection, XSS, CSRF, Path Traversal, Brute Force)\nattackTimeline: Time-series data showing attack patterns over days\nseverityLevels: Distribution of attacks by severity (Critical, High, Medium, Low)\nattackSources: Geographic distribution of attack origins\nFor Performance Metrics Reports:\naverage_response_time_ms: Average response time\npeak_response_time_ms: Peak response time\ntotal_requests: Total number of requests\nfailed_requests: Number of failed requests\nerror_rate: Percentage of failed requests\ncpu_usage_percent: CPU utilization\nmemory_usage_mb: Memory consumption\nFor Business Event Reports:"},{"page":159,"heading":"Custom Report Details View","anchor":"custom-report-details-view","text":"event_category: Category of business event\nevent_action: Action performed\nuser_id: User who triggered the event\nentity_type: Type of entity (Order, User, etc.)\nentity_id: Entity identifier\ntransaction_amount: Financial transaction amount\nDetailed Information Tabs\nCustom reports may include additional tabs with contextual information:\nENVIRONMENT: Application and runtime environment details\nSYSTEM: Hardware and OS information\nCUSTOM DATA: Report-specific data in JSON format\nData Visualization\nCustom reports that include structured data (such as attack distributions, timelines, and severity breakdowns) are automatically rendered with interactive visualizations:\nPie Charts: Display distribution data such as attack types or severity levels\nLine Charts: Show time-series data like attack timelines across multiple days\nBar Charts: Compare categorical data such as geographic attack sources\nArea Charts: Visualize cumulative trends over time\nThese visualizations provide immediate insights into your custom report data without requiring external analytics tools."},{"page":159,"heading":"Custom Report Benefits","anchor":"custom-report-benefits","text":"Custom reports provide:\nFlexibility: Track any data relevant to your application\nSecurity Monitoring: Detect and respond to threats in real-time\nPerformance Insights: Monitor application health and performance\nBusiness Intelligence: Track important business metrics\nAudit Compliance: Maintain audit trails for regulatory requirements\nClient-Side Implementation\nTo create and send custom reports from your application, see Custom Reports in the Reporting documentation.\nReport Management"},{"page":159,"heading":"Searching and Filtering","anchor":"searching-and-filtering","text":"Use the search and filtering capabilities to find specific reports:\nGlobal Search: Use the search bar to find reports across all columns\nColumn Filters: Click the filter icon in any column header to filter by that field\nDate Filtering: Use the date picker to filter reports by time period\nReport Type Filter: Filter by the Name column to show only specific report types"},{"page":159,"heading":"Deleting Reports","anchor":"deleting-reports","text":"To remove a report from the system:\nLocate the report\nLocate the report in the list.\nDelete it\nClick the delete (trash) icon on the left side of the report row.\nConfirm the deletion\nConfirm the deletion.\nNote: Deleted reports cannot be recovered. Exercise caution when deleting reports."},{"page":159,"heading":"Exporting Report Data","anchor":"exporting-report-data","text":"While the web interface provides comprehensive viewing capabilities, you can also access report data programmatically through the Babel Licensing Service API for:\nBulk data export\nIntegration with external analytics tools\nCustom reporting and visualization\nAutomated alerting and monitoring"},{"page":159,"heading":"Overall Benefits","anchor":"overall-benefits","text":"The Reports page offers comprehensive advantages for software providers:\nUnified Dashboard: View all report types in a single interface\nQuick Issue Identification: Rapidly identify and prioritize problems\nUsage Analytics: Understand how customers use your software\nSecurity Monitoring: Detect threats and unauthorized access\nData-Driven Decisions: Make informed choices about product development\nImproved Support: Quickly diagnose and resolve customer issues\nCompliance: Maintain audit trails and usage records\nWith the Reports page, you can improve application quality, enhance user experience, optimize licensing strategies, and reduce the time required to identify and resolve issues."},{"page":159,"heading":"Related Documentation","anchor":"related-documentation","text":"For information on implementing reporting in your client applications:\nReporting Overview - Introduction to the reporting framework\nException Reports - Implementing crash and error reporting\nLicense Reports - Enabling license usage tracking\nCustom Reports - Creating custom report types"},{"page":159,"heading":"Custom report charts","anchor":"custom-report-charts","text":"Plot properties in a custom report are rendered below the scalar properties grid. Data must follow the format in Custom Reports. UsageReport is a custom report, distinct from the built-in LicenseReport. These examples show CPU measurements and feature counts from fictional local data.\nCPU line chart — fictional data\nCPU line chart — fictional data\nFeature usage pie chart — fictional data\nFeature usage pie chart — fictional data"},{"page":159,"heading":"Deobfuscating exception reports","anchor":"deobfuscating-exception-reports","text":"Open an ExceptionReport and select EXCEPTION. Under Deobfuscated Stack Trace, the service matches maps using the reported assemblies or application name and version. Store the maps generated during obfuscation with the assemblies of the corresponding product release. If no match is found, choose that release in Map files. The original stays visible; the result lists maps used and the number of decoded frames. Hide Babel generated frames filters generated frames, Decode again repeats decoding, and Copy copies the result when maps are available. Without matching maps the report remains readable, but original method names cannot be restored."},{"page":160,"heading":"","anchor":"","text":"The Resources page in the Babel Licensing Web Application provides a central repository for managing various digital assets used throughout the licensing service. This page allows you to organize, access, and maintain important files such as email templates, signature keys, and other resources that support your licensing operations.\nResources"},{"page":160,"heading":"Overview","anchor":"overview","text":"The Resources page displays a comprehensive list of all assets in a tabular format, allowing for easy navigation and management. Each resource is categorized and includes detailed information about its purpose, format, and creation date."},{"page":160,"heading":"Page Actions","anchor":"page-actions","text":"At the top of the page, you'll find several action buttons:\nADD: Create or upload a new resource to the system\nSearch: Filter resources using the search field\nExport/Print: Generate reports or export resource information\nRefresh: Reset grid layout and update the resource list with the latest information"},{"page":160,"heading":"Resource Information","anchor":"resource-information","text":"The main grid displays detailed information about each resource with the following columns:\nType: Categorizes the resource (e.g., email, RSA)\nName: The title or identifier of the resource\nSource: Origin or file name of the resource (e.g., Babel.snk)\nCreated At: Date and time when the resource was added to the system\nData Format: The file format of the resource (e.g., html, PEM)\nDescription: A brief explanation of the resource's purpose"},{"page":160,"heading":"Resource Types","anchor":"resource-types","text":"The Resources page manages several types of assets:\nSignature Keys (type: RSA)\nDigital signature keys used to sign and validate licenses, including:\nPortable signature keys\nSystem-specific keys (e.g., Babel.snk)\nThese RSA 1024 Signature Keys are critical for license security and validation.\nEmail Templates (type: email)\nHTML-formatted email templates used for various customer communications, including:\nSoftware maintenance reminders\nTrial license notifications\nNew license delivery\nProduct updates\nEach email template is designed for a specific communication scenario and can be customized to match your branding requirements."},{"page":160,"heading":"Resource Management","anchor":"resource-management","text":"For each resource, the following actions are available:\nEdit (pencil icon): Modify the resource content or metadata\nDelete (trash icon): Remove the resource from the system\nDownload (down arrow icon): Save a local copy of the resource"},{"page":160,"heading":"Adding a New Resource","anchor":"adding-a-new-resource","text":"Open the add form\nClick the \"ADD\" button in the top-right corner.\nSelect the resource type\nSelect the resource type from the dropdown.\nUpload or create the content\nUpload or create the resource content.\nFill in the metadata\nFill in the required metadata (Name, Description).\nSave the resource\nSave the resource."},{"page":160,"heading":"Editing Resources","anchor":"editing-resources","text":"Locate the resource\nLocate the resource in the grid.\nOpen the editor\nClick the edit (pencil) icon.\nModify the content or metadata\nModify the content or metadata as needed.\nSave your changes\nSave your changes."},{"page":160,"heading":"Using Resources in the System","anchor":"using-resources-in-the-system","text":"Resources stored in this repository are available throughout the Babel Licensing Service:\nEmail templates are used for automated customer communications\nSignature keys are used for license generation and validation\nOther resources support various system functions"},{"page":160,"heading":"Best Practices","anchor":"best-practices","text":"Regularly review and update email templates to ensure they contain current information\nMaintain secure backups of signature keys\nUse descriptive names and complete descriptions to ensure resources are easily identifiable\nConsider creating standardized naming conventions for different resource types"},{"page":161,"heading":"","anchor":"","text":"Warning: Starting with 12.0 the web application is delivered encrypted inside the service package and is served only by a Babel Licensing Service with a Data Center license. It cannot be hosted from a separate static web server. To manage a Server edition service, use the Management API, or Babel Desktop on the service machine.\nThe Babel Licensing Service decrypts the web application scripts in memory at run time, and only when its license includes the web application feature. Copying the files from the service wwwroot folder to another web server, such as an nginx container, does not produce a working web application."},{"page":161,"heading":"Managing a Remote Service","anchor":"managing-a-remote-service","text":"To browse a remote Babel Licensing Service from your local machine, install Babel Desktop and add a Licensing connection to the service address with an API key. Babel Desktop works with both the Server and the Data Center editions, but profiles of remote services are read-only: creating, editing and deleting records requires a Local test profile with Local management, that is, Babel Desktop running on the service machine. To change the data of a remote service, use the Management API.\nIf the remote service runs the Data Center edition, you can also open the web application directly in a browser at the service address."},{"page":161,"heading":"Running the Service as API Only","anchor":"running-the-service-as-api-only","text":"To run the service as API only, without serving the web application, set EnableWebUI to false in the appsettings.json file:\n\"Application\": {\n  \"EnableWebApi\": true,\n  \"EnableWebUI\": false\n}\nWith EnableWebUI set to false the service does not serve the web application files. The REST API, gRPC and, when enabled, Swagger and the health check endpoint stay available, so Babel Desktop and other API clients keep working."},{"page":161,"heading":"API Key Generation","anchor":"api-key-generation","text":"The API key must be generated on the remote Babel Licensing Service. To generate an API key:\nOpen the web application or Babel Desktop\nNavigate to the \"API Keys\" section\nCreate a new API key with appropriate permissions\nCopy the generated key for use in your client configuration\nEnsure that the API key has sufficient permissions to perform the operations you need."},{"page":161,"heading":"Troubleshooting","anchor":"troubleshooting","text":"If you encounter issues connecting to the remote service:\nCheck Network Connectivity: Confirm that your local machine can reach the remote server (try using ping or similar tools)\nValidate API Key: Ensure the API key is valid and has the necessary permissions\nCheck SSL/TLS: If using HTTPS, verify that the SSL certificate is valid and trusted\nFirewall Settings: Ensure that your firewall allows outbound connections to the remote service port\nCheck Service Health: Use the health check endpoint (/health) on the remote service to verify it's operational\nCheck the Edition: If the browser shows the upgrade page instead of the web application, the service license does not include the web application feature. Replace babel.licenses with a Data Center license and restart the service."},{"page":161,"heading":"Security Considerations","anchor":"security-considerations","text":"When connecting to a remote licensing service, consider these security best practices:\nUse HTTPS for secure communication\nRegularly rotate API keys\nApply the principle of least privilege when assigning permissions to API keys\nDo not commit configuration files with API keys to source control\nInfo: Before 12.0 the web application files could be copied to a separate web server, for example an nginx Docker container, and pointed at a remote service through a config.js file. This procedure does not apply to the 12.0 service package."},{"page":162,"heading":"","anchor":"","text":"The Sign In page is the entry point to the Babel Licensing Web Application, serving as the security gateway that authenticates users before granting access to the system. This clean, minimalist interface ensures a straightforward authentication process.\nSign In Babel Licensing Web Application"},{"page":162,"heading":"Accessing the Sign In Page","anchor":"accessing-the-sign-in-page","text":"When the Babel Licensing Service is started on your server, you can access the web application by opening a web browser and navigating to:\nhttp://localhost:5455\nIf you've configured the service to run on a different port or server, adjust the URL accordingly.\nAuthentication Components\nThe Sign In page contains the following elements:\nUsername Field: Input field for entering your administrative username\nPassword Field: Secure input field for entering your password\nRemember Me: Checkbox option to maintain your session for future visits\nSIGN IN Button: Blue button to submit your credentials\nInitial Administrator Account\nStarting with Babel Licensing 11.7.0, the service no longer ships with the historical admin / admin default credentials. The administrator account is created on the first run from values you provide in the service configuration.\nSet the following keys before the first start, either in appsettings.json (under the Application section) or via the corresponding environment variables:\nSetting | Environment variable | Required\nApplication:AdminUsername | BABEL_SERVICE_APPLICATION__ADMINUSERNAME | Yes\nApplication:AdminPassword | BABEL_SERVICE_APPLICATION__ADMINPASSWORD | Yes\nApplication:AdminEmail | BABEL_SERVICE_APPLICATION__ADMINEMAIL | Recommended"},{"page":162,"heading":"Accessing the Sign In Page","anchor":"accessing-the-sign-in-page","text":"The administrator account is created on the first run only when both AdminUsername and AdminPassword are non-empty; if either is empty the service starts normally (roles are still seeded) but no administrator user is provisioned and you will not be able to sign in to the Web Application until you populate them and restart. Once the account exists, the password should be rotated through the Web Application and the AdminPassword configuration entry can be cleared.\nImportant Security Note: Choose a strong password for the initial administrator and never commit appsettings.json with AdminPassword populated. Prefer environment variables, a .env file outside source control, or a secret store. See Configuration for the full reference.\nUpon successful authentication, you will be redirected to the Dashboard page, where you can begin managing your software licensing operations.\nTroubleshooting Access\nIf you encounter issues accessing the Sign In page:\nVerify that the Babel Licensing Service is running correctly\nCheck that you're using the correct URL and port number\nEnsure your network configuration allows access to the service\nReview any firewall settings that might be blocking access\nAfter successful authentication, you'll have full access to all the features and functionalities of the Babel Licensing Web Application based on your user role and permissions."},{"page":162,"heading":"Session duration","anchor":"session-duration","text":"Without Remember Me, the session survives page reloads in the same browser tab and ends when that tab is closed. With Remember Me, the session is kept for subsequent visits until the server-issued token expires. Signing out clears the saved session. This option does not extend the token expiry."},{"page":163,"heading":"","anchor":"","text":"The License Templates view in Babel Licensing is where you manage the license templates used to create and issue licenses to your customers. These templates define the standard parameters and configurations that will be applied to new licenses.\nNote: For more detailed information on the conceptual framework and technical implementation of License Templates, including their role in the licensing architecture, please refer to the \"License Templates\" chapter of this manual.\nTemplates"},{"page":163,"heading":"Overview","anchor":"overview","text":"The Templates view displays a tabular list of all available license templates in your Babel Licensing system. Each row represents a single template with its key properties displayed across multiple columns."},{"page":163,"heading":"Action Buttons","anchor":"action-buttons","text":"At the top of the Templates view, you'll find several important action buttons:\nADD: Creates a new license template\nSearch: Allows you to search for specific templates\nRefresh: Updates the template list to reflect the latest changes\nImport/Export: Enables importing or exporting templates (button with document icon)"},{"page":163,"heading":"Template List Columns","anchor":"template-list-columns","text":"The template grid displays the following information for each template:\nName: The descriptive name of the template (e.g., \"ACME Charting 11.0.0\")\nIssue Date: Whether the template includes an issue date (indicated by a checkbox)\nSupport Days: The number of days of support included with licenses based on this template (typically 365)\nExpire Days: The number of days until licenses created from this template will expire\nType: The license type category (Server, Corporate, Basic, Enterprise, Cloud)\nFormat: The format in which licenses will be generated (XML DSig, XML)\nMode: The operational mode of the license (File, Activation)\nUser Key: The format for user keys generated with this template"},{"page":163,"heading":"Row Actions","anchor":"row-actions","text":"Each template row includes action buttons:\nEdit (pencil icon): Opens the template editor to modify the template\nDelete (trash can icon): Removes the template from the system\nAdditional Options (three dots menu): Provides access to more actions"},{"page":163,"heading":"License Modes","anchor":"license-modes","text":"The templates can be configured for different license modes:\nFile: Generates downloadable license files\nActivation: Creates licenses that require activation on specific machines\nFloating: Enables a pool of licenses to be shared among multiple users or machines, with a limit on concurrent usage"},{"page":163,"heading":"Format Options","anchor":"format-options","text":"Templates define the format for generated licenses:\nXML DSig: XML format with digital signature for enhanced security\nXML: Standard XML format\nASCII: Plain text format using standard ASCII character encoding including common character symbols like parentheses and punctuation.\nBASE32: Encoded format using Base32 encoding scheme, which produces license strings using alphanumeric characters"},{"page":163,"heading":"Creating a New Template","anchor":"creating-a-new-template","text":"Open the new template form\nClick the ADD button at the top of the template list.\nFill in the template details\nFill in the template details, including name, type, expiration, and format.\nConfigure properties and restrictions\nConfigure any additional properties or restrictions.\nSave the template\nSave the template."},{"page":163,"heading":"Managing Existing Templates","anchor":"managing-existing-templates","text":"Use the search functionality to locate specific templates\nClick the edit (pencil) icon to modify a template\nUse the delete (trash) icon to remove templates that are no longer needed"},{"page":163,"heading":"Editing License Templates in Babel Licensing","anchor":"editing-license-templates-in-babel-licensing","text":"The Edit Template screen in Babel Licensing allows you to create or modify license templates. This comprehensive interface is divided into several sections, each controlling different aspects of the license template.\nLicense Template Edit\nTemplate Import\nAt the top of the screen, you'll find options to import an existing template:\nSELECT XML TEMPLATE: Button to select an existing XML template file\nDrop XML file here: Area where you can drag and drop a template XML file\nTemplate Details\nThis section contains the basic information about the template:\nName: The descriptive name of the template\nLicense Type: The category of license (e.g., \"Premium\")\nMode: The deployment method for licenses created with this template:\nActivation: For licenses activated on specific machines\nFloating: For licenses shared among multiple users\nFile: For downloadable license files\nUser Key: The format for generating user activation keys (e.g., {TOKEN:5}-{TOKEN:5}-{TOKEN:5}-{TOKEN:5})\nIssue Date: Checkbox to include the issue date in licenses generated from this template\nExpire Days: Number of days until licenses created from this template will expire\nSupport Days: Duration of support provided with licenses (e.g., \"365\" days)\nLicense File Name: Default filename for generated license files (e.g., babel.licenses)\nFormat: Output format for licenses (e.g., \"Ascii\", \"XML\", \"XML DSig\", \"BASE32\")\nDescription: Optional field for additional information about the template\nSelection"},{"page":163,"heading":"Editing License Templates in Babel Licensing","anchor":"editing-license-templates-in-babel-licensing","text":"This section associates the template with specific products and signing keys:\nProduct: The software product this template is for (e.g., \"ACME TradeSphere\")\nSign Keys: Cryptographic keys used to sign licenses generated from this template\nSelect a sign key pair: Dropdown to choose from available signing keys\nInfo: If Signing Keys is not selected, the product's default keys will be used to sign the license.\nLicense Properties\nThis tabbed section defines the properties included in licenses created from this template:\nASSEMBLIES Tab\nLists the software assemblies covered by licenses created from this template:\nName: Assembly name (e.g., \"TradeSphere\")\nVersion: Software version (e.g., \"1.8.0.0\")\nCulture: Localization setting (e.g., \"neutral\")\nPublic Key Token: Cryptographic identifier (e.g., \"45cd27cb2b21cf6\")\nAdditional tabs include:\nCOMPONENTS: For managing software components\nFIELDS: For custom license fields\nFEATURES: For controlling feature access\nThe \"+\" button allows adding new assemblies, components, fields, or features.\nRestrictions\nThis section defines limitations and conditions for licenses generated from this template:\nADD RESTRICTION: Button to add various types of restrictions: BETA, DOMAIN, HARDWARE TRIAL, USAGE, CUSTOM"},{"page":163,"heading":"Creating Custom Restrictions","anchor":"creating-custom-restrictions","text":"Custom restrictions in Babel Licensing provide powerful flexibility when standard restriction types don't meet your specific licensing requirements. With custom restrictions, you can create tailor-made constraints for your software licenses based on unique parameters or conditions.\nThe Custom Restrictions panel allows you to define your own restriction logic through three main components:\nRestriction Name: A unique identifier for your custom restriction\nProperties: Key-value pairs that define the parameters of your restriction\nProperty Name: The name of the parameter (e.g., \"totalMemory\")\nProperty Value: The value associated with the parameter (e.g., \"4096\")\nUse the ADD PROPERTY button to include additional parameters\nCustom XML Content: Advanced configuration using XML syntax to define complex restriction logic that is represented by XML elements children of the custom Restriction element.\nThis section allows you to include custom XML elements that will be embedded in the license\nIn the example, <Cpu architecture=\"arm\" /> restricts the license to ARM-based processors\nTo create a custom restriction:"},{"page":163,"heading":"Creating Custom Restrictions","anchor":"creating-custom-restrictions","text":"Add a custom restriction\nClick the ADD RESTRICTION button and select \"CUSTOM\" from the dropdown menu.\nName the restriction\nEnter a meaningful name for your restriction that reflects its purpose.\nAdd properties\nAdd properties that define the parameters for your restriction.\nAdd custom XML elements if needed\nIf needed, include custom XML elements to implement more complex restriction logic.\nSave your changes\nSave your changes to apply the custom restriction to the license template.\nCustom restrictions are particularly useful for hardware-specific limitations (like CPU architecture or memory requirements), feature-based licensing, or any specialized licensing scenarios unique to your application.\nWhen licenses are generated from templates with custom restrictions, your application code must include logic to interpret and enforce these custom restrictions by checking the license properties against the runtime environment. To see full code example please refer to the License Restrictions paragraph.\nAction Buttons\nAt the bottom of the screen, you'll find:\nSAVE: Saves all changes to the template\nCANCEL: Discards changes and returns to the previous screen"},{"page":163,"heading":"Best Practices","anchor":"best-practices","text":"Create separate templates for different product versions and license types\nUse consistent naming conventions for templates to make them easily identifiable\nRegularly review and update templates to reflect changes in your licensing strategy\nThe License Templates view serves as the foundation of your licensing system, allowing you to standardize license generation while maintaining flexibility for different products and license types."},{"page":164,"heading":"","anchor":"","text":"Webhooks allow external applications to receive real-time notifications when specific events occur in the Babel Licensing Service. Use them to connect your existing systems, automate workflows and keep data synchronized.\nWebhooks\nAccessing Webhooks\nWebhooks are available from the main navigation menu in the Babel Licensing Service. Click on the \"Webhooks\" menu item in the left sidebar to access the webhooks management interface."},{"page":164,"heading":"Managing Webhooks","anchor":"managing-webhooks","text":"Viewing Webhooks\nThe webhooks page displays a table with all configured webhook subscriptions and their details:\nName: A descriptive name for the webhook\nURL: The endpoint where event notifications will be sent. The URL is shown as a clickable link only when it uses http or https.\nEvent: The type of event the webhook is subscribed to\nOwner User: The user who created the webhook\nSent At: The timestamp of the last event delivery\nNext Retry: When the next delivery attempt will occur (if applicable)\nStatus: Current status of the webhook (OK, Error, etc.)"},{"page":164,"heading":"Adding a New Webhook","anchor":"adding-a-new-webhook","text":"Open the new webhook form\nClick the \"+ ADD\" button in the top-right corner of the webhooks page.\nFill in the required information\nName: Enter a descriptive name for the webhook\nURL: Provide the endpoint URL where notifications should be sent\nEvent: Select the event type(s) you want to subscribe to\nSecret: Generate or enter a secret key for request verification\nSave the webhook\nClick \"Save\" to create the webhook subscription."},{"page":164,"heading":"Editing a Webhook","anchor":"editing-a-webhook","text":"Find the webhook\nFind the webhook in the list.\nOpen the editor\nClick the edit icon (pencil) in the row.\nModify the details\nModify the webhook details.\nSave your changes\nClick \"Save\" to update the webhook subscription."},{"page":164,"heading":"Deleting a Webhook","anchor":"deleting-a-webhook","text":"Find the webhook subscription\nFind the webhook subscription in the list.\nDelete it\nClick the delete icon (trash) in the row.\nConfirm the deletion\nConfirm the deletion when prompted."},{"page":164,"heading":"Testing a Webhook","anchor":"testing-a-webhook","text":"Find the webhook subscription\nFind the webhook subscription in the list.\nSend a test event\nClick the refresh icon to send a test event.\nView the delivery result\nView the delivery result in the webhook events details.\nThe system will process the test event through the same delivery mechanism as real events, including the same headers and signature verification, allowing you to validate your endpoint's handling of webhook payloads."},{"page":164,"heading":"Webhook Event Details","anchor":"webhook-event-details","text":"When a webhook is triggered, the expanded view shows delivery details:\nTimestamp: When the event occurred\nEvent Type: The type of event (e.g., license.created)\nStatus: Delivery status (OK, Failed)\nResponse: The response received from your endpoint\nError: Any error messages (if delivery failed)\nRetry Count: Number of delivery attempts\nNext Retry: When the next retry will occur (if applicable)"},{"page":164,"heading":"Supported Events","anchor":"supported-events","text":"Babel Licensing Service supports the following webhook events:\nLicenses\nlicense.created Triggered when a new license is created.\nlicense.updated Triggered when an existing license is updated.\nlicense.deleted Triggered when a license is deleted.\nlicense.expiring Triggered when a license is about to expire.\nlicense.expired Triggered when a license has expired.\nlicense.revoked Triggered when a license is revoked.\nlicense.supportexpiring Triggered when a license's support is about to expire.\nlicense.supportexpired Triggered when a license's support has expired.\nlicense.activated Triggered when a license is activated.\nlicense.deactivated Triggered when a license is deactivated.\nlicense.requested Triggered when a license is requested.\nlicense.released Triggered when a license is released.\nOrders\norder.created Triggered when a new order is created.\norder.updated Triggered when an existing order is updated.\norder.deleted Triggered when an order is deleted.\nReports\nreport.created Triggered when a new report is created."},{"page":164,"heading":"Webhook Payload Reference","anchor":"webhook-payload-reference","text":"This section provides detailed information about the structure and content of webhook event payloads for different event types.\nLicense Event Payload\nWhen handling a license event (like license.created), the payload includes the following fields:\n{\n    \"id\": 101,\n    \"licenseId\": \"LIC-0001\",\n    \"userKey\": \"XJK-SHJD-GE5E\",\n    \"licensee\": \"Acme Corp\",\n    \"licensingMode\": 1,\n    \"issueDate\": \"2025-03-16T00:00:00Z\",\n    \"supportExpireDate\": \"2026-03-16T00:00:00Z\",\n    \"expireDate\": \"2025-12-31T23:59:59Z\",\n    \"customerId\": 501,\n    \"orderId\": 302,\n    \"templateId\": 10,\n    \"revoked\": false,\n    \"trace\": false,\n    \"eventType\": \"license.created\",\n    \"timestamp\": \"2025-03-16T12:00:00Z\"\n}"},{"page":164,"heading":"Webhook Payload Reference","anchor":"webhook-payload-reference","text":"Field | Type | Description\nid | Integer | The unique database identifier for the license. Used for API reference and internal tracking.\nlicenseId | String | A human-readable license identifier (e.g., \"LIC-0001\") used in customer communications and documentation.\nuserKey | String | The activation key that end-users enter to activate the licensed software.\nlicensee | String | The name of the individual or organization to whom the license is issued.\nlicensingMode | Integer | The type of licensing mode applied (e.g., \"0: File\", \"1: Activation\", \"2: Floating\").\nissueDate | ISO 8601 DateTime | The date and time when the license was initially issued.\nsupportExpireDate | ISO 8601 DateTime | The date and time when technical support for this license ends.\nexpireDate | ISO 8601 DateTime | The date and time when the license itself expires and becomes invalid.\ncustomerId | Integer | Reference to the customer who owns this license. Maps to a customer record in the system.\norderId | Integer | Reference to the order through which this license was purchased.\ntemplateId | Integer | The ID of the license template used to generate this license, determining its features and limitations.\nrevoked | Boolean | Indicates whether the license has been invalidated administratively (true) or remains active (false).\ntrace | Boolean | Indicates whether the license has tracing enabled."},{"page":164,"heading":"Webhook Payload Reference","anchor":"webhook-payload-reference","text":"eventType | String | Identifies the specific event type that triggered this webhook (e.g., \"license.created\", \"license.updated\").\ntimestamp | ISO 8601 DateTime | The exact time when the event occurred and the webhook was dispatched.\nOrder Event Payload\nFor order-related events (like order.created), the webhook payload contains these fields:\n{\n    \"id\": 202,\n    \"orderNumber\": \"ORD-12345\",\n    \"customerId\": 501,\n    \"createdAt\": \"2025-03-16T12:00:00Z\",\n    \"status\": \"completed\",\n    \"eventType\": \"order.created\",\n    \"timestamp\": \"2025-03-16T12:05:00Z\"\n}\nField | Type | Description\nid | Integer | The unique database identifier for the order. Use this ID when making API calls for order details.\norderNumber | String | A human-readable order reference number used in customer communications and financial records.\ncustomerId | Integer | The unique identifier of the customer who placed the order. References a customer record.\ncreatedAt | ISO 8601 DateTime | The date and time when the order was initially created in the system.\nstatus | String | The current processing status of the order. Possible values include: \"pending\", \"processing\", \"completed\", \"cancelled\", \"refunded\".\neventType | String | Identifies which order event triggered this webhook (e.g., \"order.created\", \"order.updated\", \"order.deleted\").\ntimestamp | ISO 8601 DateTime | The exact time when the event occurred and the webhook was dispatched.\nReport Event Payload"},{"page":164,"heading":"Webhook Payload Reference","anchor":"webhook-payload-reference","text":"For report-related events (like report.created), the webhook payload includes these fields:\n{\n    \"id\": 303,\n    \"name\": \"Monthly Report\",\n    \"date\": \"2025-03-15T00:00:00Z\",\n    \"eventType\": \"report.created\",\n    \"timestamp\": \"2025-03-16T12:10:00Z\"\n}\nField | Type | Description\nid | Integer | The unique database identifier for the report. Use this ID to retrieve the full report via API.\nname | String | The descriptive title of the report as defined in the system.\ndate | ISO 8601 DateTime | The date associated with the report content (typically the reporting period end date).\neventType | String | Identifies which report event triggered this webhook (currently only \"report.created\").\ntimestamp | ISO 8601 DateTime | The exact time when the event occurred and the webhook was dispatched."},{"page":164,"heading":"Webhook Delivery and Retry Logic","anchor":"webhook-delivery-and-retry-logic","text":"Babel Licensing Service processes webhooks through a background service that runs continuously:\nThe service checks for new webhook events every 30 seconds\nWebhooks are processed in batches of up to 50 events at a time\nThe system handles both pending (new) events and previously failed events that are scheduled for retry\nEach webhook delivery includes standard headers:\nUser-Agent: Identifies the Babel Licensing Service\nX-Babel-Webhook-Id: Unique identifier for the webhook delivery\nX-Babel-Event: The type of event being delivered\nX-Babel-Timestamp: When the event was dispatched\nX-Babel-Signature: HMAC-SHA256 signature (if a secret is configured)\nRetry Mechanism\nWhen a webhook delivery fails:\nThe system automatically schedules a retry for 5 minutes later\nEach webhook can be configured with a maximum retry count\nFailed events remain in the system until they are successfully delivered or the maximum retry count is reached\nThe webhook interface shows the next scheduled retry time for failed deliveries\nEach failed delivery stores the error message or HTTP status code for troubleshooting\nWebhook Status\nWebhooks in the system can have the following statuses:\nOK: Event was successfully delivered\nFailed: Event delivery failed and maximum retries were exceeded\nPending: Event is waiting to be processed\nScheduled: Event delivery failed and is scheduled for retry"},{"page":164,"heading":"Securing Webhooks","anchor":"securing-webhooks","text":"All webhook requests include a signature in the X-Babel-Signature header. This signature is generated using HMAC-SHA256 with your webhook's secret key and the request body as input.\nTo verify the webhook:\nGet the signature\nGet the signature from the X-Babel-Signature header.\nCompute the expected signature\nCompute an HMAC-SHA256 signature using your secret key and the raw request body.\nCompare the signatures\nCompare the computed signature with the one in the header.\nProcess only on a match\nOnly process the webhook if signatures match.\nExample verification code (C#):\nprivate bool VerifyWebhookSignature(string payload, string signatureHeader, string secret)\n{\n    using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));\n    var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));\n    var computedSignature = Convert.ToBase64String(computedHash);\n    \n    return signatureHeader == computedSignature;\n}"},{"page":164,"heading":"Implementing a Webhook Receiver","anchor":"implementing-a-webhook-receiver","text":"Below is a complete example of how to implement a webhook receiver in ASP.NET Core that properly validates webhook signatures:"},{"page":164,"heading":"Implementing a Webhook Receiver","anchor":"implementing-a-webhook-receiver","text":"// WebhookValidator.cs\nusing System;\nusing System.Security.Cryptography;\nusing System.Text;\n\nnamespace YourProject.Utilities\n{\n    public static class WebhookValidator\n    {\n        /// <summary>\n        /// Validates the webhook payload against the provided signature using HMAC-SHA256.\n        /// </summary>\n        /// <param name=\"payload\">The raw JSON payload.</param>\n        /// <param name=\"secret\">The shared secret.</param>\n        /// <param name=\"signature\">The signature from the incoming request header.</param>\n        /// <returns>True if the signature is valid; otherwise, false.</returns>\n        public static bool ValidateSignature(string payload, string secret, string signature)\n        {\n            using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));\n            var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));\n            var computedSignature = BitConverter.ToString(hash).Replace(\"-\", \"\").ToLowerInvariant();\n            return string.Equals(computedSignature, signature, StringComparison.OrdinalIgnoreCase);\n        }\n    }\n}\n\n// WebhookController.cs\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.Logging;\nusing System.IO;\nusing System.Threading.Tasks;\nusing YourProject.Utilities;\n\nnamespace YourProject.Controllers\n{\n    [ApiController]\n    [Route(\"api/webhook\")]\n    public class WebhookController : ControllerBase\n    {\n        private readonly ILogger<WebhookController> _logger;"},{"page":164,"heading":"Implementing a Webhook Receiver","anchor":"implementing-a-webhook-receiver","text":"        // Ideally, the secret comes from configuration\n        private readonly string _webhookSecret = \"your-webhook-secret\";\n        \n        public WebhookController(ILogger<WebhookController> logger)\n        {\n            _logger = logger;\n        }\n        \n        [HttpPost]\n        public async Task<IActionResult> ReceiveWebhook()\n        {\n            // Read the payload from the request body\n            var payload = await new StreamReader(Request.Body).ReadToEndAsync();\n            \n            // Retrieve the signature from the request headers\n            if (!Request.Headers.TryGetValue(\"X-Babel-Signature\", out var incomingSignature))\n            {\n                _logger.LogWarning(\"Missing X-Babel-Signature header\");\n                return Unauthorized(\"Signature header missing\");\n            }\n            \n            // Validate the signature\n            if (!WebhookValidator.ValidateSignature(payload, _webhookSecret, incomingSignature))\n            {\n                _logger.LogWarning(\"Invalid webhook signature\");\n                return Unauthorized(\"Invalid signature\");\n            }\n            \n            // Process the webhook payload\n            _logger.LogInformation(\"Webhook payload validated and processed\");\n            \n            // TODO: Deserialize and process the payload as needed\n            \n            return Ok();\n        }\n    }\n}"},{"page":164,"heading":"Best Practices for Receiving Webhooks","anchor":"best-practices-for-receiving-webhooks","text":"When implementing a webhook receiver:\nAlways validate signatures - Use the provided signature validation code to verify the authenticity of each webhook\nStore your webhook secret securely - Don't hardcode it as shown in the example; use a secure configuration system\nRespond quickly - Return a 200 OK response as soon as you've validated the signature\nProcess asynchronously - After validating and returning a response, process the webhook in a background thread or queue\nImplement idempotency - Use the event ID to avoid processing duplicate webhooks if they're delivered more than once\nLog all webhook events - Keep a record of all received webhooks for debugging and auditing"},{"page":164,"heading":"Processing Webhook Events","anchor":"processing-webhook-events","text":"Handling Different Event Types\nYour webhook receiver should be designed to handle different event types appropriately. Here's an example of how you might process various webhook events after validating the signature:\n// Example of webhook event processing\nprivate async Task ProcessWebhookEvent(string payload, string eventType)\n{\n    switch (eventType)\n    {\n        case \"license.created\":\n            await ProcessNewLicense(payload);\n            break;\n            \n        case \"license.expired\":\n            await ProcessExpiredLicense(payload);\n            break;\n            \n        case \"order.created\":\n            await ProcessNewOrder(payload);\n            break;\n            \n        // Handle other event types\n            \n        default:\n            _logger.LogWarning($\"Unhandled webhook event type: {eventType}\");\n            break;\n    }\n}\n\n// Example deserialization and processing\nprivate async Task ProcessNewLicense(string payload)\n{\n    try\n    {\n        // Deserialize the payload\n        var licenseEvent = JsonSerializer.Deserialize<LicenseCreatedEvent>(payload);\n        \n        // Process the license\n        _logger.LogInformation($\"Processing new license: {licenseEvent.LicenseId}\");\n        \n        // Example: Store in your database, notify users, etc.\n        await _licenseService.SyncLicenseAsync(licenseEvent.Id);\n    }\n    catch (Exception ex)\n    {\n        _logger.LogError(ex, \"Error processing license.created webhook\");\n    }\n}"},{"page":164,"heading":"Troubleshooting","anchor":"troubleshooting","text":"Common Issues\nWebhook not receiving events: Check the webhook status in the dashboard and verify the event type is one you've subscribed to\nAuthentication failures: Verify your signature validation code is correct and that you're using the same secret as configured in the webhook\nTimeouts: Ensure your endpoint responds within a reasonable time (the system waits for a response before marking as successful)\nInvalid URL: Check that your webhook URL is accessible from the internet and returns HTTP 2xx status codes\nCustom headers not being applied: Review the format of your custom headers in the webhook configuration\nWebhook marked as failed: Check the error message in the webhook details to see the specific HTTP status code or exception that occurred\nViewing Webhook History\nFor each webhook, you can view the complete delivery history:\nClick on a webhook in the main list to expand its details\nThe history section shows all delivery attempts with timestamps, event types, status, and any error messages\nUse this information to diagnose delivery issues or verify successful deliveries"},{"page":165,"heading":"","anchor":"","text":"AI Integration with Babel Licensing (Data Center)\nInfo: AI integration through the Babel Licensing MCP Server is included in the Data Center edition. Babel Desktop's MCP server, available with both licensing editions, is the desktop alternative; see Two ways to integrate.\nBabel Licensing integrates with AI assistants through the Model Context Protocol (MCP), enabling you to manage licenses, customers, products, and more using natural language conversations with AI."},{"page":165,"heading":"Two ways to integrate","anchor":"two-ways-to-integrate","text":"There are two MCP servers, and which one fits depends on where your licensing data lives.\nBabel Licensing MCP Server: a standalone server that talks to the Babel Licensing Service over its REST API. Use it to drive a hosted licensing system remotely from any MCP client; it covers all the service's endpoints. The rest of this section describes this server.\nBabel Desktop MCP server: a local MCP server in Babel Desktop, off until you enable it. It works on the Babel Licensing Service profile the desktop is signed in to. Through its Licensing tools an assistant can read licensing entities, dashboards and reports, and propose creates, edits, revokes and deletes, which you confirm before they run. The obfuscation project tools are available in the same server. It is included in the Server and Data Center editions; see Babel Desktop MCP Server.\nUse the service MCP for a remote, API-backed system. Use the Babel Desktop MCP server if you already work in Babel Desktop and want the assistant to use the service profile it is connected to."},{"page":165,"heading":"What is AI Integration?","anchor":"what-is-ai-integration","text":"AI integration allows you to interact with your Babel Licensing system through conversational AI assistants like Claude. Instead of manually navigating through APIs, web interfaces, or writing custom scripts, you can simply ask an AI assistant to perform tasks in natural language.\nTraditional approach:\ncurl -X POST https://api.babel-licensing.com/licenses/activate \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-Key: your-key\" \\\n  -d '{\"userKey\":\"ABC-123\",\"productCode\":\"PROD001\",\"hardwareId\":\"HW-12345\"}'\nAI-powered approach:\nYou: \"Activate license ABC-123 for product PROD001 on hardware HW-12345\"\nAI:  \"I've activated the license successfully. It expires on December 31, 2025...\""},{"page":165,"heading":"How It Works","anchor":"how-it-works","text":"The Babel Licensing MCP Server acts as a bridge between AI assistants and your Babel Licensing API:\ngraph LR\n    A[You] <-->|Natural Language| B[AI Assistant<br/>Claude]\n    B <-->|MCP Protocol| C[MCP Server<br/>Babel Licensing]\n    C <-->|HTTPS/API| D[Babel Licensing<br/>Service]\n\n    style A fill:#e1f5ff,stroke:#01579b,stroke-width:2px\n    style B fill:#fff3e0,stroke:#e65100,stroke-width:2px\n    style C fill:#f3e5f5,stroke:#4a148c,stroke-width:2px\n    style D fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px\nYou communicate with an AI assistant in natural language\nAI Assistant understands your intent and determines which operations to perform\nMCP Server translates AI tool calls into Babel Licensing API requests\nBabel Licensing Service processes the requests and returns results\nAI Assistant presents the results in a conversational, easy-to-understand format"},{"page":165,"heading":"Benefits of AI Integration","anchor":"benefits-of-ai-integration","text":"1. Natural Language Interface\nInteract with your licensing system using plain English instead of learning API endpoints, parameters, and syntax.\nExample queries:\n\"Show me all active Ultimate licenses created this month\"\n\"Create a new customer called Acme Corp with email contact@acme.com\"\n\"Which licenses are expiring in the next 30 days?\"\n\"Generate a report of all Enterprise licenses for customer ID 123\"\n2. Intelligent Data Retrieval\nAI assistants can understand complex queries and automatically construct the appropriate filters, selections, and joins.\nAsk:\n\"Show me customers who have both active and expired licenses, including their contact information and recent orders\"\nAI automatically:\nFetches customers with licenses\nIncludes related contacts and orders\nFilters for both active and expired licenses\nPresents the data in an organized format\n3. Automated Workflows\nChain multiple operations together in a single conversation:\nExample workflow:\nYou: \"Create a new customer 'TechStart Inc', add their product manager\n      as a contact, create an order for 10 Team licenses, and\n      send them a welcome email\"\n\nAI:  1. Creates customer (ID: 456)\n     2. Adds contact person\n     3. Creates order with 10 licenses\n     4. Sends welcome email\n     ✓ All tasks completed successfully\n4. Data Analysis and Insights\nAsk analytical questions and get intelligent summaries:\nExamples:"},{"page":165,"heading":"Benefits of AI Integration","anchor":"benefits-of-ai-integration","text":"\"Which products have the highest license activation rates?\"\n\"Show me license usage trends over the last quarter\"\n\"Which customers have the most support tickets?\"\n\"Analyze our license renewal patterns\"\n5. Error Prevention and Validation\nAI assistants can help prevent mistakes by:\nValidating data before submission\nSuggesting corrections for malformed requests\nWarning about potentially problematic operations\nExplaining error messages in plain language\nExample:\nYou: \"Deactivate all licenses for customer 789\"\n\nAI:  \"This will deactivate 47 active licenses for TechStart Inc.\n      This is a significant action. Would you like me to:\n      1. Proceed with deactivation\n      2. Show you the list of licenses first\n      3. Filter by specific criteria\"\n6. Learning and Documentation\nAI assistants can explain API functionality, best practices, and help you understand your data:\nAsk:\n\"How do floating licenses work in Babel Licensing?\"\n\"What's the difference between deactivating and revoking a license?\"\n\"Explain the fields in this license object\"\n\"What are the best practices for license template configuration?\"\n7. Time Savings\nReduce the time spent on:\nWriting and debugging API scripts\nNavigating through web interfaces\nLooking up API documentation\nFormatting complex queries\nParsing and interpreting API responses\n8. Accessibility\nMake your licensing system accessible to team members who may not be:"},{"page":165,"heading":"Benefits of AI Integration","anchor":"benefits-of-ai-integration","text":"Familiar with REST APIs\nComfortable with command-line tools\nTechnical enough to write scripts\nExperienced with database queries"},{"page":165,"heading":"Use Cases","anchor":"use-cases","text":"Customer Support\nSupport agents can quickly:\nLook up customer license status\nActivate or deactivate licenses\nCheck expiration dates\nResolve activation issues\nGenerate license keys\nExample:\n\"Customer John Doe (email: john@example.com) says his license isn't working. Check his license status and recent activation attempts.\"\nSales Operations\nSales teams can:\nCreate new customers and orders\nGenerate trial licenses\nTrack license usage and renewals\nAnalyze customer license portfolios\nPrepare sales reports\nExample:\n\"Create a 30-day trial license for product Ultimate Edition for prospect sarah@newcompany.com\"\nDevelopment and Testing\nDevelopers can:\nTest license activation flows\nCreate test licenses and customers\nDebug integration issues\nValidate license configurations\nSimulate different scenarios\nExample:\n\"Create 5 test licenses for product DEV-001 with hardware IDs TEST-1 through TEST-5, all expiring tomorrow\"\nSystem Administration\nAdministrators can:\nMonitor system health\nReview error logs\nManage users and permissions\nConfigure webhooks\nAnalyze system usage\nExample:\n\"Show me all error-level log entries from the past 24 hours related to license activation failures\"\nReporting and Analytics\nAnalysts can:\nGenerate custom reports\nAnalyze licensing trends\nTrack customer behavior\nMonitor product performance\nIdentify opportunities\nExample:\n\"Create a summary report showing license activation trends by product and customer segment for Q4 2025\"\nIntegration Management\nDevOps engineers can:"},{"page":165,"heading":"Use Cases","anchor":"use-cases","text":"Test webhook endpoints\nMonitor API usage\nConfigure integrations\nTroubleshoot connectivity issues\nValidate configurations\nExample:\n\"Test the webhook subscription for license activation events and show me the last 5 events that were sent\""},{"page":165,"heading":"Getting Started","anchor":"getting-started","text":"To start using AI with Babel Licensing:\nSet up the MCP server\nFollow the MCP Server installation guide.\nConfigure your AI client\nConnect Claude Desktop or another MCP-compatible client.\nAsk the assistant\nAsk questions and request operations in plain language."},{"page":165,"heading":"Example Conversations","anchor":"example-conversations","text":"License Management\nYou: \"Show me all Ultimate licenses that will expire in the next 30 days\"\nAI:  \"I found 12 Ultimate licenses expiring in the next 30 days:\n\n      1. License ABC-123-XYZ (Customer: Acme Corp)\n         Expires: December 15, 2025\n      2. License DEF-456-UVW (Customer: TechStart Inc)\n         Expires: December 22, 2025\n      ...\n\n      Would you like me to send renewal reminders to these customers?\"\nCustomer Operations\nYou: \"Create a new customer called Innovation Labs, add their CTO\n      as the primary contact, and set up a webhook to notify us\n      when they activate licenses\"\n\nAI:  \"I've completed all three tasks:\n\n      ✓ Created customer 'Innovation Labs' (ID: 789)\n      ✓ Added CTO as primary contact\n      ✓ Set up webhook subscription for license activation events\n\n      The webhook will POST to your configured endpoint whenever\n      Innovation Labs activates a license.\"\nTroubleshooting"},{"page":165,"heading":"Example Conversations","anchor":"example-conversations","text":"You: \"Customer ID 456 is reporting license activation failures.\n      Check their recent activation attempts and system logs\"\n\nAI:  \"I've found the issue. Customer 456 (TechStart Inc) attempted\n      to activate license XYZ-789 3 times in the past hour, but all\n      failed because:\n\n      Error: Maximum activation count (5) exceeded\n\n      The license has already been activated on 5 different machines.\n      To resolve this, you can either:\n      1. Deactivate one of the existing activations\n      2. Increase the max activation count for this license\n      3. Issue a new license with a higher limit\n\n      Would you like me to show you the currently activated machines?\"\nAnalytics\nYou: \"Compare license activation rates between our Team\n      and Business editions over the last quarter\"\n\nAI:  \"Here's the comparison for Q4 2025:\n\n      Team Edition:\n      - Total licenses sold: 450\n      - Activated: 423 (94%)\n      - Average time to activation: 2.3 days\n\n      Business Edition:\n      - Total licenses sold: 180\n      - Activated: 175 (97%)\n      - Average time to activation: 1.1 days\n\n      Key insights:\n      - Business edition has higher activation rate (97% vs 94%)\n      - Business customers activate faster (1.1 vs 2.3 days)\n      - Both editions show strong activation rates above 90%\""},{"page":165,"heading":"Advanced Capabilities","anchor":"advanced-capabilities","text":"Batch Operations\nProcess multiple items efficiently:\nYou: \"Extend the expiration date by 90 days for all Ultimate\n      licenses owned by customer 789\"\nComplex Filtering\nUse sophisticated criteria without knowing the syntax:\nYou: \"Find all licenses that:\n      - Belong to customers whose name starts with 'Tech'\n      - Were created after January 1, 2025\n      - Are not revoked\n      - Have been activated at least once\"\nData Transformation\nGet data in the format you need:\nYou: \"Export all customer contact information to a CSV-like\n      format for import into our CRM\"\nProactive Monitoring\nSet up intelligent alerts:\nYou: \"Let me know about any license activation failures in\n      the past hour and suggest potential causes\""},{"page":165,"heading":"Security Considerations","anchor":"security-considerations","text":"When using AI integration:\nAPI Keys: Store your Babel Licensing API keys securely in environment variables\nAccess Control: Use API keys with appropriate permissions for the intended use case\nAudit Logs: Review MCP server logs regularly to monitor operations\nData Privacy: Be mindful of sensitive data in conversations with AI assistants\nSSL/TLS: Always use encrypted connections to your Babel Licensing service"},{"page":165,"heading":"Supported AI Clients","anchor":"supported-ai-clients","text":"The Babel Licensing MCP Server is compatible with:\nClaude Desktop - Anthropic's desktop application with native MCP support\nClaude.ai - Web-based access to Claude (via MCP proxy)\nCustom MCP Clients - Any client implementing the Model Context Protocol specification"},{"page":165,"heading":"Learn More","anchor":"learn-more","text":"MCP Server Setup Guide - Detailed installation and configuration\nModel Context Protocol - Learn about the MCP standard\nBabel Licensing API Reference - Complete API documentation\nClaude Desktop - Download Claude with MCP support"},{"page":165,"heading":"Support","anchor":"support","text":"Need help with AI integration?\nEmail: support@babelfor.net\nDocumentation: Babel Licensing Docs\nAPI Reference: Included with MCP server (babel-licensing-api.json)\nTransform how you interact with your licensing system. Start using AI to manage licenses, customers, and products with the power of natural language conversation."},{"page":166,"heading":"","anchor":"","text":"Babel Licensing MCP Server (Data Center)\nThe Babel Licensing MCP Server is a Python-based Model Context Protocol (MCP) server that exposes all Babel Licensing API functions as tools. This enables AI assistants like Claude to interact directly with your Babel Licensing system for license management, customer operations, product management, and more."},{"page":166,"heading":"What is MCP?","anchor":"what-is-mcp","text":"The Model Context Protocol (MCP) is an open standard that enables AI assistants to securely connect to external systems and data sources. MCP servers act as bridges between AI models and your business systems, allowing natural language interactions with APIs, databases, and tools."},{"page":166,"heading":"Features","anchor":"features","text":"Complete API Coverage: Exposes all 90+ Babel Licensing API endpoints as MCP tools\nType-Safe Configuration: Pydantic-based configuration with automatic validation\nAuthentication Support: Supports both API Key and Bearer Token authentication\nDaily Log Rotation: Automatic logging to logs/ directory with daily file rotation\nComprehensive Toolset: Includes tools for:\nAuthentication and user management\nLicense operations (activate, deactivate, validate, request, release)\nCustomer and contact management\nProduct and order management\nLicense templates and tokens\nWebhooks and event management\nReports and logging\nEmail notifications\nSystem settings and configuration"},{"page":166,"heading":"Requirements","anchor":"requirements","text":"Python 3.10 or higher\nBabel Licensing API access (base URL and credentials)\nAn MCP-compatible client (e.g., Claude Desktop)"},{"page":166,"heading":"Installation","anchor":"installation","text":"Quick Start\nmacOS / Linux\nExtract the archive and navigate to the directory:\nunzip babel-licensing-mcp-*.zip\ncd babel-licensing-mcp-*\nRun the setup script:\nchmod +x setup.sh\n./setup.sh\nConfigure your environment:\n# Edit .env file with your Babel Licensing API credentials\nnano .env\nWindows\nExtract the ZIP archive and navigate to the directory in PowerShell\nEnable PowerShell script execution (if needed):\nSet-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser\nRun the setup script:\n.\\setup.ps1\nConfigure your environment:\n# Edit .env file with your Babel Licensing API credentials\nnotepad .env"},{"page":166,"heading":"Manual Installation","anchor":"manual-installation","text":"Create a virtual environment\npython3 -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\nInstall dependencies\npip install -r requirements.txt\nConfigure environment variables\ncp .env.example .env\n# Edit .env with your actual credentials"},{"page":166,"heading":"Configuration","anchor":"configuration","text":"The server requires the following environment variables (configured in .env):\n# Babel Licensing API Base URL\nBABEL_API_BASE_URL=https://your-babel-licensing-server.com\n\n# Authentication - Use ONE of the following:\n# Option 1: API Key\nBABEL_API_KEY=your-api-key-here\n\n# Option 2: Bearer Token\n# BABEL_BEARER_TOKEN=your-bearer-token-here\n\n# Optional Configuration\n# BABEL_VERIFY_SSL=true           # Set to false for self-signed certificates\n# BABEL_TIMEOUT=30                # Request timeout in seconds\n# BABEL_CONTENT_TYPE=application/json  # Content type: application/json or application/toon\n# DEBUG=false                      # Enable debug logging\nContent Type Configuration\nThe server supports two content types for API requests:\napplication/json (default): Standard JSON format\napplication/toon: TOON format for specialized use cases\nTo use TOON format, set the BABEL_CONTENT_TYPE environment variable:\nBABEL_CONTENT_TYPE=application/toon\nThe client will automatically set the appropriate Content-Type and Accept headers for all API requests."},{"page":166,"heading":"Usage","anchor":"usage","text":"Running the MCP Server\nOption 1: Using the installed command\nbabel-licensing-mcp\nOption 2: Direct execution\npython src/server.py\nConfiguring with AI Clients\nThe Babel Licensing MCP Server can be used with any MCP-compatible AI client, including Claude Desktop and Claude Code.\nConfiguring with Claude Desktop\nAdd the following to your Claude Desktop configuration file:\nmacOS: ~/Library/Application Support/Claude/claude_desktop_config.json\nWindows: %APPDATA%\\Claude\\claude_desktop_config.json\nLinux: ~/.config/Claude/claude_desktop_config.json\nRecommended Configuration (Direct Path)\n{\n  \"mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/absolute/path/to/babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\n        \"/absolute/path/to/babel-licensing-mcp/src/server.py\"\n      ],\n      \"env\": {\n        \"BABEL_API_BASE_URL\": \"https://your-babel-server.com\",\n        \"BABEL_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\nExample with actual paths (macOS):\n{\n  \"mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/Users/username/Projects/babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\n        \"/Users/username/Projects/babel-licensing-mcp/src/server.py\"\n      ],\n      \"env\": {\n        \"BABEL_API_BASE_URL\": \"https://api.babel-licensing.com\",\n        \"BABEL_API_KEY\": \"abc123def456\"\n      }\n    }\n  }\n}\nExample with actual paths (Windows):"},{"page":166,"heading":"Usage","anchor":"usage","text":"{\n  \"mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"C:\\\\Users\\\\username\\\\Projects\\\\babel-licensing-mcp\\\\venv\\\\Scripts\\\\python.exe\",\n      \"args\": [\n        \"C:\\\\Users\\\\username\\\\Projects\\\\babel-licensing-mcp\\\\src\\\\server.py\"\n      ],\n      \"env\": {\n        \"BABEL_API_BASE_URL\": \"https://api.babel-licensing.com\",\n        \"BABEL_API_KEY\": \"abc123def456\"\n      }\n    }\n  }\n}\nNote: Replace /absolute/path/to/ with the actual path to your project directory. You can find it by running pwd (macOS/Linux) or cd (Windows) in the project folder.\nAlternative: Using .env file\nInstead of specifying environment variables in the Claude Desktop config, you can create a .env file in the project root:\n# Copy the example file\ncp .env.example .env\n\n# Edit with your credentials\nBABEL_API_BASE_URL=https://your-babel-server.com\nBABEL_API_KEY=your-api-key-here\nThen use a simpler Claude Desktop configuration:\n{\n  \"mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/absolute/path/to/babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\n        \"/absolute/path/to/babel-licensing-mcp/src/server.py\"\n      ]\n    }\n  }\n}\nAfter Configuration:\nCompletely quit and restart Claude Desktop\nStart a new conversation\nLook for the 🔨 tools icon indicating MCP servers are connected\nAsk Claude: \"What Babel Licensing tools do you have access to?\"\nConfiguring with Claude Code"},{"page":166,"heading":"Usage","anchor":"usage","text":"Claude Code is a VS Code extension that provides AI assistance directly in your development environment. To use the Babel Licensing MCP Server with Claude Code:\nStep 1: Install Claude Code\nInstall the Claude Code extension from the VS Code marketplace:\nOpen VS Code\nGo to Extensions (Cmd+Shift+X on macOS, Ctrl+Shift+X on Windows/Linux)\nSearch for \"Claude Code\"\nClick Install\nStep 2: Add MCP Server to Settings\nOpen your VS Code settings and add the MCP server configuration:\nOption A: Workspace Settings (recommended for project-specific usage)\nCreate or edit .vscode/settings.json in your workspace:\n{\n  \"claude.mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/absolute/path/to/babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\n        \"/absolute/path/to/babel-licensing-mcp/src/server.py\"\n      ],\n      \"env\": {\n        \"BABEL_API_BASE_URL\": \"https://licensing.example.com\",\n        \"BABEL_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\nOption B: User Settings (for global access across all workspaces)\nOpen Command Palette (Cmd+Shift+P on macOS, Ctrl+Shift+P on Windows/Linux)\nType \"Preferences: Open User Settings (JSON)\"\nAdd the claude.mcpServers configuration:"},{"page":166,"heading":"Usage","anchor":"usage","text":"{\n  \"claude.mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/Users/username/Projects/babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\n        \"/Users/username/Projects/babel-licensing-mcp/src/server.py\"\n      ],\n      \"env\": {\n        \"BABEL_API_BASE_URL\": \"https://licensing.example.com\",\n        \"BABEL_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\nStep 3: Using Environment Variables\nYou can reference environment variables in your configuration:\n{\n  \"claude.mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/path/to/babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\"/path/to/babel-licensing-mcp/src/server.py\"],\n      \"env\": {\n        \"BABEL_API_BASE_URL\": \"${env:BABEL_URL}\",\n        \"BABEL_API_KEY\": \"${env:BABEL_KEY}\"\n      }\n    }\n  }\n}\nThen set the environment variables in your shell before starting VS Code:\n# macOS/Linux\nexport BABEL_URL=\"https://licensing.example.com\"\nexport BABEL_KEY=\"your-api-key-here\"\ncode .\n\n# Windows PowerShell\n$env:BABEL_URL = \"https://licensing.example.com\"\n$env:BABEL_KEY = \"your-api-key-here\"\ncode .\nStep 4: Using .env File (simplest approach)\nConfigure the .env file in the MCP server directory with your credentials, then use a minimal configuration:\n{\n  \"claude.mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/path/to/babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\"/path/to/babel-licensing-mcp/src/server.py\"]\n    }\n  }\n}\nThe server will automatically load settings from the .env file."},{"page":166,"heading":"Usage","anchor":"usage","text":"Step 5: Platform-Specific Path Examples\nmacOS:\n{\n  \"claude.mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/Users/username/Projects/babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\n        \"/Users/username/Projects/babel-licensing-mcp/src/server.py\"\n      ]\n    }\n  }\n}\nWindows:\n{\n  \"claude.mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"C:\\\\Users\\\\username\\\\Projects\\\\babel-licensing-mcp\\\\venv\\\\Scripts\\\\python.exe\",\n      \"args\": [\n        \"C:\\\\Users\\\\username\\\\Projects\\\\babel-licensing-mcp\\\\src\\\\server.py\"\n      ]\n    }\n  }\n}\nLinux:\n{\n  \"claude.mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/home/username/projects/babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\n        \"/home/username/projects/babel-licensing-mcp/src/server.py\"\n      ]\n    }\n  }\n}\nStep 6: Using Relative Paths\nFor workspace-specific configurations, you can use VS Code variables:\n{\n  \"claude.mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"${workspaceFolder}/../babel-licensing-mcp/venv/bin/python\",\n      \"args\": [\n        \"${workspaceFolder}/../babel-licensing-mcp/src/server.py\"\n      ],\n      \"cwd\": \"${workspaceFolder}/../babel-licensing-mcp\"\n    }\n  }\n}\nThis is useful when the MCP server is in a sibling directory to your workspace.\nStep 7: Verify Installation\nAfter configuring, reload VS Code to activate the MCP server:\nOpen Command Palette (Cmd+Shift+P / Ctrl+Shift+P)\nType \"Developer: Reload Window\"\nPress Enter\nTo verify the server is working:"},{"page":166,"heading":"Usage","anchor":"usage","text":"Open the Claude panel in VS Code\nStart a new conversation\nAsk: \"What Babel Licensing capabilities do you have?\"\nClaude should list all 86 available tools\nClaude Code Usage Tips:\nContext-Aware Requests: Claude Code can see your current file and workspace, so you can ask:\n\"Based on this code, create a license for this customer\"\n\"Generate a license activation call for the product in this file\"\nCode Generation: Ask Claude to generate code that uses the Babel Licensing API:\n\"Write a C# method to activate a license using these parameters\"\n\"Create a Python script to query all active licenses\"\nInline Assistance: Select code and ask Claude to:\n\"Check if this license key is valid\"\n\"Find the customer associated with this user key\"\nMulti-File Operations: Claude can help coordinate licensing across multiple files:\n\"Update license keys in all configuration files\"\n\"Find all hardcoded license keys in this project\"\nTroubleshooting Claude Code:\nIf the MCP server doesn't connect:\nCheck Extension Status: Ensure Claude Code extension is activated\nVerify Python Path: Confirm the virtual environment path is correct\nCheck Logs: View Claude Code output in VS Code Output panel\nReload Window: Use \"Developer: Reload Window\" after config changes\nCheck Permissions: Ensure the Python executable has execute permissions\nMultiple Environment Setup:\nYou can configure different Babel Licensing environments:"},{"page":166,"heading":"Usage","anchor":"usage","text":"{\n  \"claude.mcpServers\": {\n    \"babel-licensing-prod\": {\n      \"command\": \"/path/to/venv/bin/python\",\n      \"args\": [\"/path/to/src/server.py\"],\n      \"env\": {\n        \"BABEL_API_BASE_URL\": \"https://licensing.production.com\",\n        \"BABEL_API_KEY\": \"${env:BABEL_PROD_KEY}\"\n      }\n    },\n    \"babel-licensing-dev\": {\n      \"command\": \"/path/to/venv/bin/python\",\n      \"args\": [\"/path/to/src/server.py\"],\n      \"env\": {\n        \"BABEL_API_BASE_URL\": \"https://licensing.dev.com\",\n        \"BABEL_API_KEY\": \"${env:BABEL_DEV_KEY}\"\n      }\n    }\n  }\n}\nThis allows you to switch between production and development environments when working with Claude."},{"page":166,"heading":"Logging","anchor":"logging","text":"The server automatically logs all operations to daily log files in the logs/ directory:\nLocation: logs/babel_licensing_YYYYMMDD.log\nFormat: Timestamped logs with level and module information\nRotation: Automatically creates a new file each day\nOutput: Logs are written to both file and console\nExample log file: logs/babel_licensing_20251111.log\n2025-11-11 10:30:15 - server - INFO - MCP server starting...\n2025-11-11 10:30:16 - server - INFO - Babel Licensing client initialized\n2025-11-11 10:31:22 - server - INFO - Tool called: babel_get_customers"},{"page":166,"heading":"Available Tools","anchor":"available-tools","text":"The server exposes 86 tools organized into the following categories:\nNote: Authentication is handled automatically via API Key or Bearer Token configured in environment variables. Interactive login tools are not required.\nLicensing Operations (7 tools)\nbabel_activate_license - Activate a license\nbabel_deactivate_license - Deactivate a license\nbabel_request_license - Request a license\nbabel_release_license - Release a license\nbabel_license_heartbeat - Send license heartbeat\nbabel_validate_license - Validate a license\nbabel_get_license_info - Get license information\nManagement\nAPI Keys (4 tools)\nbabel_get_api_keys - List API keys\nbabel_insert_api_key - Create new API key\nbabel_update_api_key - Update API key\nbabel_delete_api_key - Delete API key\nUsers (7 tools)\nbabel_get_users - List users\nbabel_insert_user - Create user\nbabel_update_user - Update user\nbabel_delete_user - Delete user\nbabel_get_user_roles - Get user roles\nbabel_add_user_to_roles - Add user to roles\nbabel_remove_user_from_roles - Remove user from roles\nCustomers (7 tools)\nbabel_get_customers - List customers\nbabel_insert_customer - Create customer\nbabel_update_customer - Update customer\nbabel_delete_customer - Delete customer\nbabel_get_customer_contacts - Get customer contacts\nbabel_get_customer_orders - Get customer orders\nbabel_get_customer_licenses - Get customer licenses\nProducts (15 tools)"},{"page":166,"heading":"Available Tools","anchor":"available-tools","text":"Product management (get, insert, update, delete)\nProduct releases management\nRelease assemblies management\nLicense templates for releases\nOrders (9 tools)\nOrder management (get, insert, update, delete)\nOrder products management\nOrder licenses retrieval\nLicenses (9 tools)\nLicense management (get, insert, update, delete)\nLicense tokens management\nLicense traces\nLicense templates\nWebhooks (9 tools)\nWebhook subscriptions management\nEvent types retrieval\nWebhook testing\nEvent management\nAdditional Management Tools\nAssemblies (4 tools)\nContacts (4 tools)\nResources (4 tools)\nReports (3 tools)\nLogging (3 tools)\nSettings (2 tools)\nEmail (2 tools)\nServer Info (1 tool)"},{"page":166,"heading":"Working with the API","anchor":"working-with-the-api","text":"Data Format for Insert/Update Operations\nWhen using tools that create or update resources (tools starting with babel_insert_ or babel_update_), the client automatically wraps your data in the appropriate request format required by the Babel Licensing API.\nYou only need to provide the raw data - the wrapping is handled automatically.\nExamples\nCreating a new customer:\n// You provide:\n{\n  \"customer_data\": {\n    \"name\": \"Acme Corporation\",\n    \"email\": \"contact@acme.com\"\n  }\n}\n\n// The client automatically wraps it as:\n{\n  \"customer\": {\n    \"name\": \"Acme Corporation\",\n    \"email\": \"contact@acme.com\"\n  }\n}\nCreating a new user:\n// You provide:\n{\n  \"user_data\": {\n    \"userName\": \"johndoe\",\n    \"email\": \"john@example.com\",\n    \"password\": \"SecureP@ssw0rd\"\n  }\n}\n\n// The client automatically wraps it as:\n{\n  \"user\": {\n    \"userName\": \"johndoe\",\n    \"email\": \"john@example.com\"\n  },\n  \"password\": \"SecureP@ssw0rd\"\n}\nUpdating a license:\n// You provide:\n{\n  \"license_data\": {\n    \"id\": 123,\n    \"revoked\": false,\n    \"description\": \"Updated description\"\n  }\n}\n\n// The client automatically wraps it as:\n{\n  \"license\": {\n    \"id\": 123,\n    \"revoked\": false,\n    \"description\": \"Updated description\"\n  }\n}\nQuery Parameters\nMany GET endpoints support the following query parameters:"},{"page":166,"heading":"Working with the API","anchor":"working-with-the-api","text":"select - Comma-separated list of field names to include in response\nfilter - Filtering criteria using .NET syntax (see Filter Syntax below)\ninclude - Comma-separated list of related objects to include (see Include Parameter below)\nsort - Field name with optional 'asc' or 'desc'\ntake - Pagination limit (page size)\nskip - Pagination offset\nInclude Parameter\nThe include parameter allows you to fetch related objects in a single request.\nIMPORTANT Rules:\nUse PascalCase names (capitalized): Customer, Order, Product (NOT customer, order, product)\nMUST add included objects to select - include them in both parameters\nMultiple objects: separate with comma without spaces\nExamples:\n// Correct - Get licenses with customer and order objects\n{\n  \"params\": {\n    \"select\": \"id,licenseId,licenseType,createdAt,customerId,orderId,Customer,Order\",  // \u0005 Include Customer,Order here\n    \"include\": \"Customer,Order\"  // \u0005 PascalCase, no spaces\n  }\n}\n\n// Wrong - lowercase names\n{\n  \"params\": {\n    \"select\": \"id,licenseId,customer,order\",  // L Lowercase\n    \"include\": \"customer,order\"  // L Will fail\n  }\n}\n\n// Wrong - missing from select\n{\n  \"params\": {\n    \"select\": \"id,licenseId,licenseType\",  // L Missing Customer,Order\n    \"include\": \"Customer,Order\"  // Objects won't be returned!\n  }\n}\nAvailable Include Options:"},{"page":166,"heading":"Working with the API","anchor":"working-with-the-api","text":"babel_get_licenses: Product, Order, Customer, Template, Licensee\nbabel_get_customers: Contacts, Orders, Licenses\nbabel_get_orders: Customer, Reseller, Products, Licenses\nbabel_get_products: Releases, Orders\nbabel_get_users: Roles, Settings, Customer\nbabel_get_api_keys: Owner\nbabel_get_all_license_tokens: License, NodeLockedLicense\nbabel_get_license_templates: Product\nFilter Syntax\nThe API uses .NET filter syntax, NOT OData standard.\nComparison Operators:\nOperator | Description | Example\n>= | Greater than or equal | createdAt >= \"2025-11-11T00:00:00\"\n<= | Less than or equal | expireDate <= \"2025-12-31T23:59:59\"\n> | Greater than | id > 100\n< | Less than | id < 1000\n== | Equal | revoked == false\n!= | Not equal | status != \"expired\"\nLogical Operators:\nOperator | Description | Example\n&& | Logical AND | revoked == false && expireDate >= \"2025-01-01\"\n|| | Logical OR | status == \"active\" || status == \"trial\"\n! | Negation (NOT) | !revoked or !licenseType.Contains(\"Trial\")\nString Functions:\nFunction | Description | Example\nContains() | Check if string contains substring | licenseType.Contains(\"Ultimate\")\nStartsWith() | Check if string starts with substring | userKey.StartsWith(\"ABC\")\nEndsWith() | Check if string ends with substring | licenseeEmail.EndsWith(\"@example.com\")\nComplex Filter Examples:"},{"page":166,"heading":"Working with the API","anchor":"working-with-the-api","text":"# Active licenses of Ultimate type created after Nov 11\nrevoked == false && licenseType.Contains(\"Ultimate\") && createdAt >= \"2025-11-11T00:00:00\"\n\n# Exclude Enterprise licenses\n!licenseType.Contains(\"Enterprise\")\n\n# User keys starting with ABC or XYZ\nuserKey.StartsWith(\"ABC\") || userKey.StartsWith(\"XYZ\")\n\n# Expired licenses excluding trial\nexpireDate < \"2025-01-01T00:00:00\" && !licenseType.Contains(\"Trial\")\nIMPORTANT: Do NOT use OData syntax (eq, ne, gt, lt, and, or). These will not work.\nSort Parameter:\nThe sort parameter accepts:\nField name with direction: createdAt desc (descending)\nField name with direction: createdAt asc (ascending)\nField name only: createdAt (defaults to ascending)\nComplete Example:\n{\n  \"params\": {\n    \"filter\": \"revoked == false && licenseType.Contains(\\\"Ultimate\\\") && expireDate >= \\\"2025-01-01T00:00:00\\\"\",\n    \"select\": \"id,licenseId,userKey,expireDate,licenseType\",\n    \"take\": 10,\n    \"skip\": 0,\n    \"sort\": \"createdAt desc\"\n  }\n}"},{"page":166,"heading":"Examples","anchor":"examples-1","text":"Activating a License\nAsk Claude:\n\"Activate a license with user key ABC-123-DEF, product code PROD001, and hardware ID HW-12345\"\nClaude will use the babel_activate_license tool:\n{\n  \"tool\": \"babel_activate_license\",\n  \"arguments\": {\n    \"license_data\": {\n      \"userKey\": \"ABC-123-DEF\",\n      \"productCode\": \"PROD001\",\n      \"hardwareId\": \"HW-12345\"\n    }\n  }\n}\nGetting Customers\nAsk Claude:\n\"Show me the first 10 reseller customers, sorted by company name\"\nClaude will use the babel_get_customers tool:\n{\n  \"tool\": \"babel_get_customers\",\n  \"arguments\": {\n    \"params\": {\n      \"filter\": \"isReseller == true\",\n      \"take\": 10,\n      \"sort\": \"company asc\"\n    }\n  }\n}\nCreating a Webhook Subscription\nAsk Claude:\n\"Create a webhook subscription for license activation and deactivation events pointing to https://example.com/webhook\"\nClaude will use the babel_create_webhook_subscription tool:\n{\n  \"tool\": \"babel_create_webhook_subscription\",\n  \"arguments\": {\n    \"subscription_data\": {\n      \"url\": \"https://example.com/webhook\",\n      \"events\": [\"license.activated\", \"license.deactivated\"],\n      \"isActive\": true\n    }\n  }\n}\nComplex Query Example\nAsk Claude:\n\"Show me all Ultimate licenses created after November 11, 2025 that are not revoked, including customer and order details, sorted by creation date\"\nClaude will construct a query like:"},{"page":166,"heading":"Examples","anchor":"examples-1","text":"{\n  \"tool\": \"babel_get_licenses\",\n  \"arguments\": {\n    \"params\": {\n      \"filter\": \"revoked == false && licenseType.Contains(\\\"Ultimate\\\") && createdAt >= \\\"2025-11-11T00:00:00\\\"\",\n      \"select\": \"id,licenseId,userKey,expireDate,licenseType,createdAt,Customer,Order\",\n      \"include\": \"Customer,Order\",\n      \"sort\": \"createdAt desc\"\n    }\n  }\n}"},{"page":166,"heading":"Troubleshooting","anchor":"troubleshooting","text":"Connection Issues\nVerify your BABEL_API_BASE_URL is correct\nEnsure your API key or bearer token is valid\nCheck network connectivity to the Babel Licensing server\nReview server logs in the logs/ directory for detailed error messages\nSSL Certificate Issues\nIf you encounter SSL certificate verification errors (especially with self-signed certificates):\nSet BABEL_VERIFY_SSL=false in your .env file or environment configuration\nFor Claude Desktop, add it to the env section:\n{\n  \"mcpServers\": {\n    \"babel-licensing\": {\n      \"command\": \"/path/to/venv/bin/python\",\n      \"args\": [\"/path/to/src/server.py\"],\n      \"env\": {\n        \"BABEL_API_BASE_URL\": \"https://your-server.com\",\n        \"BABEL_API_KEY\": \"your-key\",\n        \"BABEL_VERIFY_SSL\": \"false\"\n      }\n    }\n  }\n}\nSecurity Note: Only disable SSL verification for trusted internal servers with self-signed certificates. Never disable it for production systems or public APIs.\nAuthentication Errors\nMake sure you're using only ONE authentication method (API key OR bearer token)\nVerify your credentials are not expired\nCheck that your API key has the necessary permissions\nTool Execution Errors\nCheck the input schema for the tool you're using\nEnsure all required parameters are provided\nVerify parameter types match the schema\nReview the API response for specific error messages\nToken Saturation with babel_get_logs"},{"page":166,"heading":"Troubleshooting","anchor":"troubleshooting","text":"The babel_get_logs tool can return very large amounts of data, especially when including the exception and properties fields. This can saturate the available AI tokens in the conversation.\nField Selection Guidelines:\nexception and properties: Can contain very large amounts of data - avoid when requesting many records\nmessageTemplate: Not strictly necessary as it only contains the formatting template; the actual informative content is in message\nRecommended fields: id, message, level, timeStamp\nBest Practices:\nLimit the fields in select: Avoid including exception, properties, and messageTemplate unless specifically needed\n# Good - excludes large/unnecessary fields\n{\n  \"params\": {\n    \"select\": \"id,message,level,timeStamp\",\n    \"take\": 50\n  }\n}\n\n# Risky - includes large fields\n{\n  \"params\": {\n    \"select\": \"id,message,level,timeStamp,exception,properties\",\n    \"take\": 50  # May saturate tokens\n  }\n}\nUse pagination wisely: When including exception or properties, use small take values (10-20 records max)\nFilter before fetching: Use the filter parameter to reduce the number of records before retrieving them"},{"page":166,"heading":"API Documentation","anchor":"api-documentation","text":"For detailed information about the Babel Licensing API endpoints, parameters, and responses, refer to the babel-licensing-api.json OpenAPI specification file included in the MCP server package."},{"page":166,"heading":"Support","anchor":"support","text":"For issues or questions, contact: support@babelfor.net"},{"page":166,"heading":"Resources","anchor":"resources","text":"Model Context Protocol Documentation\nClaude Desktop\nBabel Licensing Documentation\nBabel Licensing API Reference"},{"page":166,"heading":"Version History","anchor":"version-history","text":"0.1.0 (Initial Release)\nComplete implementation of all Babel Licensing API endpoints\nSupport for authentication, licensing operations, and management functions\nComprehensive test suite\nFull documentation"},{"page":167,"heading":"","anchor":"","text":"A collection of practical use cases and examples that will guide you in\nstraightforwardly integrating Babel Licensing functionalities into your applications."},{"page":167,"heading":"License Files And Serials","anchor":"license-files-and-serials","text":"These examples demonstrate how to implement various licensing strategies using Babel Licensing, from trial licenses to sophisticated feature-based and device-bound licensing systems.\nTrial Serial License: Validating Serial with Trial Days and Code Encryption.\nFeature Based Licenses: Use code encryption passwords to realize feature based licenses.\nLicense Activation in MAUI: Showcase License Activation and Exception Reporting in MAUI Application."},{"page":167,"heading":"Licensing with Code Encryption","anchor":"licensing-with-code-encryption","text":"These examples pair Babel Licensing with Babel Obfuscator Code Encryption. The password that unlocks the encrypted code lives inside the license, so a protected feature becomes cryptographically — not just conditionally — dependent on a valid license.\nLicense-Bound Code Encryption: The code-encryption password lives in a signed, hardware-locked license, not in the binary.\nExternal Encrypted Code: Deliver a premium feature as an external .eil file unlocked by a license.\nSubscription License: Time-limited license with a grace period gating code-encrypted pro features."},{"page":168,"heading":"","anchor":"","text":"Trial licenses allow software vendors to offer time-limited trial versions of their applications to potential customers.\nIn this article, we will explore the concept of Trial Serial Licenses and demonstrate its implementation through a sample console application. The provided code showcases how to create a trial license that expires after a certain number of days and limits the number of runs allowed. Additionally, it demonstrates the usage of encryption techniques to protect sensitive code that is only executed if the license is valid. By understanding the Trial Serial License model and examining the accompanying code, developers can gain valuable insights into leveraging Babel Licensing for implementing trial versions of their software products."},{"page":168,"heading":"Code Example","anchor":"code-example","text":"To access the code for the TrialLicense project and explore it further, you can clone the repository from GitHub using the following command:\ngit clone https://github.com/babelfornet/trial-license-string-console-example.git\nThe TrialLicense project demonstrates how to implement a trial license system using Babel Licensing within a console application. This sample project is compatible with Windows, Linux, and macOS. By cloning the repository, you will have access to the complete source code, allowing you to delve into the implementation details, examine the different components, and explore the functionalities of the trial licensing system.\nThe project utilizes the Babel Obfuscator NuGet package to obfuscate and encrypt the code during the build process.\nTo activate the Babel Obfuscator, set the environment variable BABEL_LICENSE to the path of the license file, or the floating license key.\nThe encrypted code can only be executed with a valid serial key that contains the decryption password.\nTrial License Example\nTo start the application, open a Shell window, navigate to the project's Debug folder, and then run the command TrialLicense by pressing ENTER. This will execute the application."},{"page":168,"heading":"Trial License Generation","anchor":"trial-license-generation","text":"The following code is responsible for generating a trial license serial:\nstring hardwareKey = HardwareId.Create().ToMachineKey();\n\nvar sign = (RSASignature)Pem.ReadSignature(\"Keys.pem\");\n\nvar lic = new StringLicense()       // Create a new string license\n   .ForAssembly(Assembly.GetExecutingAssembly()) // The license is for this assembly\n   .WithUniqueId()                 // Unique ID for the license\n   .WithHardwareKey(hardwareKey)   // Lock to the current machine\n   .WithTrialDays(2)               // Give 2 days trial\n   .WithMaximumRunCount(3)         // Allow 3 runs\n   .WithField(\"source1\", \"p@ssw0rd1\".Encrypt(\"!sEcr3tp@sswOrD!\"))  // Set the encrypted code password            \n   .SignWith(sign);                // Sign the license with the private key\n\n// Convert the license object to an ASCII string\nstring serial = lic.ToReadableString(\"ASCII\");\nHere's a breakdown of its functionality:"},{"page":168,"heading":"Trial License Generation","anchor":"trial-license-generation","text":"HardwareId.Create().ToMachineKey() generates a hardware-specific key that uniquely identifies the current machine. This key is used to lock the trial license to the current machine.\n(RSASignature)Pem.ReadSignature(\"Keys.pem\") reads the RSA private key from the \"Keys.pem\" file. This key is used to sign the license and validate its authenticity.\nnew StringLicense() creates a new instance of the StringLicense class, representing the trial license.\n.ForAssembly(Assembly.GetExecutingAssembly()) specifies that the license is associated with the current assembly.\n.WithUniqueId() generates a unique identifier for the license.\n.WithHardwareKey(hardwareKey) locks the license to the current machine by associating it with the hardware key generated at point 1.\n.WithTrialDays(2) sets the trial period to 2 days, indicating that the license will expire after this duration.\n.WithMaximumRunCount(3) sets the maximum number of runs allowed for the trial version.\n.WithField(\"source1\", \"p@ssw0rd1\".Encrypt(\"!sEcr3tp@sswOrD!\")) adds a field named \"source1\" to the license and sets its value to an encrypted password. This password will be used to decrypt specific code execution when the license is valid.\n.SignWith(sign) signs the license with the RSA private key obtained in step 2, ensuring its integrity and authenticity.\nlic.ToReadableString(\"ASCII\") converts the license object into an ASCII string representation."},{"page":168,"heading":"Trial License Generation","anchor":"trial-license-generation","text":"The resulting license serial is stored inside the registry, along with the public key used for validation.\nThis code demonstrates the process of generating a trial license serial, including securing it with encryption and storing it in the registry. The trial license can be validated using the corresponding public key to ensure its authenticity and enforce trial restrictions, such as trial duration and run limits."},{"page":168,"heading":"Trial License Validation","anchor":"trial-license-validation","text":"The following code snippet demonstrates a practical implementation of this process. It utilizes Babel Licensing to perform the trial serial validation.\nvar store = new LicenseStore();\nstore.Load();\nif (store.Serial == null)\n{\n    Console.WriteLine(\"No serial found\");\n    return;\n}\n\n// Get the public key from the key to validate the license signature\nstring publicKey = Convert.ToString(store.Key).Decrypt(\"pk_p@sswOrd\");\n\nvar manager = new StringLicenseManager();\n\n// The public key is used to validate the license signature\nmanager.SignatureProvider = RSASignature.FromKeys(publicKey);\n\n// Validate the serial\n// A license object is returned if the serial is valid and all license restrictions are met\nBabel.Licensing.ILicense license = manager.Validate(store.Serial);\n\nConsole.WriteLine(\"Serial {0} is valid\", license.Id);\nvar trial = license.Restrictions.OfType<TrialRestriction>().FirstOrDefault();\n\nif (trial != null)\n{\n    Console.WriteLine(\"Trial time left: {0}\", trial.TimeLeft);\n    Console.WriteLine(\"Runs left: {0}\", trial.RunCountLeft);\n}\nHere, the public key used to validate the license signature is retrieved from the license file information. The value associated with the \"Key\" key is obtained, and the \"pk_p@sswOrd\" decryption password is used to decrypt the stored value."},{"page":168,"heading":"Trial License Validation","anchor":"trial-license-validation","text":"An instance of the StringLicenseManager class is created to manage the license validation process. The SignatureProvider property of the manager is set to an RSASignature object created from the retrieved public key. This sets up the manager to use the public key for validating the license signature.\nBabel.Licensing.ILicense license = manager.Validate(serial);\nThe manager.Validate(serial) method is called to validate the license. The license serial stored in the serial variable is passed as an argument. If the serial is valid and meets all the license restrictions, a license object implementing the Babel.Licensing.ILicense interface is returned. It represents the validated license.\nFinally, the remaining trial time and the number of runs left are then printed to the console.\nOverall, this code validates a license serial by retrieving the serial and public key from the registry, configuring the license manager with the public key, and calling the validation method. It then displays the validation result and any relevant license information, such as trial time and run count, if applicable."},{"page":168,"heading":"Execution of Encrypted Code","anchor":"execution-of-encrypted-code","text":"The provided code segment showcases the execution of encrypted code and how it can be retrieved using Babel Obfuscator. Let's examine how this code operates:\nFirstly, there are two methods involved:\n[Obfuscation(Feature = \"msil encryption get password\", Exclude = false)]\ninternal static string GetEncryptedCodePassword(string source)\n{\n    return EncryptedGetEncryptedCodePassword(source);\n}\n\n[Obfuscation(Feature = \"msil encryption\", Exclude = false)]\nprivate static string EncryptedGetEncryptedCodePassword(string source)\n{\n    var store = new LicenseStore();\n    store.Load();\n\n    if (store.Serial == null)\n    {\n        throw new Exception(\"No serial found\");\n    }\n\n    // Get the public key from the key to validate the license signature\n    string publicKey = Convert.ToString(store.Key).Decrypt(\"pk_p@sswOrd\");\n\n    var manager = new StringLicenseManager();\n\n    // The public key is used to validate the license signature\n    manager.SignatureProvider = RSASignature.FromKeys(publicKey);\n\n    // Validate the serial\n    // A license object is returned if the serial is valid and all license restrictions are met\n    Babel.Licensing.ILicense license = manager.Validate(store.Serial);\n\n    // Reuse the same secret used to decrypt the code password\n    return license.Fields.First(item => item.Name == source).Value.Decrypt(\"!sEcr3tp@sswOrD!\");\n}"},{"page":168,"heading":"Execution of Encrypted Code","anchor":"execution-of-encrypted-code","text":"The GetEncryptedCodePassword method serves as an entry point to retrieve the encrypted code password. It calls the EncryptedGetEncryptedCodePassword method, passing a source value as a parameter. The purpose of this method is to extract the encrypted code password associated with the provided source from the license. Please refer to Babel Obfuscator Code Encryption to learn more about encrypted code with a password.\nInside EncryptedGetEncryptedCodePassword, the following steps occur:\nThe code retrieves the license serial and the corresponding public key from the license file.\nThe public key is decrypted using the password \"pk_p@sswOrd\".\nA StringLicenseManager instance is created to validate the license using the decrypted public key.\nThe license is validated by passing the serial to the Validate method of the manager.\nIf the serial is valid and meets all license restrictions, a license object is returned.\nThe encrypted code password associated with the specified source is retrieved from the license fields.\nFinally, the encrypted password is decrypted using the secret \"!sEcr3tp@sswOrD!\" and returned.\nFurthermore, Babel Obfuscator is used to obfuscate and encrypt the code. The obfuscation features used are:\nFor the ExecuteEncryptedCode method:\n[Obfuscation(Feature = \"msil encryption:source=source1;password=p@ssw0rd1;internal=true\", Exclude = false)]\nprivate void ExecuteEncryptedCode()\n{\n    Console.WriteLine(\"Encrypted code running\");\n}"},{"page":168,"heading":"Execution of Encrypted Code","anchor":"execution-of-encrypted-code","text":"The msil encryption feature is applied with the specified source (\"source1\"), encryption password (\"p@ssw0rd1\"), and internal set to true. This obfuscation ensures that the code within this method is encrypted and protected.\nBy combining these components, the encrypted code password can be retrieved from the license using Babel Obfuscator. The validated password allows for the decryption and execution of the encrypted code within the ExecuteEncryptedCode method, providing a secure and controlled execution environment for sensitive code sections."},{"page":169,"heading":"","anchor":"","text":"Babel Obfuscator includes a licensing feature that allows you to generate feature-based licenses for your obfuscated code. This means that you can create licenses that unlock specific features or functionality within your application based on the license key that is provided.\nOne way to implement this is by using code encryption in combination with Babel Licensing. You can use Babel Obfuscator to encrypt your code and then generate a license key that unlocks specific encrypted sections of the code. This way, you can provide different license levels or feature sets based on the user's needs.\nFor example, suppose you have an application with three levels of functionality: Standard, Professional and Enterprise. You can use Babel Obfuscator to encrypt the Enterprise features of the application and then generate a license key that unlocks those features. You can then provide different license keys to users based on their subscription level, with each key unlocking the appropriate set of features.\nTo implement this, you would use Babel Licensing to generate the license keys and verify them at runtime. When the user enters a license key, your application uses Babel Licensing to validate the key and determine which features should be unlocked. The encrypted sections of the code would then be decrypted and made available to the user.\nThe source code of the example that demonstrates feature-based licensing with code encryption is available on GitHub"},{"page":169,"heading":"","anchor":"","text":"git clone https://github.com/babelfornet/license-features-example.git\nThe example references the Babel Licensing NuGet package to use its features. The example code will include an implementation of the LicenseManager class, which provides methods for checking the validity of a license and the presence of specific features."},{"page":169,"heading":"","anchor":"","text":"public ILicense ValidateLicense()\n{\n   // To validate the license, only the public key is required.\n   // The private key is only used to sign the license, and in production the private key\n   // should not be distributed with the application.\n   // The public key should be distributed with the application and used to validate the license.\n\n   // The following signature provider can be used to create and validate the license\n   // as includes both the private key and the public key.\n   var signature = CreateSignature();\n\n   // The public key string can be embedded into the application and used to create a signature\n   // provider used only to validate the license.\n   string publicKey = signature.ExportKeys(publicKeyOnly: true);\n\n   // To create the RSASignature from the public key use the following code\n   var validatingSignature = RSASignature.FromKeys(publicKey);\n\n   // And assign the validating signature provider to the license manager\n   var licenseManager = new XmlLicenseManager();\n   licenseManager.SignatureProvider = validatingSignature;\n\n   license = licenseManager.Validate(File.ReadAllText(LicenseFileName), typeof(LicenseManager), this);\n   return license;\n}\nThe example will also include the code to generate an XML license file that specifies the license information, such as the expiration date, licensed features, and product information."},{"page":169,"heading":"","anchor":"","text":"Warning: Note that the code made available in the example to generate the license is only for demonstration purposes and must not be included in production.\nCode encryption can be used to protect the code that makes up the features of a software application from being used without the proper license file. This can be achieved by encrypting the code that implements a particular feature and requiring a password to decrypt and execute the code.\n[Obfuscation(Feature = \"msil encryption:internal=true;source=feature1;cache=false;password=aR&tj4i7u@\", Exclude = false)]\ninternal class Feature1\n{\n   public Feature1() { }\n\n   public string DoTask()\n   {\n      return \"Feature1: \" + Add(7, 8);\n   }\n\n   public int Add(int a, int b) => a + b;\n}\nThe password can be obtained from a license file that is generated based on the features that the user has licensed.\nBabel Obfuscator uses the Obfuscation attribute to mark the code that makes up the feature to be protected and specifies the method that should be called at runtime to retrieve the password needed to decrypt and execute the protected code. This method is typically a small function that retrieves the password from a license file or a licensing server. The password is then used by Babel Obfuscator to decrypt the protected code during runtime, ensuring that only licensed users can access the feature."},{"page":169,"heading":"","anchor":"","text":"[Obfuscation(Feature = \"msil encryption get password\")]\ninternal static string GetSourcePassword(string source)\n{\n   var lm = LicenseManager.Instance;\n\n   var feature = lm.License.Features.FirstOrDefault(item => item.Name == source);\n   if (feature == null)\n      throw new ApplicationException(source + \" not found\");\n\n   return Encoding.UTF8.GetString(feature.Data);\n}\nOnce the example is compiled, run the obfuscation project Obfuscate.babel in Babel Desktop or from the command line with babel --project Obfuscate.babel to protect the application features with Code Encryption.\nThe obfuscation statistics report the methods encrypted for each feature source, such as feature1. In Babel Desktop, the Code Encryption statistics list every encrypted method with its source.\nYou can start the protected application and generate a license for the three different application editions provided: Standard, Professional and Enterprise. Each edition unlocks an incremental number of features, meaning that the higher the edition you license, the more features you will be able to use within the application. So, generating a license for the Enterprise edition will unlock all the features, while generating a license for the Standard edition will only unlock a subset of the features.\nLicensed Features"},{"page":169,"heading":"","anchor":"","text":"The LicenseManager class will check for a valid license and the presence of the requested features. If the license is valid and the features are enabled, the application will allow the user to access those features.\nOverall, using code encryption with Babel Licensing can provide a powerful way to create flexible and feature-rich applications while still protecting your code from reverse engineering and piracy."},{"page":170,"heading":"","anchor":"","text":"Make a protected feature cryptographically dependent on a valid license by storing the\ncode-encryption password inside the license itself.\nA boolean license check — if (!IsLicensed) return; — is easy to patch out. This example\nshows a stronger pattern: the sensitive method is encrypted with Babel Obfuscator\nCode Encryption, and the password that the Babel Virtual\nMachine (BVM) needs to run it is not in the binary at all. It lives, itself encrypted, inside a\nsigned and hardware-locked Babel license. Removing the license check is not enough — without a\nvalid license there is no password, and without the password the encrypted method cannot be\nreconstructed or executed."},{"page":170,"heading":"Code Example","anchor":"code-example","text":"git clone https://github.com/babelfornet/license-bound-encryption-console-example.git\nThe project is a cross-platform .NET console application with two parts: SecureApp, the\nlicensed application whose sensitive method is code-encrypted, and LicenseGenerator, a\nvendor-side tool that mints signed licenses. The Babel package version is centralized in\nDirectory.Build.props so the sample can target the version that matches your feed."},{"page":170,"heading":"The Protected Method","anchor":"the-protected-method","text":"The intellectual property to protect is a single method. The [Obfuscation] attribute tells\nBabel to encrypt its body and store it inside the assembly (internal=true) under the source\nname core, using a build-time password:\n[Obfuscation(Feature = \"msil encryption:internal=true;source=core;password=C0re-Pr0tect!on-K3y\", Exclude = false)]\npublic static long Compute(int a, int b)\n{\n    long acc = 0;\n    for (int i = 1; i <= b; i++)\n        acc += (long)a * i;\n    return acc + 42;\n}\nCode Encryption is enabled in the Release build only, scoped to the sensitive class through an\nMSBuild property in SecureApp.csproj:\n<PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\n  <MsilEncryption Condition=\"'$(MsilEncryption)' == ''\">SecureApp\\.Secret::.*</MsilEncryption>\n  <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>\n</PropertyGroup>\nInfo: Code Encryption runs only in the Release configuration. The BabelWarningsAsErrors line turns\nthe evaluation-mode warning W00000 into an error, so an unprotected assembly can never ship\nby accident."},{"page":170,"heading":"Where the Password Lives","anchor":"where-the-password-lives","text":"At build time the method is encrypted with the password C0re-Pr0tect!on-K3y. At runtime the\nBVM asks the application for that password through a get password hook before it can run the\nmethod. Instead of returning a hard-coded value, the hook validates the license and reads the\npassword from it:\n[Obfuscation(Feature = \"msil encryption get password\")]\ninternal static string GetSourcePassword(string source)\n{\n    var license = Validate();\n\n    // The code password is carried by the license as an encrypted field.\n    var field = license.Fields.FirstOrDefault(f => f.Name == source)\n        ?? throw new InvalidOperationException($\"License does not grant source '{source}'.\");\n\n    // Decrypt the field with the vendor secret to recover the real code password.\n    return field.Value.Decrypt(Secrets.FieldSecret);\n}\nValidate() uses the embedded RSA public key to verify the license signature and enforces\nevery restriction, including the hardware lock:\npublic static ILicense Validate()\n{\n    var manager = new StringLicenseManager\n    {\n        SignatureProvider = RSASignature.FromKeys(PublicKey)\n    };\n    return manager.Validate(File.ReadAllText(LicenseFilePath), typeof(Program));\n}"},{"page":170,"heading":"Minting the License","anchor":"minting-the-license","text":"The vendor-side LicenseGenerator signs a license that binds to the SecureApp assembly and to\nthe current machine, and carries the code password as an encrypted field. The password\ntherefore never appears in clear — not in the binary, and not even in the license file:\nstring encryptedPassword = Secrets.CodePassword.Encrypt(Secrets.FieldSecret);\n\nvar license = new StringLicense()\n    .ForAssembly(assemblyFullName)\n    .WithUniqueId(\"SECURE-\")\n    .WithHardwareKey(HardwareId.Create().ToMachineKey())\n    .WithField(Secrets.Source, encryptedPassword)\n    .LicensedTo(\"Demo Customer\", \"demo@example.com\", \"ACME Corp\");\n\nstring serial = license.SignWith(signature).ToReadableString(\"ASCII\");\nWarning: The LicenseGenerator and the RSA private key (keys.pem) are for demonstration only. In\nproduction the license is issued by the vendor — or by the\nBabel Licensing Service — and the private key is kept\noffline. Only the public key ships with the application."},{"page":170,"heading":"Running It","anchor":"running-it","text":"# Build the app in Release — this is when Babel encrypts Secret.Compute.\ndotnet build src/SecureApp/SecureApp.csproj -c Release\n\n# Generate a signed, machine-locked license.\ndotnet run --project src/LicenseGenerator\n\n# Deploy the license next to the app and run it.\ncp SecureApp.lic src/SecureApp/bin/Release/net8.0/\ndotnet src/SecureApp/bin/Release/net8.0/SecureApp.dll\nWith a valid license the protected method runs:\nLicense OK      : SECURE-8CCC8\nLicensed to     : Demo Customer\nBound to machine: ADSQH-89GGJ-J7CJY-3FQFK-DF48H\n\nProtected computation Secret.Compute(7, 5) = 147\nThe encrypted method ran: the license unlocked the code.\nRemove or tamper with SecureApp.lic, or run it on a different machine, and the outcome is not\njust a friendlier error message — the encrypted code physically cannot run:\nLicense INVALID : Invalid license signature\nProtected computation blocked: Invalid license signature\nWithout a valid license the encrypted code cannot be decrypted or executed."},{"page":170,"heading":"Why This Is Stronger","anchor":"why-this-is-stronger","text":"Because the password is derived from a signed license, an attacker who strips the validation\ncode out of the assembly gains nothing: the BVM still has no password for the core source, so\nSecret.Compute remains an opaque, encrypted blob. The signature prevents forging a license,\nand the hardware lock prevents reusing a legitimate one on another machine. This same technique\nunderpins the Feature Based Licenses example and\nthe vendor-hosted License Templates, where the encrypted field\nis delivered by the Babel Licensing Service instead of a local generator."},{"page":171,"heading":"","anchor":"","text":"Ship a premium feature as encrypted code that lives outside the application and is unlocked\nonly when the customer also holds a license that grants it.\nBabel Obfuscator can strip the encrypted body of a method into a separate binary file with the\n.eil extension instead of embedding it in the assembly (see\nExternal Code Files). That file can be\ndeployed independently — for example, delivered together with a license the moment a customer\nupgrades. This example combines the two: the premium code is an external .eil file, and both\nthe file and a valid Babel license granting the feature are required to run it."},{"page":171,"heading":"Code Example","anchor":"code-example","text":"git clone https://github.com/babelfornet/external-encrypted-code-console-example.git\nReportTool is a console application with a free Standard report and a Premium analysis. The\nPremium code is encrypted into premium.eil; LicenseGenerator mints either a Standard or a\nPremium license."},{"page":171,"heading":"External Encryption","anchor":"external-encryption","text":"The premium method sets a source but not internal, so Babel writes its encrypted body to\nan external premium.eil file:\n[Obfuscation(Feature = \"msil encryption:source=premium;password=Pr3m!um-R3port-K3y\", Exclude = false)]\npublic static string Analyze(int[] data)\n{\n    double mean = data.Average();\n    double variance = data.Select(x => (x - mean) * (x - mean)).Sum() / data.Length;\n    return $\"Premium analysis: mean={mean:0.00}, variance={variance:0.00}, stddev={Math.Sqrt(variance):0.00}\";\n}\nBabel emits premium.eil next to the intermediate assembly. A short MSBuild target copies it to\nthe output folder so it can be deployed with — or deliberately withheld from — the application:\n<Target Name=\"CopyBabelExternalFiles\" AfterTargets=\"Build\">\n  <ItemGroup>\n    <BabelEilFiles Include=\"$(IntermediateOutputPath)*.eil\" />\n  </ItemGroup>\n  <Copy SourceFiles=\"@(BabelEilFiles)\" DestinationFolder=\"$(OutDir)\"\n        SkipUnchangedFiles=\"false\" Condition=\"'@(BabelEilFiles)' != ''\" />\n</Target>"},{"page":171,"heading":"Two License-Gated Hooks","anchor":"two-license-gated-hooks","text":"For external code the BVM calls two hooks: one to obtain the encrypted stream, and one for the\npassword. This example gates both on a valid license, so neither the file alone nor the\nlicense alone is sufficient:\n// Returns the .eil stream only when a valid license grants the feature.\n[Obfuscation(Feature = \"msil encryption get stream\")]\ninternal static Stream? GetSourceStream(string source)\n{\n    if (!HasFeature(source))\n        return null;                       // Not licensed for this feature.\n\n    var path = Path.Combine(FeaturesDirectory, source + \".eil\");\n    return File.Exists(path) ? File.OpenRead(path) : null;   // Feature file not delivered.\n}\n\n// Returns the password carried by the license.\n[Obfuscation(Feature = \"msil encryption get password\")]\ninternal static string GetSourcePassword(string source)\n{\n    var license = Validate();\n    var field = license.Fields.FirstOrDefault(f => f.Name == source)\n        ?? throw new InvalidOperationException($\"License does not grant source '{source}'.\");\n    return field.Value.Decrypt(Secrets.FieldSecret);\n}\nHasFeature returns true only when the validated license carries a field with the feature\nname, which the generator adds for a Premium license:\nif (premium)\n{\n    string encrypted = Secrets.PremiumPassword.Encrypt(Secrets.FieldSecret);\n    builder = builder.WithField(Secrets.PremiumSource, encrypted);\n}"},{"page":171,"heading":"Running It","anchor":"running-it","text":"# Build in Release — Babel encrypts Premium.Analyze into premium.eil.\ndotnet build src/ReportTool/ReportTool.csproj -c Release\n\n# Mint a Premium license (add --standard for a Standard one).\ndotnet run --project src/LicenseGenerator\n\n# Deliver BOTH the license and the external code, then run.\ncp ReportTool.lic src/ReportTool/bin/Release/net8.0/\ndotnet src/ReportTool/bin/Release/net8.0/ReportTool.dll\nThe four combinations make the two-factor gate visible:\nLicense | premium.eil delivered | Result\nStandard | no | Premium blocked\nPremium | no | Premium blocked — feature not delivered\nStandard | yes | Premium blocked — not licensed\nPremium | yes | Premium analysis runs\nWhen either factor is missing, the BVM reports no code source premium stream and the Standard\nreport keeps working on its own.\nInfo: Delivering protected code as a separate file is a natural fit for feature-based and add-on\nlicensing: the base application is one download, and each paid feature is a small .eil file\nshipped alongside the license that unlocks it. The vendor can revoke a feature by simply not\nrenewing the license that grants it.\nWarning: keys.pem and the passwords in the sample are for demonstration only. In production the license\nis issued by the vendor or the Babel Licensing Service,\nand the RSA private key is kept offline."},{"page":172,"heading":"","anchor":"","text":"A time-limited subscription license with a grace period, where the subscription-only code is\nprotected with Babel Obfuscator Code Encryption.\nSubscriptions need two behaviors that a plain expiry date does not give you: a grace period\nso paying customers are not cut off the instant a renewal is late, and enforcement that cannot\nbe bypassed by editing a config file. This example does both, and ties the premium (\"pro\")\nfunctionality to the subscription with Code Encryption: the pro\nmethod only runs while the subscription — including its grace window — is valid, because the\nBabel Virtual Machine gets its decryption password from the license."},{"page":172,"heading":"Code Example","anchor":"code-example","text":"git clone https://github.com/babelfornet/subscription-license-console-example.git\nProSuite is a console application with a free basic feature and an encrypted pro feature;\nLicenseGenerator mints subscription licenses with configurable duration and grace."},{"page":172,"heading":"Two Dates: Renewal and Hard Cutoff","anchor":"two-dates-renewal-and-hard-cutoff","text":"The license carries two dates:\nthe engine-enforced ExpireDate, set to the end of the grace period (the hard cutoff), and\na soft subscription-end field marking when renewal is due.\nDateTime subscriptionEnd = now.AddDays(days);          // soft end — renewal due\nDateTime hardCutoff = subscriptionEnd.AddDays(grace);  // engine-enforced end of grace\n\nvar license = new StringLicense { ExpireDate = hardCutoff };\nlicense\n    .ForAssembly(assemblyFullName)\n    .WithUniqueId(\"SUBSCR-\")\n    .WithHardwareKey(HardwareId.Create().ToMachineKey())\n    .WithField(Secrets.SubscriptionEndField, subscriptionEnd.ToString(\"O\"))\n    .WithField(Secrets.ProSource, Secrets.ProPassword.Encrypt(Secrets.FieldSecret))\n    .LicensedTo(\"Demo Customer\", \"demo@example.com\", \"ACME Corp\");\nBabel Licensing rejects the license automatically once ExpireDate has passed, so the hard\ncutoff needs no code of its own. The application only has to distinguish active from in\ngrace, which it does by comparing the soft subscription-end field to the current time:\nvar now = DateTime.UtcNow;\nif (subEnd.HasValue && now > subEnd.Value)\n{\n    int graceDaysLeft = (int)Math.Ceiling(((license.ExpireDate ?? now) - now).TotalDays);\n    return new SubscriptionStatus(SubscriptionState.Grace, subEnd, graceDaysLeft,\n        $\"Subscription lapsed — grace period active ({graceDaysLeft} day(s) left). Please renew.\");\n}"},{"page":172,"heading":"The Encrypted Pro Feature","anchor":"the-encrypted-pro-feature","text":"The pro method is encrypted; its password comes from the license through the get password\nhook. That is what ties the encrypted code to the subscription: while the license validates\n(active or in grace) the hook returns the password and the method runs; once the hard cutoff\npasses, Validate() throws and the hook can no longer supply the password.\n[Obfuscation(Feature = \"msil encryption:internal=true;source=pro;password=Pr0-Su1te-2026-K3y\", Exclude = false)]\npublic static string Forecast(double[] series) { /* premium analytics */ }\n\n[Obfuscation(Feature = \"msil encryption get password\")]\ninternal static string GetSourcePassword(string source)\n{\n    var license = Validate();   // throws once past the end of grace\n    var field = license.Fields.FirstOrDefault(f => f.Name == source)\n        ?? throw new InvalidOperationException($\"License does not grant source '{source}'.\");\n    return field.Value.Decrypt(Secrets.FieldSecret);\n}"},{"page":172,"heading":"Running It","anchor":"running-it","text":"# Build in Release — Babel encrypts Pro.Forecast.\ndotnet build src/ProSuite/ProSuite.csproj -c Release\n\n# Mint a subscription license: active for 30 days, 7-day grace.\ndotnet run --project src/LicenseGenerator -- --days 30 --grace 7\n\ncp ProSuite.lic src/ProSuite/bin/Release/net8.0/\ndotnet src/ProSuite/bin/Release/net8.0/ProSuite.dll\nRe-mint the license to walk through every state:\ndotnet run --project src/LicenseGenerator -- --days -2 --grace 7   # lapsed, in grace\ndotnet run --project src/LicenseGenerator -- --expired             # past grace\nState | Condition | Pro feature\nActive | before the subscription end | runs\nGrace | past the subscription end, before the hard cutoff | runs, with a renewal warning\nExpired | past the hard cutoff | locked — the BVM cannot decrypt it\nPast the grace period the application proves the point by trying to call the pro method anyway:\nSubscription expired: License expired\n\nBasic average: 13.63\nPro forecast is locked. Renew your subscription to restore access.\n(proof) encrypted Pro.Forecast blocked: License expired\nInfo: For recurring billing, the same license is normally issued and renewed by the\nBabel Licensing Service, which can shorten the validity\nwindow and push renewals automatically. The offline file license shown here is the simplest way\nto demonstrate the active / grace / expired transitions."},{"page":172,"heading":"Running It","anchor":"running-it","text":"Warning: keys.pem and the passwords in the sample are for demonstration only. Keep the RSA private key\noffline and issue licenses from the vendor side; only the public key ships with the application."},{"page":173,"heading":"","anchor":"","text":"In this guide, we'll explore how to implement license activation in a .NET MAUI application using Babel Licensing. This approach allows you to securely bind licenses to specific devices, ensuring your software is only used according to your licensing terms. By following this implementation pattern, you'll create a robust licensing system that works consistently across multiple platforms while leveraging platform-specific device information.\nPrerequisites\nBefore you begin, ensure you have the following:\nVisual Studio 2022 with .NET MAUI workload installed\nBabel.Licensing NuGet package (version 11.0.0 or later)\nA Babel Licensing Service instance running (either locally or on a server)\nBasic understanding of .NET MAUI application development\nA Babel Licensing Server or Data Center edition license\nSample Project\nYou can download the complete sample project from GitHub using the following command:\ngit clone https://github.com/babelfornet/maui-licensed-app.git\nThis repository contains a fully implemented MAUI application with Babel Licensing integration across all supported platforms.\nLicensed MAUI Application\nWhy License Activation in MAUI?\nMAUI (Multi-platform App UI) allows developers to build cross-platform applications from a single codebase. However, when implementing licensing, you need to consider the unique characteristics of each platform. License activation is particularly well-suited for MAUI applications because:"},{"page":173,"heading":"","anchor":"","text":"Device-Specific Binding: Licenses are linked to the specific device where the application runs, preventing unauthorized use on multiple devices.\nOffline Operation: Once activated, applications can operate without continuous server connection, making it ideal for mobile applications.\nCross-Platform Compatibility: The licensing model works consistently across different platforms (Android, iOS, Windows, MacCatalyst).\nSetting Up the Project Structure\nThe MauiLicApp example demonstrates a well-organized approach to implementing Babel Licensing in a MAUI application:\nMauiLicensedApp/\n├── Licensing/                 # Core licensing implementation\n│   ├── BabelLicensingExtensions.cs\n│   ├── ISystemInformation.cs\n│   └── LicensingService.cs\n├── Platforms/                 # Platform-specific implementations\n│   ├── Android/               \n│   ├── iOS/                   \n│   ├── MacCatalyst/           \n│   └── Windows/               \n├── Reporting/                 # Exception reporting functionality\n│   └── BabelReportingExtensions.cs\n└── MauiProgram.cs             # Application initialization\nThis structure separates licensing concerns from the rest of your application while maintaining platform-specific implementations where needed.\nImplementing the SystemInformation Base Class\nThe core of our cross-platform licensing system is the SystemInformationBase abstract class, which defines a platform-independent interface for gathering system information required for license activation:"},{"page":173,"heading":"","anchor":"","text":"public abstract class SystemInformationBase : ISystemInformation\n{\n    public abstract string DeviceId { get; }\n    public abstract string DeviceManufacturer { get; }\n    public abstract string DeviceModel { get; }\n    public abstract string OsVersion { get; }\n    // Additional system properties...\n}\nThis class implements Babel Licensing's ISystemInformation interface, ensuring compatibility with the licensing system while providing a consistent abstraction across platforms."},{"page":173,"heading":"Platform Specific System Information","anchor":"platform-specific-system-information","text":"In a MAUI application, platform-specific implementations of SystemInformationBase are crucial for several key reasons:\nHardware Access Differences: Each platform has unique APIs and methods for accessing hardware information. For example, Android uses Build.SERIAL or Settings.Secure.ANDROID_ID, while iOS uses UIDevice.CurrentDevice.IdentifierForVendor.\nSecurity Restrictions: Mobile platforms have different security models that restrict access to certain system information. Platform-specific implementations can navigate these restrictions appropriately.\nUnique Identifiers: The approach to generate reliable, persistent device identifiers varies by platform. What works on Windows won't work on iOS or Android.\nFeature Availability: Some hardware information available on one platform may not be accessible on another, requiring platform-specific alternatives.\nHere's how it works in practice for different platforms:\nAndroid Implementation\nThe Android implementation leverages Android-specific APIs to gather system information:"},{"page":173,"heading":"Platform Specific System Information","anchor":"platform-specific-system-information","text":"public class SystemInformation : SystemInformationBase\n{\n    public override string DeviceId \n    { \n        get\n        {\n            try\n            {\n                return Settings.Secure.GetString(_context.ContentResolver, \n                    Settings.Secure.AndroidId) ?? string.Empty;\n            }\n            catch (Exception)\n            {\n                return string.Empty;\n            }\n        }\n    }\n    \n    public override string DeviceManufacturer => Build.Manufacturer ?? string.Empty;\n    \n    // Other implementations...\n}\niOS Implementation\nThe iOS implementation uses iOS-specific APIs:\npublic class SystemInformation : SystemInformationBase\n{\n    public override string DeviceId \n    { \n        get\n        {\n            try\n            {\n                return UIDevice.CurrentDevice?.IdentifierForVendor?.AsString() ?? string.Empty;\n            }\n            catch (Exception)\n            {\n                return string.Empty;\n            }\n        }\n    }\n    \n    public override string DeviceManufacturer => \"Apple\";\n    \n    // Other implementations...\n}\nWindows Implementation\nThe Windows implementation uses Windows Management Instrumentation (WMI) to collect system information:"},{"page":173,"heading":"Platform Specific System Information","anchor":"platform-specific-system-information","text":"public class SystemInformation : SystemInformationBase\n{\n    public override string SystemUuid\n    {\n        get\n        {\n            try\n            {\n                using var searcher = new ManagementObjectSearcher(\n                    \"SELECT UUID FROM Win32_ComputerSystemProduct\");\n                foreach (var obj in searcher.Get())\n                {\n                    return obj[\"UUID\"]?.ToString() ?? string.Empty;\n                }\n                return string.Empty;\n            }\n            catch (Exception)\n            {\n                return string.Empty;\n            }\n        }\n    }\n    \n    // Other implementations...\n}"},{"page":173,"heading":"Registering Platform-Specific Implementations","anchor":"registering-platform-specific-implementations","text":"Each platform needs to register its specific SystemInformation implementation during application startup. This is typically done in the platform-specific entry point:\nFor Android (MainApplication.cs):\n[Application]\npublic class MainApplication : MauiApplication\n{\n    public MainApplication(IntPtr handle, JniHandleOwnership ownership)\n        : base(handle, ownership)\n    {\n        // Register the SystemInformation service for licensing\n        LicenseServices.Current.AddService(typeof(ISystemInformation), \n            new SystemInformation());\n    }\n\n    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();\n}\nFor iOS (Program.cs):\npublic class Program\n{\n    static void Main(string[] args)\n    {\n        // Register the SystemInformation service for licensing\n        LicenseServices.Current.AddService(typeof(ISystemInformation), \n            new SystemInformation());\n        \n        UIApplication.Main(args, null, typeof(AppDelegate));\n    }\n}\nFor Windows (App.xaml.cs):\npublic partial class App : MauiWinUIApplication\n{\n    protected override void OnLaunched(LaunchActivatedEventArgs args)\n    {\n        // Register the SystemInformation service for licensing\n        LicenseServices.Current.AddService(typeof(ISystemInformation), \n            new SystemInformation());\n\n        base.OnLaunched(args);\n    }\n}"},{"page":173,"heading":"Configuring Babel Licensing in MAUI","anchor":"configuring-babel-licensing-in-maui","text":"With platform-specific implementations in place, we need to configure Babel Licensing for the MAUI application. This is done using extension methods that integrate with MAUI's dependency injection system:"},{"page":173,"heading":"Configuring Babel Licensing in MAUI","anchor":"configuring-babel-licensing-in-maui","text":"public static MauiAppBuilder UseBabelLicensing(\n    this MauiAppBuilder builder, \n    Action<BabelLicensingConfiguration>? configureClient = null)\n{\n    // Register platform-specific system information service\n    builder.Services.AddSingleton<SystemInformationBase>(serviceProvider =>\n    {\n        return LicenseServices.Current.GetService(typeof(ISystemInformation)) \n            as SystemInformationBase ?? \n        throw new InvalidOperationException(\"SystemInformation service not registered.\");\n    });\n\n    // Create the BabelLicensing configuration\n    var config = new BabelLicensingConfiguration {\n        // Set the default client ID\n        ClientId = AppInfo.Current.Name,\n        // Set the machine ID using system UUID and name\n        MachineId = new HardwareId(\n            HardwareComponents.SystemUuid | \n            HardwareComponents.SystemName).ToMachineKey(),                \n        // Set the signature provider with public key for license verification\n        SignatureProvider = RSASignature.FromKeys(\"PUBLIC_KEY_HERE\")\n    };\n\n    // Apply custom configuration\n    configureClient?.Invoke(config);\n\n    // Register services\n    builder.Services.AddSingleton<BabelLicensing>(/* ... */);\n    builder.Services.AddSingleton<BabelServiceLicenseProvider>(/* ... */);\n\n    return builder;\n}\nThis extension method is then used in MauiProgram.cs to apply the licensing configuration:"},{"page":173,"heading":"Configuring Babel Licensing in MAUI","anchor":"configuring-babel-licensing-in-maui","text":"public static MauiApp CreateMauiApp()\n{\n    // Configure BabelLicensing service URL\n    string babelHttpServiceUrl = \"https://your-license-server:5455\";\n\n    var builder = MauiApp.CreateBuilder();\n    builder\n        .UseMauiApp<App>()\n        .UseBabelLicensing(config => {\n            config.ServiceUrl = babelHttpServiceUrl;\n        })\n        .UseBabelReporting(config => {\n            config.ServiceUrl = babelHttpServiceUrl;\n        })\n        .ConfigureFonts(fonts => { /* ... */ });\n\n    // Register the LicensingService for dependency injection\n    builder.Services.AddSingleton<LicensingService>();\n\n    return builder.Build();\n}"},{"page":173,"heading":"Creating the LicensingService","anchor":"creating-the-licensingservice","text":"The LicensingService class provides a simplified interface for licensing operations throughout your application:\npublic class LicensingService\n{\n    private readonly BabelLicensing _client;\n    private readonly BabelServiceLicenseProvider _licenseProvider;\n\n    public LicensingService(BabelLicensing client, BabelServiceLicenseProvider licenseProvider)\n    {\n        _client = client;\n        _licenseProvider = licenseProvider;\n    }\n\n    public BabelLicensing Client => _client;\n    public bool IsLicensed => BabelLicenseManager.IsLicensed(typeof(BabelLicensingExtensions));\n    public string? UserKey => _licenseProvider.UserKey;\n\n    public async Task ActivateLicenseAsync(string userKey)\n    {\n        await _client.ActivateLicenseAsync(userKey, typeof(BabelLicensingExtensions));\n    }\n\n    public async Task DeactivateLicenseAsync()\n    {\n        if (!string.IsNullOrEmpty(UserKey))\n        {\n            await _client.DeactivateLicenseAsync(UserKey);\n        }\n    }\n\n    public async Task<ILicense> ValidateLicenseAsync()\n    {\n        return await BabelLicenseManager.ValidateAsync(typeof(BabelLicensingExtensions));\n    }\n}\nThis service encapsulates the Babel Licensing API behind a simple, application-specific interface. It can be injected into any page or viewmodel that needs licensing functionality."},{"page":173,"heading":"Implementing License Activation in the UI","anchor":"implementing-license-activation-in-the-ui","text":"With the licensing infrastructure in place, you can now implement license activation in your UI. Here's an example from MainPage.xaml.cs:"},{"page":173,"heading":"Implementing License Activation in the UI","anchor":"implementing-license-activation-in-the-ui","text":"private async void OnActivateClicked(object sender, EventArgs e)\n{\n    try\n    {\n        if (_licensingService.IsLicensed)\n        {\n            // If licensed, validate the license\n            var license = await _licensingService.ValidateLicenseAsync();\n            ActivateBtn.Text = $\"License valid: {license.Id}\";\n            \n            // Show system information\n            await DisplayAlert(\"System Info\", \n                $\"Device: {_systemInfo.DeviceManufacturer} {_systemInfo.DeviceModel}\\n\" +\n                $\"OS: {_systemInfo.OperatingSystem} {_systemInfo.OsVersion}\\n\" +\n                $\"System: {_systemInfo.SystemName}\\n\" +\n                $\"UUID: {_systemInfo.SystemUuid}\", \n                \"OK\");\n        }\n        else\n        {\n            // If not licensed, prompt for activation\n            string userKey = await DisplayPromptAsync(\"License Activation\", \n                \"Enter your license key:\", \n                accept: \"Activate\", \n                cancel: \"Cancel\");\n            \n            if (!string.IsNullOrEmpty(userKey))\n            {\n                try\n                {\n                    await _licensingService.ActivateLicenseAsync(userKey);\n                    await DisplayAlert(\"Success\", \"License activated successfully!\", \"OK\");\n                    UpdateLicenseStatus();\n                }\n                catch (Exception ex)\n                {\n                    await DisplayAlert(\"Activation Failed\", "},{"page":173,"heading":"Implementing License Activation in the UI","anchor":"implementing-license-activation-in-the-ui","text":"                        $\"Could not activate license: {ex.Message}\", \"OK\");\n                }\n            }\n        }\n    }\n    catch (Exception ex)\n    {\n        await DisplayAlert(\"Error\", $\"License operation failed: {ex.Message}\", \"OK\");\n    }\n}\nThis implementation allows users to input a license key and activate the application. Once activated, the license is bound to the device and can be validated in subsequent application launches."},{"page":173,"heading":"Adding Exception Reporting","anchor":"adding-exception-reporting","text":"Babel Licensing also supports exception reporting, which can be integrated into your MAUI application using the BabelReportingExtensions class:\npublic static void ReportUnhandledException(this Exception ex)\n{\n    try \n    {\n        var task = Task.Run(async () => \n        {\n            try \n            {\n                await ex.SendReportAsync();\n            }\n            catch (Exception innerEx)\n            {\n                Debug.WriteLine($\"Failed to report exception: {innerEx.Message}\");\n            }\n        });\n\n        task.Wait(TimeSpan.FromSeconds(5));\n    }\n    catch (Exception reportEx)\n    {\n        Debug.WriteLine($\"Failed to report exception: {reportEx.Message}\");\n    }\n}\nThis functionality can be registered in the application's unhandled exception handlers:\n// In App.xaml.cs\nprivate void SetupExceptionHandling()\n{\n    AppDomain.CurrentDomain.UnhandledException += (sender, args) => \n    {\n        var ex = args.ExceptionObject as Exception;\n        ex?.ReportUnhandledException();\n    };\n}\nException Report"},{"page":173,"heading":"Best Practices for MAUI License Activation","anchor":"best-practices-for-maui-license-activation","text":"To ensure a smooth licensing experience in your MAUI application:\nError Handling: Implement comprehensive error handling for network and licensing operations, especially for mobile applications that may have intermittent connectivity.\nGraceful Degradation: When license validation fails due to connectivity issues, provide a grace period or limited functionality rather than completely blocking the application.\nUI Feedback: Provide clear feedback about licensing status in the UI, making it obvious when a license is active, expired, or invalid.\nTesting: Test your licensing implementation on all target platforms to ensure consistent behavior across devices.\nConclusion\nImplementing license activation in a .NET MAUI application with Babel Licensing requires a strategic approach to handle platform-specific differences while maintaining a consistent licensing experience. By creating a platform-independent abstraction with platform-specific implementations, you can reliably gather the system information needed for secure license activation.\nThe MauiLicApp example demonstrates a comprehensive implementation that works across Android, iOS, Windows, and MacCatalyst platforms. By following this pattern and the best practices outlined in this guide, you can effectively protect your MAUI applications with a robust licensing system."},{"page":173,"heading":"Best Practices for MAUI License Activation","anchor":"best-practices-for-maui-license-activation","text":"This approach ensures that your applications are only used according to your licensing terms while providing a seamless experience for legitimate users across all supported platforms."},{"page":174,"heading":"","anchor":"","text":"Babel Desktop is the cross-platform application for Windows, macOS and Linux\nthat edits and runs Babel Obfuscator projects and manages a Babel Licensing\nService."},{"page":174,"heading":"License requirements","anchor":"platform-license-requirements","text":"License edition | Supported platforms\nEnterprise | Windows\nUltimate or higher | Windows, macOS, Linux\nA demo license can be used for evaluation. Licensing management also requires the appropriate Babel Licensing Server or Data Center entitlement.\nBabel Desktop is new in Babel 12.0. It replaces Babel UI, which ran only on Windows. The desktop runs the Babel Obfuscator engine itself, so with the same settings a run produces the same output as the command line tool or the MSBuild task. Projects are saved as the .babel files the MSBuild task reads, which means a project set up in the desktop can later be built unattended on a build server.\nThe application covers:"},{"page":174,"heading":"License requirements","anchor":"platform-license-requirements","text":"Obfuscation projects: add assemblies, connect merge, embed and reference dependencies on a canvas, edit every engine option and the XML rules, run the obfuscation and review the statistics. See Obfuscation Projects.\nTools: decode obfuscated stack traces with XML map files in the Stack Decoder, browse the engine warning reference and discover engine plugin arguments.\nLicensing: the built-in Licensing views connect to a Babel Licensing Service with an API key and manage customers, products, orders, licenses, templates, tokens, reports, users, API keys, webhooks and server settings, with a dashboard and an activity globe.\nPersonalization: extensions, themes and interface languages (English, Italian, French, German, Spanish and Japanese).\nAutomation: an opt-in local MCP server lets an AI assistant such as Claude Code operate the application.\nUpdates: new versions are installed automatically from a signed update feed.\nBabel Desktop start screen with no project open, showing the Add assemblies and Open project buttons, the New, Open and Command palette shortcuts, the activity bar on the left and the status bar reporting that the local engine is connected\nThe start screen: add assemblies or open a project to begin\nInfo: Babel Desktop does not install the babel command line tool or the MSBuild task. To run Babel from a terminal, a build script or MSBuild, use the zip packages or the NuGet tools described in Install."},{"page":174,"heading":"Getting Started","anchor":"getting-started","text":"Install: installers for Windows, macOS and Linux.\nProduct Activation: load your license from a file, an activation key or a floating license, and what each license enables."},{"page":174,"heading":"The Application Window","anchor":"the-application-window","text":"The main window is laid out like a code editor:\nActivity bar: the column of icons on the left opens the Project sidebar, the Extensions view, the Stack decoder, each Licensing connection, the views added by installed extensions, the account menu and Settings.\nCanvas: the project graph, with the Add Assembly button and the zoom controls. See Obfuscation Projects.\nProperties panel: the settings and XML rules of the selected assembly, docked on the right.\nActivity panel: the progress and the engine log of the current run, docked at the bottom.\nStatus bar: the engine connection state and the engine version.\nTo resize a panel, drag its separator. Babel Desktop remembers the sizes.\nCommand Palette"},{"page":174,"heading":"The Application Window","anchor":"the-application-window","text":"Press Ctrl+Shift+P (Cmd+Shift+P on macOS) to open the command palette. The commands you used last are at the top, under recently used, and each command shows its keyboard shortcut when it has one. Type to filter the list. The palette lists all application commands: project commands (Project: New, Project: Open..., Project: Open Recent..., Project: Save, Project: Save As...), assembly commands (Assembly: Add primary targets..., Assembly: Replace input and keep settings..., the dependency commands), the setup commands (Obfuscation: Setup merge into main assembly, Obfuscation: Setup public obfuscation (all assemblies), Obfuscation: Set level...), tools (Tools: Stack decoder, Tools: Warning reference, Tools: Job warnings), Engine plugins commands, MCP server commands, commands added by extensions, and the About commands with the third-party notices.\nCommand palette open over the project canvas, with Project: Open... marked as recently used, followed by Project: Open Recent..., Tools: Stack decoder, Tools: Warning reference, Project: New, Assembly: Replace input and keep settings..., the Project Save commands and the Assembly commands, each with its keyboard shortcut\nThe command palette\nKeyboard Shortcuts"},{"page":174,"heading":"The Application Window","anchor":"the-application-window","text":"Command | Windows and Linux | macOS\nCommand palette | Ctrl+Shift+P | Cmd+Shift+P\nNew project | Ctrl+N | Cmd+N\nOpen project | Ctrl+O | Cmd+O\nSave project | Ctrl+S | Cmd+S\nSave project as | Ctrl+Shift+S | Cmd+Shift+S\nAdd assembly | Ctrl+Shift+A | Cmd+Shift+A\nRun obfuscation | Ctrl+Enter | Cmd+Enter\nRun obfuscated app | Ctrl+F5 | Cmd+F5\nAuto layout graph | Ctrl+Shift+L | Cmd+Shift+L\nProject sidebar | Ctrl+Shift+E | Cmd+Shift+E\nExtensions view | Ctrl+Shift+X | Cmd+Shift+X\nStack decoder | Ctrl+Shift+D | Cmd+Shift+D\nSettings | Ctrl+, | Cmd+,\nSettings\nThe Settings dialog sorts settings into categories and has a search box at the top:\nAppearance: interface language, theme, density, text size and the style of the Licensing activity globe. See Themes and Languages.\nApplication: version and automatic updates. See Updates.\nLicense: the engine license source, described in Product Activation.\nExtensions: the address of an extension catalog.\nMCP: the automation server. See MCP Server.\nObfuscation: whether independent flows of a project run in parallel, and how many at once. See Running Flows in Parallel.\nSelected assembly: shortcuts to the properties and XML rules of the selected assembly.\nLicensing connections and IP geolocation: the services managed from Babel Desktop and the IP lookup of the activity globe. See Licensing.\nCategories added by each Licensing connection and by installed extensions."},{"page":174,"heading":"Work Recovery","anchor":"work-recovery","text":"Babel Desktop takes recovery snapshots of project changes you have applied but not saved. If the application or the engine stops unexpectedly, a banner on the next start offers to restore that work. Session passwords, such as signing key passwords, are never written to snapshots or project files, so you have to enter them again."},{"page":175,"heading":"","anchor":"","text":"Babel Desktop ships as a native installer for each operating system. Each installer includes the application runtime and a self-contained .NET runtime, so the machine does not need Node.js or .NET. Download the package for your platform and processor architecture from the babelfor.NET download area."},{"page":175,"heading":"License requirements","anchor":"platform-license-requirements","text":"License edition | Supported platforms\nEnterprise | Windows\nUltimate or higher | Windows, macOS, Linux\nA demo license can be used for evaluation. Licensing management also requires the appropriate Babel Licensing Server or Data Center entitlement.\nPlatform | Package | Updates\nWindows | babel-desktop-<version>-win-x64.exe (per-user installer) | Automatic, from inside the application\nWindows | babel-desktop-<version>-win-x64.msi (per-machine installer) | Managed by your IT deployment tools\nmacOS | babel-desktop-<version>-mac-arm64.dmg or .zip | Automatic, from inside the application\nLinux | babel-desktop-<version>-linux-x86_64.AppImage | Automatic, from inside the application\nLinux | babel-desktop-<version>-linux-amd64.deb, babel-desktop-<version>-linux-x86_64.rpm | Through the system package manager\nEach download folder also contains a SHA256SUMS file you can use to verify the packages.\nWindows\nPer-user installer (EXE). Run babel-desktop-<version>-win-x64.exe. It does not need administrator rights. You can pick the installation folder, and the installer adds a Start menu shortcut. This installation updates itself; see Updates.\nPer-machine installer (MSI). The MSI installs Babel Desktop for every user on the machine. Use it for managed deployments such as Group Policy or Intune. It can install silently:\nmsiexec /i babel-desktop-<version>-win-x64.msi /qn\nAn MSI installation does not update itself. To upgrade, deploy the MSI of the new version."},{"page":175,"heading":"License requirements","anchor":"platform-license-requirements","text":"Your settings and user data stay on the machine when you uninstall Babel Desktop.\nmacOS\nOpen babel-desktop-<version>-mac-arm64.dmg and drag the application to the Applications folder, or extract the .zip package and move the application to Applications. Start it from Launchpad or the Applications folder.\nLinux\nAppImage. Make the file executable and run it. An AppImage updates itself. On some distributions you need FUSE support to run it.\nchmod +x babel-desktop-<version>-linux-x86_64.AppImage\n./babel-desktop-<version>-linux-x86_64.AppImage\nDEB and RPM packages. Install the package with your distribution's package manager. The application is added to the desktop menu. To update, install the package of the new version.\n# Debian, Ubuntu\nsudo apt install ./babel-desktop-<version>-linux-amd64.deb\n\n# Fedora, RHEL\nsudo dnf install ./babel-desktop-<version>-linux-x86_64.rpm\nThe installed application is named Babel Obfuscator in the Start menu, in Launchpad and in the desktop menu of Linux."},{"page":175,"heading":"Application Integrity","anchor":"application-integrity","text":"On Windows and macOS, Babel Desktop checks its application files every time it starts. If any of them has been modified since installation, for example by a tool that patches applications, Babel Desktop closes before its window opens. Install the same package again to repair it; your settings and projects stay as they are.\nBabel Desktop cannot be started as a Node.js process. It ignores the ELECTRON_RUN_AS_NODE, NODE_OPTIONS and NODE_EXTRA_CA_CERTS environment variables and the --inspect and --inspect-brk command line options."},{"page":175,"heading":"Proxy and Certificates","anchor":"proxy-and-certificates","text":"Babel Desktop uses the proxy settings of the operating system and trusts the same certificate authorities it does, for sign-in, updates, the extension catalog, the documentation and the Licensing connections. If your network inspects TLS traffic with its own certificate authority, add that authority to the system certificate store on Windows and macOS, or on Linux to the shared NSS database (~/.pki/nssdb) that Chromium-based browsers use.\nNext, load your license: see Product Activation."},{"page":176,"heading":"","anchor":"","text":"The engine in Babel Desktop uses the Babel license you load in Settings > License. With no license loaded, the engine runs in evaluation mode and an Evaluation banner on the canvas lists the restrictions."},{"page":176,"heading":"License requirements","anchor":"platform-license-requirements","text":"License edition | Supported platforms\nEnterprise | Windows\nUltimate or higher | Windows, macOS, Linux\nA demo license can be used for evaluation. Licensing management also requires the appropriate Babel Licensing Server or Data Center entitlement.\nOpen the License settings\nOpen Settings (Ctrl+, on Windows and Linux, Cmd+, on macOS) and choose License.\nChoose the license source\nSelect how the engine obtains its license:\nLicense file: click Browse... and select your babel.licenses file. Babel Desktop remembers the path and reloads the file each time it starts.\nActivation key: enter the activation key and click Activate. The activation is saved on the machine and restored on each start. Deactivate releases it.\nFloating license: enter the floating license key and click Request license. The license is checked out from the license server for the session and returned when the application exits. Tick Request automatically at startup to request it at every start.\nCheck the license\nThe Current license badge shows the edition of the loaded license, and the details list its license id, product, version and maintenance.\nSettings dialog on the License page: a Data Center license badge, the license id, product, version and maintenance, the License source choice between License file, Activation key and Floating license, and the Licensing settings with the export folder and user key format\nSettings > License, with the Licensing extension settings below"},{"page":176,"heading":"License requirements","anchor":"platform-license-requirements","text":"You receive the license file, activation key or floating license key when you buy Babel. The command line tool and the MSBuild task accept the same license; see Product Activation for those tools and for build servers.\nThe table shows what each license enables in Babel Desktop:\nCapability | Requirement\nObfuscation projects and tools on Windows | Enterprise or higher\nObfuscation projects and tools on macOS and Linux | Ultimate or higher\nLicensing | A Babel Licensing license (Server or Data Center edition), or an unlicensed installation in evaluation mode\nAutomatic updates on Windows | Any valid license, within its maintenance period\nAutomatic updates on macOS and Linux | An Ultimate edition or demo license, within its maintenance period"},{"page":176,"heading":"Troubleshooting","anchor":"troubleshooting","text":"If the Current license badge still shows Evaluation after you load a license file, check that the file is the babel.licenses you received for this version. A license unlocks the versions released while its maintenance is active, but not versions released after the maintenance expired.\nAn activation key is bound to the machine where it was activated. To move it to another machine, click Deactivate on the old machine first.\nA floating license needs the license server to be reachable when the license is requested. If the request fails, check the network connection to the server and that a license token is available."},{"page":177,"heading":"","anchor":"","text":"An obfuscation project collects the assemblies to protect, their dependencies\nand the settings of each one. Babel Desktop shows it as a graph on a canvas\nand runs it with the Babel Obfuscator engine.\nBabel Desktop saves projects as .babel files, the MSBuild project format the MSBuild task uses. You can build a project saved in the desktop with MSBuild, and open an existing .babel project in the desktop."},{"page":177,"heading":"Creating a Project","anchor":"creating-a-project","text":"Add the assemblies\nClick Add assemblies on the start screen or + Add Assembly on the canvas toolbar (Ctrl+Shift+A, Cmd+Shift+A on macOS), or drag .NET assemblies from the file manager onto the canvas. Each assembly becomes a primary target: a node on the canvas that the engine obfuscates.\nConnect the dependencies\nAdd the assemblies that are merged into, embedded in or referenced by a target, as described in Dependencies.\nConfigure each target\nSelect a node and open the properties panel to edit its settings and XML rules. See Target Settings.\nSave and run\nSave the project with File > Save (Ctrl+S, Cmd+S on macOS), then click Run project (Ctrl+Enter, Cmd+Enter on macOS). Save writes the open .babel file and asks for a file name only for a new project. To save a copy under another name, use File > Save As... (Ctrl+Shift+S, Cmd+Shift+S on macOS).\nTo start over, use Project: New (Ctrl+N) or the New project button on the canvas. Project: Open Recent... in the command palette reopens a recent project, and the Open Project dialog starts in the folder of the last project you opened. If the current project has unsaved changes, Babel Desktop asks whether to discard them before it creates or opens another one. Wait for a running job to finish first."},{"page":177,"heading":"The Project Canvas","anchor":"the-project-canvas","text":"The canvas shows each assembly as a node. Drag the background, scroll the wheel or swipe with two fingers to pan. Pinch, or hold Ctrl (Cmd on macOS) while you scroll, to zoom around the pointer. The zoom buttons and Fit view frame the graph. Drag nodes to arrange them, or let View > Auto Layout Graph (Ctrl+Shift+L, Cmd+Shift+L on macOS) place the targets from left to right in run order, with the dependencies of each target stacked on its left. Node positions are saved in the project file.\nProject canvas of the project FullMerge.babel: the primary target BubbleBurst.exe on the right and four merge inputs on the left, BubbleBurst.View.dll, BubbleBurst.ViewModel.dll, MvvmFoundation.Wpf.dll and Thriple.dll, each connected to it with a line labelled MERGE\nA primary target with four merged assemblies\nRest the pointer on a node for half a second, or move to it with the keyboard, to open its card. The card of a primary target shows its state, its run order, how many assemblies it merges, embeds and references, its map links and the path of the input file. After a run it also shows the obfuscation score.\nDependencies\nThe top and bottom anchors of a node connect dependencies. Drag from the bottom anchor of the source assembly to the top anchor of the target, or click the two anchors one after the other. A new dependency gets one of three types:"},{"page":177,"heading":"The Project Canvas","anchor":"the-project-canvas","text":"Type | Effect\nMerge | The source assembly is merged into the target and obfuscated with it, producing a single output assembly. See Assembly Merging.\nEmbed | The source assembly is stored as a resource of the target and loaded at run time. See Assembly Embedding.\nReference | The source assembly is only used to resolve references of the target.\nBabel Desktop picks the type for you. If the target references the exact identity of the source assembly (name, version, culture and public key token), the new dependency is a Merge; if not, it is a Reference. To change the type, click the dependency line and choose Merge, Embed or Reference in the popover, then click Apply. The Assembly: Add dependency automatically... command and the Assembly: Add merge input..., Assembly: Add embedded assembly... and Assembly: Add reference... commands in the command palette add dependencies from a file picker.\nAn assembly used as a Merge input stays on the canvas but is not obfuscated separately, because it becomes part of its destination.\nExecution Order and Map Files\nThe left and right anchors connect two targets so that one runs before the other. Drag from the right anchor of the first target to the left anchor of the second. Babel Desktop then asks what the connection is for:"},{"page":177,"heading":"The Project Canvas","anchor":"the-project-canvas","text":"Choice | Effect\nExecution order only | A flow edge: target A runs before target B. Nothing passes from A to B.\nPass the map file | A map link, drawn with a MAP label: A writes its XML rename map and B reads it, so B uses the new names of the public symbols of A. A runs before B. See Cross Assembly Renaming.\nA map link turns on Generate Map Out File for the first target and adds its map to the Map In Files of the second. If the first target sets neither an output path nor a map path, its map goes to a fixed place next to its input, for example BabelOut/Library2.dll.map.xml, so the second target always finds it. Map links are not stored separately: Babel Desktop reads them from those two settings, so a project written by hand or with Babel UI shows its map links as well.\nEach node shows its step, the position at which it runs in its flow. A flow is a group of targets tied together by flow edges, map links or merge, embed and reference dependencies. Targets that are not tied to each other form separate flows. Within a flow, targets run in the order of the steps, and in project order where nothing decides it. Flow edges are saved in the project as standard MSBuild target dependencies."},{"page":177,"heading":"The Project Canvas","anchor":"the-project-canvas","text":"Babel Desktop rejects self-links and duplicate edges, and it refuses a connection that would make targets wait for each other. If the targets of a project opened from disk wait for each other's map files, the project still opens. Babel Desktop shows an error that names the circle, for example Library1.dll → Library2.dll → Library1.dll, and the project does not run until you remove one link. To remove an edge or a map link, click it and press Delete or Backspace; Esc cancels a connection in progress or clears the selection.\nReplacing an Input\nTo point a target at a new build of its assembly without losing its settings, select the node and run Assembly: Replace input and keep settings... from the command palette. Assembly: Remove selected target removes a target and its edges."},{"page":177,"heading":"Setup Commands","anchor":"setup-commands","text":"Three commands in the command palette configure a project in one step. Add the assemblies first, then run the command that fits the application.\nCommand palette filtered by Obfuscation: Set, listing Obfuscation: Setup public obfuscation (all assemblies), Obfuscation: Setup merge into main assembly and Obfuscation: Set level...\nThe setup commands in the command palette\nCommand | Effect\nObfuscation: Setup merge into main assembly | Merges every other target into the main assembly, so the project produces a single output file. The main assembly is the only .exe of the project, or the first target when there is none or more than one. An assembly the engine cannot merge is left as it is.\nObfuscation: Setup public obfuscation (all assemblies) | Prepares a set of assemblies that are shipped together to have their public symbols renamed. Each target gets an XML rule named obfuscate public and writes its rename map, and a target that depends on another one reads its map through a map link.\nObfuscation: Set level... | Applies one of three protection levels to the selected target.\nThe levels set these options and leave the others as they are:"},{"page":177,"heading":"Setup Commands","anchor":"setup-commands","text":"Level | Protection\nLight | Renaming of types, methods, fields, properties and events. Control flow, the encryption features and the anti-analysis protections are turned off.\nBalanced | Renaming, control flow obfuscation with the goto algorithm, string encryption and ILDASM suppression.\nMaximum | Renaming, control flow obfuscation with goto, switch, case, if and chained state, stream string encryption, value encryption, MSIL encryption, tampering detection, debugging protection and ILDASM suppression. When the license does not include the stream algorithm, the default string encryption is used.\nThe two setup commands skip package targets (.apk, .appx and .xap). None of the three runs while a job is in progress or an edit is waiting to be applied. They change the open project and do not save it, so you can review the result on the canvas and in the properties panel first. Applying a lower level after a higher one turns the extra protections off again."},{"page":177,"heading":"Target Settings","anchor":"target-settings","text":"Select a node and click the Properties button at the top right of the canvas, or press Enter on a selected node, to open the properties panel. The Settings tab lists every Babel Obfuscator option of the selected target, grouped as Renaming, Control flow, Code encryption, Optimization, Signing & protection, Files & dependencies, Output & diagnostics and Advanced. Type in Find a setting to filter the list.\nTarget properties panel of BubbleBurst.exe open next to the canvas on the Settings tab, with the Find a setting search box, the Map files group with Writes its rename map checked, and the Renaming group showing Flatten Namespaces, Unicode Normalization and Detect If Obfuscated\nThe properties panel of the selected target\nThe settings use the option names of the MSBuild task, so the Babel task reference and the pages of each protection describe what they do. Each option gets a control that fits its type: check boxes for switches, lists for algorithms, file and folder pickers for paths, and editors for filters and property maps.\nProperties panel on the Code encryption group: String Encryption enabled, Msil Encryption enabled with the filter .*, Dynamic Proxy Call Filters set to ICollection.* and Value Encryption with int32, int64, single, double and array enabled\nCode encryption settings: string, MSIL and value encryption"},{"page":177,"heading":"Target Settings","anchor":"target-settings","text":"Composite options such as Control Flow Obfuscation show one control per property. The next picture shows the control flow switches. The last one, chain, turns on the Ultimate chained state algorithm.\nProperties panel filtered by ControlFlow: the Control Flow Obfuscation map with enable, goto, switch, case, if, call and value enabled, token and underflow disabled, and chain left at its default\nControl Flow Obfuscation properties\nPasswords, such as a signing key or map file password, are kept for the current session only. They are never written to the project file, so you enter them again after a restart. When the engine needs a password during a run, Babel Desktop asks for it.\nInfo: Babel Desktop preserves the parts of a .babel file it does not edit, such as comments, custom properties and custom MSBuild tasks. It does not evaluate MSBuild imports, conditions or custom tasks: a project that depends on them must be built with MSBuild.\nMap Files\nThe Map files group of the properties panel collects the map settings of the selected target:"},{"page":177,"heading":"Target Settings","anchor":"target-settings","text":"Writes its rename map turns the map file of the target on or off. The path below it is where the map is written, by default next to the obfuscated assembly; Change... picks another file.\nMaps from other targets lists the map links that end on this target. Click a target name to select it.\nOther map files lists the maps this target reads that no target of the project writes, such as the map of a library obfuscated in an earlier build. Add map file... adds one and Remove takes it away.\nXML Rules\nThe XML rules tab edits the inline XML obfuscation rules of the selected target. The editor highlights the XML and Validate checks it against the Babel rules schema, reporting the line and column of each error. Open XML loads a rules file into the editor, Save XML file writes the editor content to a file and Apply to assembly stores the rules in the target. Inline rules are saved in the project file.\nXML rules tab of the target with an inline rule for the merged assembly BubbleBurst.View that sets the Dynamic Proxy Call Filters property to IEnumerator.*, and the Open XML, Validate, Save XML file and Apply to assembly buttons\nInline XML rules of a target\nEngine Plugins\nBabel Obfuscator plugins are set per target with Engine plugins: Configure DLL paths. Engine plugins: Discover argument names reads the argument names a plugin declares, so you can fill in its arguments. Plugins are .NET code that runs inside the engine, so use only plugins you trust."},{"page":177,"heading":"Running the Project","anchor":"running-the-project","text":"Click Run project at the top right of the canvas, press Ctrl+Enter (Cmd+Enter on macOS) or choose Run > Run Obfuscation. Unless a target sets its own output path, the obfuscated assembly is written to a BabelOut folder next to each input assembly. Before the run starts, Babel Desktop checks where the output will go. It will not overwrite an input assembly, a key file or a plugin, and it asks before replacing existing output files.\nThe Activity panel shows the phase in progress, a progress indicator and the engine log. The Log tab lists every message the engine writes at the target's Verbose Level, and warnings and errors are also collected in the Problems tab. Each target node reports its state on the canvas. Cancel job stops the run. Targets run one after another; when a target fails, the targets after it do not run.\nCanvas after a run: the target node BubbleBurst.exe shows completed, the Activity panel shows the Completed badge, the Log and Problems tabs with 3 problems, 100 percent and the tail of the engine log ending with the total elapsed time and 3 warnings, and the Results button is enabled\nA completed run in the Activity panel"},{"page":177,"heading":"Running the Project","anchor":"running-the-project","text":"After a run, the buttons at the top of the Activity panel open the output folder and start the obfuscated application. File > Reveal Output and Run > Run Obfuscated App (Ctrl+F5, Cmd+F5 on macOS) do the same. Babel Desktop starts a Windows executable directly and a .NET application through dotnet when its .runtimeconfig.json file is available. It does not offer to start a library.\nObfuscation Score\nAfter a completed run, the card of each target shows an obfuscation score from 0 to 100, a quick check that the run applied the protections you expected. Rest the pointer on the target to open the card.\nCard of the target BubbleBurst.exe after a run: obfuscation score 92 of 100 graded Strong, with the bars Renaming 26 of 30, Control Flow 25 of 25, String Encryption 15 of 15, Code protection 11 of 15 and Anti-analysis 15 of 15, the time of the last run, the run order Flow 1 step 1, 4 merged dependencies and the path of the input file\nThe obfuscation score of a target that merges four assemblies\nThe score adds the points of five protection layers. Each bar shows the points a layer earned out of its maximum, so a low score tells you which layer is missing."},{"page":177,"heading":"Running the Project","anchor":"running-the-project","text":"Layer | Points | Earned by\nRenaming | 30 | The share of the eligible symbols that were renamed\nControl Flow | 25 | The share of the methods that were scrambled. Methods without branches are left alone, so half of the methods is enough for all the points\nString Encryption | 15 | Encrypted strings\nCode protection | 15 | MSIL encryption (7), dynamic proxy calls (4) and value encryption (4)\nAnti-analysis | 15 | Tampering detection, debugging protection and ILDASM suppression, 5 points each\nThe score is graded Weak below 35, Fair from 35, Good from 60 and Strong from 80. It comes from the statistics of the last completed run of the project. Assemblies merged into a target count towards its score and show none of their own. A target that has not run yet shows no score.\nThe score counts the protections a run applied and says nothing about how long the result resists a given tool. A lower score can be the right one: a library with a public API keeps its public names, so it earns fewer renaming points.\nRunning Flows in Parallel\nA project with several independent flows, such as libraries that do not reference each other, can obfuscate them at the same time. Turn on Run independent flows in parallel in Settings > Obfuscation and choose how many flows run at once, from 2 to 4. The option is off by default."},{"page":177,"heading":"Running the Project","anchor":"running-the-project","text":"Each flow runs in its own engine process, and inside a flow the targets still run in order. Babel Desktop checks the whole project before any flow starts, as it does for a single run. While the flows run:\nThe progress indicator counts the targets completed out of the targets planned, and each line of the log starts with the name of its assembly, for example [Library1.dll].\nA target that fails stops its own flow. The other flows go on, and the run is reported as failed.\nCancel job stops every flow.\nWhen several targets need a certificate password, Babel Desktop asks for one at a time and names the assembly that needs it.\nEvery engine process takes a couple of seconds to start, so running in parallel saves time with large assemblies. A small project can finish sooner one target after another. With a floating license, Babel Desktop runs one flow at a time.\nTools: Job warnings in the command palette lists the warnings of the current run, and Tools: Warning reference opens the searchable catalog of engine warning codes with their descriptions.\nEngine warning reference dialog with a search box and a list of warning codes such as CF0001, CF0002, EI0001 and EM0001\nThe engine warning reference"},{"page":177,"heading":"Run Results","anchor":"run-results","text":"After a run, the Run results button on the canvas toolbar opens the protection statistics. Choose a run from the history, an obfuscated assembly and a report:\nReport | Content\nRenaming | Renamed and total types, methods, fields, properties and events, with a coverage chart\nControl Flow | Scrambled methods, inserted branch instructions and iterations, with a treemap by namespace and type and, when full statistics are collected, the cyclomatic complexity before and after the transformation\nString Encryption | The encryption algorithm and the encrypted strings by method\nCode Encryption | The encrypted methods by namespace and type\nDynamic Proxy | The proxied calls and delegate types by target method\nOptimizations | Dead code removal and optimization counters\nExecution Time | The duration of each engine phase\nYou can search and sort the tables, and drill down in the treemaps from namespace to type. Show output, Show engine log and Show statistics data open the output folder, the complete engine log and the raw statistics file of the run. Babel Desktop keeps the results of the last 30 runs.\nProtection statistics on the Renaming tab: 540 of 630 symbols renamed (85.71 percent), a radar chart of the coverage by symbol category and symbol count bars, the run and assembly pickers and the Show output, Show engine log and Show statistics data buttons\nRenaming statistics"},{"page":177,"heading":"Run Results","anchor":"run-results","text":"Protection statistics on the Control Flow tab: 234 scrambled methods, 28,990 branch instructions and 5 iterations, and a treemap of the transformed methods by namespace, from BubbleBurst.ViewModel with 58 methods to Thriple.Easing with 8\nControl Flow statistics\nWarning: The statistics files contain original symbol names and string values. Keep them, like the XML map files, away from the distributed application."},{"page":177,"heading":"Decoding Stack Traces","anchor":"decoding-stack-traces","text":"To translate the obfuscated stack traces of a protected application back to the original names with its XML map files, use the Stack Decoder."},{"page":178,"heading":"","anchor":"","text":"A stack trace from an obfuscated application shows obfuscated names. The stack decoder maps them back to the original names using the XML map files produced by the obfuscation. Enable map file generation (GenerateMapOutFile in the Output & diagnostics group) for the assemblies whose stack traces you want to decode.\nOpen the stack decoder\nClick the stack decoder icon in the activity bar, press Ctrl+Shift+D (Cmd+Shift+D on macOS) or run Tools: Stack decoder.\nAdd the map files\nClick Add map files... and select one or more map files, or drag them onto the panel. If the map files were produced with a password, enter it in Map password.\nPaste the trace\nPaste the obfuscated stack trace into Obfuscated trace, or load it from a file with Open trace....\nDecode\nClick Decode. The result appears in Decoded trace; Save decoded trace... writes it to a file.\nStack decoder with the map file Lumenbyte.Inventory.dll.map.xml loaded, the Map password and hide frames options, an obfuscated trace with frames such as d.b and a.Main, and the decoded trace naming InMemoryStockRepository.Adjust and Program.Main\nDecoding a stack trace with its map file\nHide frames Babel added removes the bridge frames that Dynamic Proxy generates, so only your own call chain is left. Clear the check box to keep all frames; each proxy frame is then labeled with the method it stands in for."},{"page":178,"heading":"","anchor":"","text":"When overloaded renaming is enabled, several methods can share one obfuscated name. In that case the decoder lists every original method that could match under the obfuscated frame. Disable overloaded renaming if you need an unambiguous mapping.\nWith Unicode renaming, obfuscated names contain unprintable characters. To avoid losing characters, save the obfuscated trace to a UTF-8 text file and load it with Open trace....\nIf the application was obfuscated with encrypted PDB file names, the decoded trace shows the original source file names; see Using PDB Files.\nError: XML map files reveal the original names of your code. Store them securely and never distribute them with the application.\nFor decoding from the command line or in an automated pipeline, see Decoding Stack Traces. Stack traces contained in exception reports collected by a Babel Licensing Service can be decoded in the Reports view."},{"page":179,"heading":"","anchor":"","text":"Licensing (Server)\nBabel Desktop manages a Babel Licensing Service: customers, products,\norders, licenses, templates, tokens, reports, users, API keys, webhooks and\nserver settings, with a dashboard and an activity globe.\nBabel Desktop calls the REST API of the Babel Licensing Service and authenticates with an API key. It does not connect to the licensing database: the database provider and connection string are configured in the service, as described in Configuration.\nBoth Babel Licensing editions are supported. Babel Desktop can browse any service you connect to, but it can create, edit and delete records only on a service running on the same machine (see Connection Profiles). With a Server license, manage a remote service with the Management API, since the web application requires the Data Center edition. With a Data Center license you can use the web application as well; it works on the same data.\nLicensing in Babel Desktop: the shield icon of the profile Lumenbyte Licensing in the activity bar, the sidebar with the Sales, Licensing, Operations and Administration groups, and the Overview dashboard with tiles for issued licenses, orders, activity events, unexpired tokens, expiring licenses and customers\nA Licensing connection open on its Overview dashboard"},{"page":179,"heading":"Availability","anchor":"availability","text":"Licensing is part of Babel Desktop. There is nothing to install: you add a connection to a service and its icon appears in the activity bar.\nLicensing is available when the license loaded in Settings > License is a Babel Licensing license (Server or Data Center edition), and in an unlicensed installation running in evaluation mode. With any other license, Settings > Licensing connections tells you that the license does not include Licensing. Connections you saved earlier stay listed there until you remove them."},{"page":179,"heading":"Pages in This Section","anchor":"pages-in-this-section","text":"Connecting to a Service: API keys, connection profiles and certificates.\nRoles and Permissions: what each role and key permission allows.\nDashboard: the Overview dashboard, the activity globe and IP geolocation.\nWorking with Records: the list, detail and form conventions shared by every view.\nSales: customers, products, releases and orders.\nLicenses: licenses, license templates, tokens and sign keys.\nReports: diagnostic reports and stack trace decoding.\nOperations: log, traces and webhooks.\nAdministration: users, API keys, server settings and server info.\nSettings and Automation: the settings of a connection and the MCP server."},{"page":180,"heading":"","anchor":"","text":"Connections are managed in Settings > Licensing connections. Open Settings with Ctrl+, (Cmd+, on macOS) and choose Licensing connections. Until you add the first connection, the page is empty and the activity bar has no Licensing icon.\nSettings dialog on the Licensing connections page before any connection: the Add connection button and the text No connections yet. Add a service to start browsing Licensing.\nLicensing connections before the first connection"},{"page":180,"heading":"Creating an API Key","anchor":"creating-an-api-key","text":"Babel Desktop authenticates to the service with an API key. Each key belongs to a user of the service. The key has that user's roles, and its own permissions (Read, Write, Delete, Create) limit what it can do. See Roles and Permissions.\nTo create the first key:\nWith a Data Center license, create the key in the web application.\nWith a Server license, sign in to the service with the Management API and create the key with POST /v1/api-keys, as described in the Management API reference.\nAfter you connect with an Administrator key, you can create more keys in the API keys view."},{"page":180,"heading":"Connection Profiles","anchor":"connection-profiles","text":"Each service you connect to has a connection profile with its own name, icon and API key. You can have several, for example one for a local test service and one for production, and each gets its own icon in the activity bar.\nAdd a connection\nIn Settings > Licensing connections, click Add connection.\nDescribe the service\nFill in the profile:\nDisplay name: the name shown in the activity bar and on every page of the profile.\nEnvironment: Local test, Staging or Production.\nToolbar icon: the icon of the profile in the activity bar (Database, Flask, Cloud, Shield or Layers).\nService endpoint: the address of the service, for example https://licensing.example.com.\nAccess mode: Read-only browsing or Local management · Create, edit and delete.\nEnter the API key\nSet Credentials to Use API key and paste the key in API key. With Add the API key later the profile is saved without a key, and you enter it when you edit the profile.\nSave\nClick Save connection. Babel Desktop checks the key with the service and shows its roles and permissions on the profile card.\nNew connection form filled in: Display name Lumenbyte Licensing, Environment Local test, Toolbar icon Shield, Service endpoint http://localhost:5620, Access mode Local management, Credentials Use API key, a masked API key and the Save connection and Cancel buttons\nA new connection profile\nThe environment determines what a profile can do:"},{"page":180,"heading":"Connection Profiles","anchor":"connection-profiles","text":"Environment | Endpoint | Access\nLocal test | localhost or 127.0.0.1 only, over HTTPS or HTTP | Read-only browsing, or local management with create, edit and delete\nStaging, Production | Any host, HTTPS only | Read-only browsing\nWarning: You can create, edit and delete records only through a Local test profile set to Local management, which means the service must run on the same machine as Babel Desktop. Profiles of remote services are read-only: to change their data, run Babel Desktop on the service machine with a local profile, or use the web application or the Management API.\nThe profile card shows the environment, the access mode, the endpoint and, once the key is accepted, its roles and permissions. Select and open (Open selected on the profile already selected) opens the profile, Edit changes it, Test connection checks authenticated access and Remove deletes the profile and its stored API key; records in the licensing database are not affected.\nSaved connection profile card: Lumenbyte Licensing with the Local test and Local management badges, the endpoint http://127.0.0.1:5620, Administrator with Read, Write, Delete and Create permissions, and the Open selected, Edit, Test connection and Remove buttons. The shield icon of the profile is in the activity bar\nA connection profile with an accepted key"},{"page":180,"heading":"Connection Profiles","anchor":"connection-profiles","text":"A saved profile adds its icon to the activity bar. The tooltip of the icon shows the name, the environment and the access mode. Click the icon to open the profile on its Overview dashboard. The profile also adds a settings category of its own, described in Settings and Automation.\nAPI keys are encrypted in the operating system's secure storage and cannot be viewed again once saved. Changing the endpoint of a remote profile clears its saved key."},{"page":180,"heading":"Self-Signed Certificates","anchor":"self-signed-certificates","text":"Babel Desktop accepts only certificates the operating system trusts and does not follow redirects. When a service presents a certificate that is not trusted, such as a self-signed certificate, Babel Desktop shows a Certificate not trusted warning with the subject, issuer, validity and SHA-256 fingerprint of the certificate. Compare the fingerprint with the certificate installed on the service, then click Trust this certificate. Babel Desktop trusts that one certificate for that service only and retries the connection. You can later forget a trusted certificate; the connection then fails until you trust it again."},{"page":181,"heading":"","anchor":"","text":"The service authorizes every request against the roles of the key owner and the permissions of the key. Babel Desktop follows the same rules in its interface. It hides the views the roles cannot read. An action the key has no permission for stays visible but disabled, with the reason. The service still makes the final decision.\nArea | Views | Administrator | LicenseManager | Sales\nSales | Customers, products, orders | Full | Full | Create and edit\nLicensing | Licenses, license templates, sign keys | Full | Full | Read; export and email licenses\nLicensing | License tokens | Full | Full | —\nLicensing, Operations | Reports, log, traces, webhooks | Full | Full | —\nAdministration | Users, roles, API keys, server settings, server info | Full | — | —\nThe key permissions map to operations: Read for browsing, Create for new records, Write for edits (including revoking a license) and Delete for deletions."},{"page":182,"heading":"","anchor":"","text":"Opening a profile shows its Overview dashboard. Choose the period (7, 30, 90 or 365 days) and click Refresh to reload it; the tooltip of the button tells when the data was read. Each widget loads as soon as its own data arrives, and if a widget's data cannot be read you can retry that widget alone.\nLicensing Overview dashboard for 90 days: tiles for issued licenses, orders, activity events, unexpired tokens, expiring licenses and customers, the order statistics with the change from the previous period, the average order value and the orders by status, the period, Refresh and Customise controls, and the sidebar with the Sales, Licensing, Operations and Administration groups\nThe Overview dashboard\nThe dashboard has these widgets:\nTiles: issued licenses, orders, activity events, unexpired tokens, licenses expiring in the next 30 days and customers. Explore records on a tile opens the matching records for the same period.\nOrder statistics: the order count compared with the previous period, the average order value per currency and the orders by status. Amounts in different currencies are never added together.\nGeographic activity: the activity globe described below.\nActivity over time, Licenses by product and Licensing modes (File, Activation, Floating) charts.\nReports: the diagnostic reports received in the period, by type.\nLog: a histogram of the service log entries by level.\nRecent activity: the latest license events, without the client they came from."},{"page":182,"heading":"","anchor":"","text":"Dashboard charts: the Activity over time bar chart with the Issued licenses selector and the Daily values list, the Licenses by product bars from Lumenbyte Inventory to Lumenbyte Developer SDK, and the Licensing modes bars for Activation, Floating and File\nActivity, product and licensing mode charts\nLower dashboard widgets: Reports with the reports of the period by type (ExceptionReport and LicenseReport), the Log histogram with the Error, Warning and Information counts, and the Recent activity list\nReports, log and recent activity widgets\nPeriods use UTC dates. The dashboard reads at most 10,000 records per dataset and marks a widget as partial when a dataset is larger.\nTo arrange the dashboard, click Customise. Drag a widget by its handle to move it, or hold Alt and press the up and down arrows, then click Done. The order is remembered."},{"page":182,"heading":"Geographic Activity","anchor":"geographic-activity","text":"The Geographic activity widget plots licensing activity on a rotating globe, above a Countries and licenses table with the flag, the activity events and the licenses of each country. For a local management profile, countries come from the country of the customer linked to each licensed order; otherwise activity is placed from the locations recorded with license traces. Drag to rotate the globe, use the mouse wheel, pinch or the + and - buttons to zoom, and click a country marker or a table row to open the licenses of that country.\nGeographic activity widget: a globe with the continents outlined in the theme color and activity markers over Europe, the zoom and reset buttons, the Configure server position button, and the Countries and licenses table with the flags, activity events and licenses of the United States, Italy and Canada\nThe activity globe and the countries table\nFor customer privacy, a country or region appears only when at least three different licenses are in it. The Info button next to the table explains the data source and the thresholds.\nThe globe draws the continents as outlines on a plain sphere, in the colors of the current theme. To see NASA satellite imagery instead, set Settings > Appearance > Globe style to Satellite map; Outlined continents is the default."},{"page":182,"heading":"IP Geolocation","anchor":"ip-geolocation","text":"Babel Desktop can also look up where activity events and the licensing server are located, using an IP geolocation provider (ipapi.is). The lookup is off by default. It is configured per profile in Settings > IP geolocation by an Administrator of a local management profile. Choose the profile in Licensing profile, then set:\nLocate activity events using IP geolocation resolves the events that have no location yet. Private and reserved addresses are never sent to the provider.\nProvider and Provider endpoint select the lookup service.\nAPI key is the provider key, stored in the secure storage of the operating system. Remove saved API key deletes it.\nCache lifetime (hours) controls how long resolved locations are kept in memory.\nResolve server position using IP geolocation places a marker for the licensing server on the globe; alternatively enter Server latitude and Server longitude yourself, which needs no provider. The Configure server position button of the globe opens these settings.\nUse Test connection to check the provider configuration. The Resolve locations action of the Reports and Traces views instead asks the service to resolve missing locations with the geolocation provider configured in the service; see Configuration."},{"page":183,"heading":"","anchor":"","text":"The sidebar of a profile groups the views as Sales, Licensing, Operations and Administration. You can reorder the sidebar items by dragging them, or with Alt+Up and Alt+Down. Views that receive new records, such as Orders, Reports and Log, show a count of the records that arrived since you last opened them.\nAll lists use the same grid:\nThe search box filters as you type. Some lists also accept filters written as label:value, shown as a hint above the grid, for example reseller:yes in Customers, revoked:no in Licenses or level:error in Log.\nClick a column header to sort.\nThe list loads more records as you scroll. The line under the grid shows how many are loaded, for example 50 of 123 loaded.\nRight-click the header row to choose the visible columns, and drag a header to move its column (Alt+Left and Alt+Right from the keyboard). Restore defaults in the same menu brings back the original columns. The choice is remembered per profile and view.\nIn lists with record actions, the first click selects a row and enables the toolbar buttons; a second click or Enter opens the record.\nCustomers list: the search box, the New customer, Edit and Delete toolbar buttons, the reseller:yes/no filter hint and the Company, Country with flags, Email and Reseller columns\nA list with its search box, toolbar and filter hint"},{"page":183,"heading":"","anchor":"","text":"Detail pages show the record in cards, with its related records in tabs and links to the records it refers to. Back returns to where you came from. Forms validate the input before saving, and destructive actions ask for confirmation.\nOn a read-only profile the lists and detail pages work the same way, without the buttons that create, edit or delete."},{"page":184,"heading":"","anchor":"","text":"Customers stores your customers and resellers, with company, contact, address, billing and notes. A reseller can be granted reserved prices on products. The customer detail has Orders, Licenses and Contacts tabs. The Customers list is pictured in Working with Records.\nCustomer detail of Blue Harbor Automation GmbH scrolled to the Address and billing and Notes cards, with the Orders, Licenses and Contacts tabs below: the Orders tab lists the orders of the customer with their status, total and payment, and has its own New order, Edit and Delete buttons\nA customer with its orders\nProducts holds what you license: code, name, price and currency, publisher information and the signature key used for its licenses. A product detail lists its orders and its releases. A release records a version of the product with its name, version, date and description, the assemblies that make it up (name, version, culture and public key token) and its license templates. When the XML map files of the obfuscated release assemblies are stored in the service, Babel Desktop uses them to decode the stack traces of exception reports sent by that release.\nProducts list with the code, name, price and currency of twelve fictional Lumenbyte products, and the New product, Edit and Delete buttons\nThe Products list"},{"page":184,"heading":"","anchor":"","text":"Orders tracks purchases with customer, status, payment and fulfilment information. On the order detail, the Products tab adds, updates and removes the ordered products, and the Licenses tab lists the licenses issued for the order. Order totals are recorded values: the dashboard reports them as recorded, not as recognized revenue.\nOrders list with order number, status (Pending, Processing, Completed, Refunded), total, currency, payment and creation date, sorted with the newest order first\nThe Orders list\nOrder detail O-26003: a summary line with status, total, currency, customer and date, the Order, Payment, Fulfilment and Notes cards, a link to the customer Blue Harbor Automation GmbH, and the Products and Licenses tabs with the Add product, Update product and Remove product buttons above the order lines\nAn order and its products"},{"page":185,"heading":"","anchor":"","text":"Licenses lists the licenses the service has issued. Select a license to enable the toolbar:\nGenerate license creates and signs a new license (see below).\nEdit changes the license terms, licensee and properties; the license is signed again when needed.\nRevoke marks the license as revoked. The service then refuses new activations and floating license requests for it and invalidates its tokens.\nExport license key... saves the signed license as <license id>.licenses in the License export folder set in the settings of the connection.\nEmail the license... sends the license to the licensee with an email template stored in the service.\nDelete removes the license.\nLicenses list with a selected row and the active toolbar: Generate license, Edit, Revoke, Export license key, Email the license and Delete, the revoked:yes/no filter hint and the License id, Type, Licensee, Issue Date, Expire Date and Revoked columns, sorted by issue date\nThe Licenses list with a license selected\nLicense detail licF401E7FD, a Runtime floating XML license for 25 sites with a masked user key, with the Edit, Revoke, Export license key, Email the license and Delete actions and the License, Dates, Licensee, Template, Description and Properties cards, with links to the customer, the order, the template and the signature key\nA license with its dates, licensee, template and properties"},{"page":185,"heading":"","anchor":"","text":"The license detail shows the user key masked. Below the cards, the Tokens tab lists the tokens of the license, with Allocate token and Delete token, and the Traces tab lists its recorded events.\nTo generate a license, click Generate license, pick a template and a signature key, then complete the form. The service builds the license from the template, which supplies the product and the features, fields and restrictions defined there; the form sets what is specific to this license. The key button in User key generates a key from the configured user key format, and the button next to it copies the key.\nGenerate license form with the template Inventory Standard and the signature key Lumenbyte Production RSA selected, the License information group with license id, type and a generated user key with its generate and copy buttons, and the start of the Terms group with mode, sites, format and issue date\nGenerating a license from a template\nThe form continues with four groups:\nTerms: licensing mode (File, Activation or Floating, see Licensing Modes), maximum sites, format, issue date, expiration date, maintenance expiration date, revoked and trace flags, description.\nLicensee: customer, order, licensee name, company and email.\nProperties: assemblies, components, fields and features. See License Properties.\nRestrictions: one card per restriction (trial, usage, hardware, beta, domain, custom). See License Restrictions."},{"page":185,"heading":"","anchor":"","text":"License templates define the licenses you generate; see License Templates. You can create and edit templates, upload a template file and save a template to a file.\nLicense templates list with name, code, type, licensing mode (File, Activation, Floating) and expires after days columns, and the New license template, Edit, Upload template file, Save template file and Delete buttons\nThe License templates list\nLicense tokens lists the tokens issued for activations and floating licenses, with client, machine id, dates and license. Allocate token, on the Tokens tab of a license, assigns a token to that license, and deleting a token releases the activation or seat it holds. See License Tokens.\nLicense tokens list with client, client id, machine id, issue and expire date and license id columns, and the Delete token button\nThe License tokens list\nSign keys stores the RSA and ECDSA key pairs that sign licenses. You can create keys, upload a key file and save a key to a file.\nSign keys list with RSA and ECDSA-P256 keys, their format and creation date, and the New sign key, Edit, Upload key file, Save key file and Delete buttons\nThe Sign keys list"},{"page":186,"heading":"","anchor":"","text":"Reports lists the diagnostic reports that licensed applications send to the service, such as exception reports; see Reporting. Filter the list by type with name:exceptionreport or name:licensereport, by text, or by date range with From date and Through date (UTC dates).\nReports list with the search box, the From date and Through date UTC filters, the Delete and Resolve locations actions, the name filter hint and the Name, Date, Client, Address, Machine id and User key columns\nThe Reports list\nA report detail shows the report metadata and tabs for each collected section: report properties, exception, process, environment variables, loaded assemblies, system and the original content. From the detail you can open the linked license, customer and order.\nExceptionReport detail with the Refresh and Delete buttons, the UID, version, date, client, machine id, address and user key, the Open linked license, Customer, Order and Decode using database maps actions, and the Report properties, Exception, Process, Environment variables, Loaded assemblies, System and Original content tabs\nAn exception report\nException tab of a report with the System.TimeoutException type, the message, the source Lumenbyte.Reporting and three stack trace frames, two of them with obfuscated names\nThe Exception tab"},{"page":186,"heading":"","anchor":"","text":"Decode using database maps decodes the obfuscated stack trace of the report with the map files registered for the matching release assemblies. An assembly matches only when its name, version, culture and public key token are the same as in the report. Decoding requires the Administrator role."},{"page":187,"heading":"","anchor":"","text":"Log: the service log entries, filterable by level with level:verbose|debug|information|warning|error|fatal.\nTraces: license events recorded for licenses with tracing enabled, with client, machine id and client IP address. The events are: license created, updated, activated, deactivated, revoked and reinstated, floating license requested and released, first use on a computer, activation refused, floating license refused and license validated online.\nWebhooks: webhook subscriptions with their event type, URL and state. Send a test event calls the subscription URL with a test payload, and the detail lists the delivered events. Webhook events lists the event types you can subscribe to. See Webhooks.\nLog view with the time, level and message columns, the latest entries of the service, and the level filter hint verbose, debug, information, warning, error, fatal\nThe service log\nTraces list with date, action such as Floating license requested and Floating license released, client, machine id and client IP address columns, and the Resolve locations action\nLicense traces\nWebhooks list with five subscriptions showing name, event type, URL, active state with one paused subscription and creation date, and the New webhook, Edit, Send a test event and Delete buttons\nWebhook subscriptions\nWebhook events view listing the sixteen event types, such as license.created, license.expiring and license.revoked, with their descriptions\nWebhook event types"},{"page":188,"heading":"","anchor":"","text":"These views require the Administrator role.\nUsers: the accounts of the service, with their profile, roles and settings. On the user detail, the Roles tab adds and removes roles.\nAPI keys: create keys for users, set their permissions and expiration date, and revoke or delete them.\nServer settings: the settings of the service, grouped as in the service configuration. A setting value is edited as JSON, so numbers, flags and arrays keep their type. See Configuration.\nServer info: the service version and license edition, the token limit, the server host and time, and license and token counts.\nUsers list with nine fictional users with lumenbyte.example.com email addresses, department and last login, and the New user, Edit and Delete buttons\nUsers\nUser detail m.keller with the Account and Profile cards and the Roles tab showing the LicenseManager role, with the buttons that add and remove a role, next to the Settings tab\nThe roles of a user\nAPI keys list with name, owner, creation date, expire date with an expired Audit export key, and revoked state with the Legacy reseller portal key revoked, and the New API key, Edit and Delete buttons\nAPI keys\nServer settings view with the Group, Name and Type columns, the Serilog settings Using, MinimumLevel, Enrich and WriteTo at the top, and the Edit button\nServer settings"},{"page":188,"heading":"","anchor":"","text":"Server info: Babel Licensing Data Center edition, version 12.0.6.0, the service license with unlimited tokens, server host and time, 121 licenses by mode with the revoked and traced counts, and 147 active tokens with the activation, floating and expired counts\nServer info"},{"page":189,"heading":"Connection Settings","anchor":"connection-settings","text":"Each connection profile adds a category to Settings, named after the profile and its environment, for example Lumenbyte Licensing · Local test · Licensing:\nLicense export folder: where Export license key... saves license files.\nUser key format, License id format, Customer code format and Order number format (Administrator): the formats used to generate these identifiers. They are stored in the service, so the web application and Babel Desktop generate identifiers the same way. See User Key Format for the syntax.\nSettings dialog on the category Lumenbyte Licensing · Local test · Licensing, with the License export folder, the User key format {TOKEN:5}-{TOKEN:5}-{TOKEN:5}-{TOKEN:5}, the License id format lic{HEX:8}, the Customer code format C-{TOKEN:8} and the Order number format O-{TOKEN:8}, above the Licensing connections section\nThe settings of a connection\nThe connections themselves are added, edited and removed in Settings > Licensing connections, as described in Connecting to a Service, and the IP lookup of the activity globe is set in Settings > IP geolocation, described in Dashboard."},{"page":189,"heading":"Automation","anchor":"automation","text":"When the MCP server of Babel Desktop is enabled, an AI assistant can work on the selected profile: read records, dashboards and reports, and propose changes that you confirm before they run. The same roles, permissions and profile restrictions apply."},{"page":190,"heading":"","anchor":"","text":"Babel Desktop is extended with declarative packages that add themes, commands\nand application views.\nAn extension is a JSON manifest that declares what the extension adds. It can be packed together with a description, pictures and translations. Extensions can add:\nThemes, which recolor the whole application, including the canvas, the charts and the Licensing globe.\nCommands in the command palette that run a built-in action, such as opening the XML rules of the selected target.\nApplication views (lists, detail pages, forms and dashboards) bound to a REST service. The built-in Licensing views of Babel Desktop are described the same way.\nAn extension cannot run arbitrary code or inject styles or markup, and it has no direct access to the file system, the network or your projects. A view extension can reach only the service it declares, and only through Babel Desktop over HTTPS (plain HTTP is accepted only for a local test service on localhost). If an extension includes validation scripts, they run in isolation with no network or file-system access. Babel Obfuscator engine plugins are unrelated to extensions: they are .NET assemblies that the engine loads, configured per target."},{"page":190,"heading":"The Extensions View","anchor":"the-extensions-view","text":"Click the Extensions icon in the activity bar (Ctrl+Shift+X, Cmd+Shift+X on macOS). The view groups packages in sections:\nInstalled: the installed extensions; disabled ones are marked Disabled.\nGallery: the extensions published in the Babel extensions gallery that are not installed yet.\nUnavailable: installed packages that the current license does not enable, with the reason.\nA fresh installation has nothing installed, and the Gallery section lists the theme packages you can add.\nExtensions view on a fresh profile: the Installed section with no extensions, the Gallery section listing the Amethyst and Copper theme packages with their version and author, and the note Gallery updated\nThe Extensions view on a fresh installation\nThe Gallery\nBabel Desktop reads the gallery from the Babel servers with your license key, so the list matches what your license can install. To install an extension, select it and click Install: Babel Desktop downloads the package, checks it against the gallery entry and shows its permissions before installing. The last list is kept for when you are offline; installing needs a connection.\nSome gallery extensions are limited to certain editions or to licenses under maintenance:"},{"page":190,"heading":"The Extensions View","anchor":"the-extensions-view","text":"An extension your edition does not include is tagged with the editions it requires, for example Requires Server or Data Center, and its page has a View plans button.\nWhen the maintenance of your license has ended, you can install the last version published before that date. Newer versions are tagged Update needs maintenance, with a Renew maintenance button.\nA package that needs a newer application is tagged Needs a newer Babel Desktop and cannot be installed until you update.\nIf the gallery does not recognise your license key, or the license is expired or revoked, a note under the list says so and the licensed extensions are left out.\nSelect an extension to open its page. The header shows the name, author, version and state, plus whichever of these buttons apply to that state: Install, Enable or Disable, Uninstall and Settings. The page has three tabs:\nDetails: the description of the extension and the permissions it requests.\nFeatures: what the manifest adds, such as themes, commands and views.\nChangelog: the changes in each version.\nThe Installation column lists the identifier, version, API version, license, requirements and the SHA-256 hash of the manifest.\nPage of the installed Copper theme extension: README describing Copper Night, Copper Day and the Open XML rules command, the themes and commands permissions, the MIT license and the SHA-256 hash\nThe Copper theme extension"},{"page":190,"heading":"The Extensions View","anchor":"the-extensions-view","text":"The gear menu on each row has the same actions. Disabling an extension removes what it added. If the extension connects to a service, disabling it also signs out and deletes the stored credentials."},{"page":190,"heading":"Development Versions","anchor":"development-versions","text":"An extension from the gallery can have a development version: a newer one that has had less testing than the stable version. You see it only if your license may install the stable version, and only when it runs on your version of Babel Desktop.\nThe page of an installed extension shows Development version ... is available. with a Try it button. If that version needs a newer Babel Desktop, the button is disabled and the page says Needs a newer Babel Desktop. Try it asks for the same confirmation as an install. Afterwards the extension carries the Development tag in the list, and its page says You are using a development version.\nAn extension on the development channel is offered the newest version that your Babel Desktop can run, development or stable, and stays on the development channel. An extension on the stable channel is never updated to a development version. Each extension follows its own channel: trying one does not change the others, or Babel Desktop itself.\nBack to stable, followed by the version number, installs the stable version the gallery names. It can be older than the one you have, and this is the only case in which Babel Desktop installs an older version of an extension. It asks for the same confirmation as an install. If the development version you have was promoted to stable in the meantime, Back to stable only removes the Development tag and downloads nothing."},{"page":190,"heading":"Installing from a File","anchor":"installing-from-a-file","text":"Open the Extensions view\nClick the Extensions icon in the activity bar (Ctrl+Shift+X, Cmd+Shift+X on macOS).\nChoose Install from file\nOpen the More actions menu of the Extensions view and choose Install from file....\nSelect the package\nSelect a .babelext package or an extension.json manifest.\nReview and install\nBefore installing, Babel Desktop validates the package and shows its author, license, requested permissions and changelog. Confirm to install it.\nExtensions are never updated without your action. When a newer version of an installed extension is available, its row shows Update available and the Extensions icon in the activity bar gets a count badge. Click Update to install it. If the new version asks for new permissions, you see them first. If the update fails, the installed version is left as it was.\nInfo: Some extensions require a license feature. A package the license does not enable is listed with a Requires license tag and cannot be installed or enabled. Licensing is not an extension: it is built into Babel Desktop and is set up in Settings > Licensing connections.\nTo create your own extension, start from a theme; extensions can also ship translations."},{"page":191,"heading":"","anchor":"","text":"Themes restyle the whole application: the colors of the canvas, the charts\nand the Licensing globe, and also the shape of the controls, the fonts and\nthe icons."},{"page":191,"heading":"Choosing a Theme","anchor":"choosing-a-theme","text":"Open the Appearance settings\nOpen Settings (Ctrl+, on Windows and Linux, Cmd+, on macOS) and choose Appearance.\nPick a theme\nChoose the theme in Settings > Appearance > Theme. System follows the light or dark appearance of the operating system, Light and Dark are the built-in themes, and each enabled extension adds its themes to the list. When a theme family has both a light and a dark theme, such as Copper Night and Copper Day, the list also offers Copper (follow system), which switches between the two as the operating system does.\nCheck the result\nThe theme changes right away. The Globe style of the Licensing dashboard is set in the same dialog.\nYou can also switch theme without opening the settings: run the Appearance command of the theme from the command palette, for example Appearance: Pixel, or click the Settings icon at the bottom of the activity bar and choose a theme in the Themes submenu.\nSettings dialog on the Appearance page rendered in the Copper Night theme, with the Interface language, Theme set to Copper Night, Globe style settings and the Application category\nSettings in the Copper Night theme\nLicensing dashboard rendered with the Copper Night theme, with themed tiles, sidebar and activity bar\nThe Licensing dashboard in the Copper Night theme\nDensity and Text Size\nA theme sets how tightly the controls are packed and how large the text is. Density and Text size in Settings > Appearance change the two values for every theme:"},{"page":191,"heading":"Choosing a Theme","anchor":"choosing-a-theme","text":"Setting | Values\nDensity | Follow theme, Compact, Normal, Comfortable\nText size | Follow theme, Small, Normal, Large\nFollow theme, the default, uses the values of the active theme."},{"page":191,"heading":"Sample Themes","anchor":"sample-themes","text":"Babel publishes a set of theme packages as samples. They are listed in the Extensions view; install one and its themes appear in Settings > Appearance > Theme.\nPackage | Themes | Look\nCopper | Copper Night, Copper Day | Copper accents on charcoal or on parchment, and a command that opens the XML rules\nAmethyst | Amethyst Night, Amethyst Day | Amethyst accents on deep plum or on lilac, with its own activity bar icons\nParchment | Parchment Day, Parchment Night | Paper and ink: textured surfaces, stamped buttons and hand-drawn icons\nPixel | Pixel | Light grey with pixel fonts, pixel-art icons and square controls\nParchment and Pixel carry pictures and need Babel Desktop 0.3.0 or later. An older version lists them as needing a newer Babel Desktop and does not install them.\nPixel\nPixel is a single light theme, so it does not follow the appearance of the operating system. The package holds no code: it restyles the application with color tokens, shape settings, three font files and SVG pictures.\nProject canvas in the Pixel theme: light grey panels, a dark grey activity bar, square nodes with thick borders, pixel-art icons and a pixel Babel logo on the target BubbleBurst.exe, whose card shows an obfuscation score of 92 graded Strong, and the Activity panel with the engine log in a monospaced pixel font\nThe project canvas and the target card in the Pixel theme\nIt changes:"},{"page":191,"heading":"Sample Themes","anchor":"sample-themes","text":"Colors: light grey panels and status bar, with one dark grey for the activity bar, the primary buttons, the active tab and the focus ring. Charts use a grey ramp with two muted hues, steel blue and ochre.\nFonts: the interface is set in Pixel Operator and monospaced text in Departure Mono. Both fonts are in the package.\nShape: square corners, thick borders, boxed tabs and outlined fields.\nIcons and logo: the 44 icons of the interface are redrawn as pixel art on a 16 by 16 grid, and the Babel logo is drawn in pixels too.\nCheck boxes and radio buttons: a square pixel frame and a stepped circle replace the system controls.\nProtection statistics in the Pixel theme: boxed tabs with Renaming selected, the counters 540 symbols renamed, 630 eligible symbols and 85.71 percent coverage in a pixel font, and the radar chart and symbol count bars drawn in dark grey and steel blue\nRun results in the Pixel theme\nSettings dialog on the Appearance page in the Pixel theme, with Interface language set to English, Theme set to Pixel, Globe style, and Density and Text size both on Follow theme\nSettings in the Pixel theme\nPixel fonts are drawn on a pixel grid and look sharpest at sizes that are multiples of it. If the text looks soft or small, choose a larger Text size."},{"page":191,"heading":"Creating a Theme","anchor":"creating-a-theme","text":"A theme is a small extension. It starts from the built-in light or dark palette (base) and overrides only the color tokens you list; the rest are inherited. Setting just accent, for example, is enough to recolor buttons, links, selections and globe markers."},{"page":191,"heading":"Creating a Theme","anchor":"creating-a-theme","text":"Write the manifest\nCreate an extension.json file that declares one theme or a light and dark theme family:\n{\n  \"apiVersion\": 1,\n  \"id\": \"acme.teal\",\n  \"name\": \"Teal\",\n  \"version\": \"1.0.0\",\n  \"author\": \"Acme\",\n  \"license\": \"MIT\",\n  \"description\": \"A teal theme family for Babel Desktop.\",\n  \"minApp\": \"0.1.0\",\n  \"minEngine\": \"12.0.0\",\n  \"permissions\": [\"themes\"],\n  \"contributes\": {\n    \"themes\": [\n      {\n        \"id\": \"teal-night\",\n        \"name\": \"Teal Night\",\n        \"base\": \"dark\",\n        \"family\": \"Teal\",\n        \"colors\": { \"accent\": \"#2cc7b5\", \"canvas\": \"#0f1a1c\", \"activity-bg\": \"#0b1416\" }\n      },\n      {\n        \"id\": \"teal-day\",\n        \"name\": \"Teal Day\",\n        \"base\": \"light\",\n        \"family\": \"Teal\",\n        \"colors\": { \"accent\": \"#0f8a7c\" }\n      }\n    ]\n  }\n}\nFollow the manifest rules\nid has the form publisher.name in lower case, and version, minApp and minEngine are three-part versions.\nbase is light or dark. A family pairs at most one light and one dark theme.\ncolors accepts only the documented tokens, each as a six-digit hex value. The tokens cover the base palette (bg, panel, panel-alt, text, muted, line, accent, accent-hover, accent-soft, on-accent, selection, focus, link), the status colors (success, warning, error and their -bg surfaces), the canvas, log and status bar, the activity bar, badges, dashboard tiles, chart series and the globe. An unknown token is rejected with the list of valid names."},{"page":191,"heading":"Creating a Theme","anchor":"creating-a-theme","text":"An optional icons object replaces named icons, such as activity.settings or canvas.run, with simple vector shapes. SVG markup is not accepted here; to use SVG files, add a skin.\nA package can also contribute commands that run a built-in action (open-assembly, open-project, save, run, cancel, tab-settings, tab-rules, tab-activity, graph-fit, plugins); this requires the commands permission.\nInstall the theme\nSave the manifest as extension.json and install it with Install from file... in the Extensions view.\nPackage it for distribution\nIf you want to distribute the theme with a description, pictures and translations, pack it as a .babelext package: a ZIP archive that contains extension.json, a mandatory README.md shown on the Details tab, optional translated README.<locale>.md files, pictures in a media folder and extension translations in a locales folder. The MIT-licensed Babel Desktop Extension SDK provides the manifest schema and the babel-extension command that validates and packs packages.\nIncrease version whenever you change a theme, then install the new package over the old one.\nShape, Controls and Type\nBesides colors, a theme can set shape, controls and type. All three are optional, and a member you leave out keeps its default."},{"page":191,"heading":"Creating a Theme","anchor":"creating-a-theme","text":"{\n  \"id\": \"teal-night\",\n  \"name\": \"Teal Night\",\n  \"base\": \"dark\",\n  \"family\": \"Teal\",\n  \"shape\": { \"radius\": \"small\", \"density\": \"compact\", \"border\": \"thin\" },\n  \"controls\": { \"button\": \"outline\", \"tabs\": \"boxed\", \"field\": \"underline\" },\n  \"type\": { \"body\": \"sans\", \"size\": \"normal\" },\n  \"colors\": { \"accent\": \"#2cc7b5\" }\n}\nMember | Values | Default\nshape.radius | none, small, medium, large, round | medium\nshape.density | compact, normal, comfortable | normal\nshape.border | thin, normal, thick | normal\ncontrols.button | solid, outline, pill | solid\ncontrols.tabs | underline, pill, boxed | underline\ncontrols.field | outlined, filled, underline | outlined\ntype.body | system, sans, serif, rounded, mono or font:<fontId> | system\ntype.mono | mono or font:<fontId> | mono\ntype.size | small, normal, large | normal\nThe named font families are fonts already installed on the computer; nothing is downloaded. The Density and Text size settings of the user, when they are not on Follow theme, take precedence over shape.density and type.size. A manifest that uses any of these members must declare minApp 0.2.0 or later.\nFonts\nA .babelext package can ship its own fonts. Declare them in contributes.fonts and select one with font:<fontId>:"},{"page":191,"heading":"Creating a Theme","anchor":"creating-a-theme","text":"\"fonts\": [\n  { \"id\": \"inter\", \"family\": \"Inter\", \"file\": \"fonts/Inter-Regular.woff2\", \"weight\": 400, \"style\": \"normal\", \"license\": \"OFL-1.1\" },\n  { \"id\": \"inter-semibold\", \"family\": \"Inter\", \"file\": \"fonts/Inter-SemiBold.woff2\", \"weight\": 600, \"style\": \"normal\", \"license\": \"OFL-1.1\" }\n]\nFont files are WOFF2 files in the fonts folder, at most 1 MiB each and 4 MiB in total.\nlicense is required and must be OFL-1.1, Apache-2.0, MIT, CC0-1.0 or Ubuntu-1.0.\nEvery declared file must be in the package and every font file must be declared. Fonts are never loaded from the network, and a bare extension.json cannot declare them.\nA family used for type.body needs a face of weight 600 or more next to the regular one.\nSkins\nA skin adds pictures to a theme. It has four optional parts:\nPart | Content\nsurfaces | Textures behind window, titlebar, activitybar, sidebar, canvas, panel, dialog and statusbar\ncontrols | Faces for button.primary, button.secondary, button.icon, tab, tab.active and field, and pictures for checkbox and radio\nicons | SVG files for the icon slots\nlogo | A PNG or SVG file that restyles the Babel logo on the start screen, in the About dialog and on the primary targets of the canvas"},{"page":191,"heading":"Creating a Theme","anchor":"creating-a-theme","text":"\"skin\": {\n  \"surfaces\": { \"window\": { \"image\": \"skins/paper.png\", \"layout\": \"tile\" } },\n  \"controls\": { \"button.primary\": { \"image\": \"skins/stamp.svg\", \"slice\": [10, 12, 10, 12], \"ink\": \"#ffffff\", \"tone\": \"#6b3fa0\" } },\n  \"icons\": { \"canvas.run\": { \"file\": \"skins/run.svg\" } },\n  \"logo\": { \"file\": \"skins/mark.svg\", \"mode\": \"tint\" }\n}\nPictures sit directly in the skins folder: PNG files up to 512 KiB and 2048 pixels a side, with an optional @2x file at twice the size, and SVG files up to 64 KiB. The whole folder stays within 4 MiB.\nA control face is cut in nine parts by slice, four whole numbers for top, right, bottom and left, so it stretches without deforming its corners. It also declares the text color ink and the background color tone, with a contrast of at least 4.5:1.\nAn icon or a logo with mode tint, the default, is painted in the color the application already uses in that place; color keeps the colors of the file.\nSVG files are checked before they are used: scripts, styles, external references and entities are refused.\nEvery file in the folder must be used and every file named in the manifest must be present. A bare extension.json cannot have a skin.\nA manifest with a skin must declare minApp 0.3.0 or later. The application icon and the installer cannot be themed."},{"page":192,"heading":"","anchor":"","text":"The Babel Desktop interface is available in English, Italian, French, German,\nSpanish and Japanese, and more languages can be added with language packages."},{"page":192,"heading":"Changing the Language","anchor":"changing-the-language","text":"Open the Appearance settings\nOpen Settings (Ctrl+, on Windows and Linux, Cmd+, on macOS) and choose Appearance.\nChoose the interface language\nSelect the language in Interface language. The interface is available in English, Italian, French, German, Spanish and Japanese.\nKeep working\nThe change takes effect right away, with no restart. Open views, form values, unsaved project changes and running jobs are kept.\nSettings dialog after switching the Interface language to Italiano: the whole interface is localized, with Impostazioni, Aspetto and Tema Chiaro\nThe interface in Italian\nOnly the interface is translated. Engine option names, engine log messages, source code and the records in your licensing database stay as they are."},{"page":192,"heading":"Language Packages","anchor":"language-packages","text":"To add another language, install a language package: a single UTF-8 JSON file, no larger than 2 MB, that maps each English interface text to its translation.\nWrite the package\n{\n  \"schemaVersion\": 1,\n  \"locale\": \"fr\",\n  \"name\": \"Français\",\n  \"version\": \"1.0.0\",\n  \"strings\": {\n    \"Save\": \"Enregistrer\",\n    \"Open {p0}\": \"Ouvrir {p0}\"\n  },\n  \"sha256\": \"<SHA-256 of JSON.stringify(strings)>\"\n}\nFollow the package rules\nlocale is a BCP 47 language tag and version a three-part version.\nEvery placeholder of the English text, such as {p0}, must be kept in the translation.\nsha256 is the hexadecimal SHA-256 hash of the strings object serialized with JSON.stringify, used to detect a corrupted file. In Node.js: createHash('sha256').update(JSON.stringify(pkg.strings)).digest('hex').\nInstall the package\nChoose Settings > Appearance > Install language package... and select the file.\nTexts a package does not translate appear in English, and entries for texts the application no longer uses are ignored. A package therefore keeps working after application updates. Settings > Appearance shows how many texts of the current version a package covers. A package cannot replace English, run scripts or download resources."},{"page":192,"heading":"Extension Translations","anchor":"extension-translations","text":"Extensions can carry their own translations. A .babelext package can include locales/<language>.json files for the texts in its manifest and translated README.<locale>.md descriptions. Babel Desktop uses them when the interface is set to that language."},{"page":193,"heading":"","anchor":"","text":"Babel Desktop can host a local Model Context Protocol (MCP) server, so an AI\nassistant such as Claude Code can open projects, change settings, run the\nobfuscation, decode stack traces and work with Babel Licensing.\nMCP is an open standard that AI assistants use to call external tools. Any MCP client with Streamable HTTP transport support can connect. The assistant works in the application you have open: projects it edits and runs it starts show up on the canvas, and it sees the changes you make in the window.\nSome example requests:\nOpen ~/Projects/Acme/Acme.babel, enable dynamic proxy and map file generation for Acme.exe, run the obfuscation and tell me about any warnings.\nAdd Acme.Core.dll to the project and merge it into Acme.exe, then show me the renaming statistics of the next run.\nDecode the stack trace in crash.txt with Acme.exe.map.xml and tell me which of my methods threw.\nShow me the licenses expiring in the next 30 days and the customers they belong to.\nSwitch the interface to the Copper Night theme and take a screenshot of the dashboard.\nWhat does dynamic proxy do? If it makes sense for Acme.exe, enable it and explain why."},{"page":193,"heading":"Enabling the Server","anchor":"enabling-the-server","text":"The server is off by default and does not listen until you enable it.\nOpen the MCP settings\nOpen Settings and choose MCP.\nEnable the server\nTick Enable the automation server. The status line changes to Running and shows the server address, http://127.0.0.1:8765/mcp with the default port. As long as the setting stays on, the server starts whenever Babel Desktop starts.\nChoose the port\nLeave Port at 8765 unless another program on the machine already uses it.\nProtect the server with a token\nTick Require an access token and click Generate. Clients must then send the token in the X-Babel-Token header. Without a token, any program running under your user account on the machine can connect, so require one on a shared machine.\nSettings on the MCP automation server page: the Enable the automation server check box, the status Running at http://127.0.0.1:8765/mcp, the Port field, the Require an access token check box with the Generate and Copy buttons, the client configuration JSON and the Copy configuration, Copy Claude Code command and Show file buttons\nSettings > MCP\nChanges apply immediately. Unticking Enable the automation server stops the server; changing the port or the token restarts it and disconnects the connected clients. The command palette also offers MCP: Start local server (project read/write), MCP: Stop local server, MCP: Show status and MCP: Reveal client configuration file."},{"page":193,"heading":"Connecting a Client","anchor":"connecting-a-client","text":"The Client configuration section of the MCP settings generates a configuration for the current port and token. Click Copy configuration and paste it into the MCP configuration of your client:\n{\n  \"mcpServers\": {\n    \"babel-obfuscator\": {\n      \"type\": \"http\",\n      \"url\": \"http://127.0.0.1:8765/mcp\",\n      \"headers\": {\n        \"X-Babel-Token\": \"paste-the-token-from-settings-mcp\"\n      }\n    }\n  }\n}\nWithout a required token, the headers block is omitted. Show file... reveals the configuration file that Babel Desktop writes for the running server.\nFor Claude Code, click Copy Claude Code command and run the copied command in a terminal:\nclaude mcp add --transport http babel-obfuscator http://127.0.0.1:8765/mcp \\\n  --header \"X-Babel-Token: paste-the-token-from-settings-mcp\"\nStart Babel Desktop first, then the assistant. To check the connection, ask the assistant to take a screenshot of the Babel Desktop window.\nWarning: Treat the token like a password and keep it out of reports, tickets and source control. Anyone who has it can operate Babel Desktop on the local machine with your permissions."},{"page":193,"heading":"What the Assistant Can Do","anchor":"what-the-assistant-can-do","text":"The server makes the application's features available as MCP tools, grouped as follows:"},{"page":193,"heading":"What the Assistant Can Do","anchor":"what-the-assistant-can-do","text":"Area | Tools\nApplication | app_get_state, app_info, app_settings, app_set_theme, app_set_globe_style, language_list, language_set, language_install, mcp_configure, app_restart, desktop_screenshot\nUpdates | app_update_status, app_update_check, app_update_install\nEngine license | license_info, license_load, license_clear, license_activate, license_deactivate, license_floating, license_release, license_configure\nProjects and targets | project_info, project_graph, graph_layout, project_open, project_save, assembly_list, assembly_add, assembly_select, assembly_remove\nSettings and rules | settings_list, settings_get, settings_set, project_rules, project_set_xml_rules, rules_validate, rules_read, rules_save\nRuns and results | obfuscate_start, obfuscate_cancel, obfuscate_status, results_list, results_read, results_table\nTools | stack_decode, trace_read, trace_save, warning_reference, plugin_arguments\nExtensions | extensions_list, extension_install, extension_state, extension_readme, extension_settings, extension_settings_save and the other extension_* tools\nLicensing | licensing_profiles, licensing_profile_save, licensing_profile_test, licensing_profile_select, licensing_layout, licensing_read, licensing_dashboard, licensing_globe_details, licensing_report, licensing_geolocation, licensing_prepare, licensing_confirm\nConfirmed changes | desktop_prepare, desktop_confirm\nDocumentation | docs_search, docs_read, docs_list"},{"page":193,"heading":"What the Assistant Can Do","anchor":"what-the-assistant-can-do","text":"Setting names are the Babel Obfuscator option names shown in the properties panel, so the assistant can use the Babel task reference to choose values. You do not need to name tools. Describe the result you want and the assistant chooses them.\nConfirmed Changes\nOperations that could lose work or overwrite files take two steps. The assistant first prepares the operation and gets back a proposal describing what will happen, for example which output files a run will replace or which record a delete will remove. It has to show you the proposal and get your approval before it confirms the operation. A proposal expires after two minutes and can be used only once. It is refused if the project, the files or the record have changed since it was made.\nTwo-step confirmation covers:\ncreating a new project, replacing an input, removing a target, editing the graph and dependencies, and starting a run (obfuscate_start returns a proposal);\nthe setup commands: merging into the main assembly, public obfuscation and the protection level of a target;\ninstalling and uninstalling extensions and removing a Licensing connection profile;\ncreating, editing, revoking and deleting Licensing records (licensing_prepare and licensing_confirm).\nChanging settings or XML rules requires the current project revision, which stops an assistant from overwriting changes it has not seen.\nObfuscation Runs"},{"page":193,"heading":"What the Assistant Can Do","anchor":"what-the-assistant-can-do","text":"A run the assistant starts is no different from one you start in the window. It writes output to the same locations, reports progress in the Activity panel and can be cancelled from either side. The assistant polls obfuscate_status until the run completes, then reads the statistics with results_read and results_table. While a run is active, the project cannot be changed.\nLicensing\nThe Licensing tools act on the Licensing connection profiles, with the roles and permissions of the profile's API key. Records can be created, edited and deleted only through a Local test profile with the local management access mode; remote and read-only profiles refuse every change. Responses leave out secrets such as license keys, API keys, tokens and IP addresses. The dashboard tools return only aggregate data.\nWhat Stays in the Window\nThe assistant cannot do the following; they are left to you in the window:\nentering credentials: signing in with an API key and generating the MCP token;\nanswering password prompts during a run, and decoding stack traces with password-protected map files;\nstarting and stopping the MCP server itself."},{"page":193,"heading":"Babel Documentation Tools","anchor":"babel-documentation-tools","text":"The server also gives the assistant the documentation you are reading now. When you ask how something works or how to do it, the assistant searches the documentation, reads the relevant section and answers with links to the pages it used, before it changes any setting. The server tells connected clients to work this way, so you do not need to name the tools.\nTool | What it does\ndocs_search | Searches the Babel Obfuscator, Babel Licensing, Babel Desktop and API Reference documentation. It takes a query of up to 500 characters, an optional section (obfuscator, licensing, desktop or api) and an optional limit from 1 to 20 (8 by default). Each result has the page title, the section heading, the page path, a link to the heading and a short excerpt\ndocs_read | Returns a page as Markdown, by the path that docs_search or docs_list returned. With a heading, it returns only that section. Pages longer than 200 KiB are cut, with a note to ask for a single section. For an unknown path, it names the closest paths\ndocs_list | Lists the pages with path, title and description, for all sections or for one\nThe documentation tools only read, and they connect only to https://docs.babelfor.net. The search runs on your machine: your question is not sent to the documentation site. The tools download the search index and the pages they read, which are the same public files described in Using the Documentation with AI.\nSome example requests:"},{"page":193,"heading":"Babel Documentation Tools","anchor":"babel-documentation-tools","text":"How do I exclude a type from renaming with XML rules? Change the rules of this project accordingly.\nSearch the licensing documentation for how my application should release a floating license when it closes.\nRead the Stack Decoder page and explain which map file I need for a release build.\nOffline Use and Updates\nBabel Desktop keeps the downloaded index and pages in a docs-cache folder in your user profile.\nThe index is checked for changes at most once every 24 hours. A page is downloaded again only when it has changed on the site.\nTo get the latest version sooner, ask the assistant to refresh the documentation. The tools accept refresh: true for this.\nWithout a network connection, the tools answer from the cached copy and mark the result as stale, with the date of the copy.\nAfter a failed connection or an error from the site, the tools use the cache for 10 minutes before they try the site again.\nInfo: The tools need to reach the site once to build the cache. Until then, offline, they return: Babel documentation is not available offline yet: connect to the internet once, or open https://docs.babelfor.net."},{"page":193,"heading":"Security","anchor":"security","text":"The server is off by default and listens only after you enable it.\nIt binds to 127.0.0.1, so other machines cannot reach it.\nWith Require an access token on, any request without the correct X-Babel-Token header is rejected.\nRequest sizes, sessions, connections and timeouts are limited, and the host and origin of each request are validated.\nNo tool runs arbitrary commands, SQL or URLs.\nThe documentation tools connect only to https://docs.babelfor.net, without following redirects, and only read.\nThe assistant has the same access to your projects and files that you have in Babel Desktop. It can change project settings, run obfuscations and, after confirmation, replace output files. If you let an assistant explore freely, give it a copy of the project, and turn the server off when you are not using it."},{"page":193,"heading":"Troubleshooting","anchor":"troubleshooting","text":"Symptom | Cause | Fix\nThe client cannot connect | Babel Desktop is not running, or the server is not enabled | Start Babel Desktop and check the status line in Settings > MCP\nEvery call is rejected as unauthorized | The token is missing or out of date | Copy the configuration again after generating a token\nThe server does not start | The port is already in use | Choose another port in Settings > MCP\nA confirmation is refused | The proposal expired or the project changed | Ask the assistant to prepare the operation again\nLicensing changes are refused | The profile is remote or read-only, or the API key lacks the role or permission | Use a Local test profile with local management and a key with the required permissions\nThe Babel Licensing Service has its own MCP server, which works remotely with the service API; see AI Integration for a comparison."},{"page":194,"heading":"","anchor":"","text":"Babel Desktop checks for new versions through a signed update feed served by\nbabelfor.NET, downloads them in the background and installs them when you\nrestart the application."},{"page":194,"heading":"How Updates Work","anchor":"how-updates-work","text":"Babel Desktop checks for updates at start-up, every four hours while it runs and whenever the loaded license changes. When a new version is available for your platform and license, the application downloads it and shows a Restart to update banner on the canvas. Click Restart now to install the update and restart, or Later to hide the banner.\nBabel Desktop does not install an update while an obfuscation is running or the project has unsaved changes. Save your work or let the run finish, then restart.\nBabel Desktop checks the signature of the update feed before using it. If the signature is invalid, the feed is refused and the check is reported as failed.\nInfo: Automatic updates apply to the per-user Windows installer (EXE), the macOS application and the Linux AppImage. The Windows MSI and the Linux DEB and RPM packages are managed by your deployment tools or package manager: in these installations updates show as disabled, and you upgrade by installing the package of the new version. See Install."},{"page":194,"heading":"Update Settings","anchor":"update-settings","text":"The Application category of Settings shows the installed version and controls updates:\nDownload and install updates automatically: on by default. When it is off, Babel Desktop only reports a new version, and Download now starts the download.\nCheck for updates checks the feed immediately. The same check is available as Check for Updates... in the application menu on macOS and in the Help menu on Windows and Linux.\nThe status line below the buttons shows the result of the last check, the download progress, or why updates are disabled. When an update is available, its release notes appear underneath.\nSettings dialog in the light theme with the Appearance category (Interface language English, Install language package, Theme Light, Globe style) and the Application category (Version, the automatic download and install check box, the Check for updates button and the status Updates are disabled (unpackaged))\nSettings > Application, here in a development build where updates are disabled"},{"page":194,"heading":"Development Versions","anchor":"development-versions","text":"Some versions of Babel Desktop are published first as development versions: newer builds that have had less\ntesting than a stable release. You receive stable versions unless you choose otherwise.\nWhen a development version is available for your license, Settings > Application shows Development version ... is available. with its release notes and a Try it button. When there is nothing else to tell you, the banner on the canvas shows the same offer. Click Later to hide the banner: it stays hidden until a different version is offered.\nTry it downloads the version that was offered. If it is no longer offered for your license, or the download fails or is cancelled, nothing is downloaded and Babel Desktop stays on the stable channel. When the download is complete, the banner asks you to restart. From then on Babel Desktop follows the development channel and offers the newest version of either kind, so a stable release that comes out later reaches you too.\nWhile you are on the development channel, Settings > Application says You are using a development version. To return, click Back to stable, followed by the version number:"},{"page":194,"heading":"Development Versions","anchor":"development-versions","text":"If a stable version newer than the one you run is available, Babel Desktop updates to it.\nOtherwise it downloads the stable version named on the button, which is older than the one you run, and installs it when you restart.\nIf the version you run has become the stable version in the meantime, there is nothing to go back to. The panel says You receive development versions of Babel Desktop. and Stop receiving development versions leaves the channel without installing anything.\nBabel Desktop goes back only to the version shown on the button. If the update service names a different one when you click, nothing is downloaded and the button shows the new version. If going back fails or is cancelled, nothing changes and you can click the button again.\nThe same license, platform and maintenance rules apply to development and stable versions. In installations where updates are disabled, nothing is offered."},{"page":194,"heading":"What Babel Desktop Reports","anchor":"what-babel-desktop-reports","text":"Babel Desktop sends a short report to the licensing service at start-up and periodically while it runs. It contains:\nthe version of Babel Desktop, its update channel (stable or development) and the platform, for example Windows x64;\na random identifier of the installation;\nfor each extension installed from the gallery, its identifier, version and channel.\nThe identifier is not derived from your hardware, your user name or your license. When a license is activated, the report is linked to that license. Like any request the application makes, the report also carries the standard request headers and comes from your IP address.\nThe report does not contain project names, paths or file contents, or any other setting. Extensions that you made yourself or that come with the application are not listed, and neither are extensions installed from a file. The exception is an extension installed from a file with an earlier version of Babel Desktop: it is listed if the gallery has an extension with the same identifier.\nThe report is sent also when automatic updates are off, and there is no setting that turns it off. The service keeps the latest report of each installation and deletes it 180 days after the last one."},{"page":194,"heading":"License and Maintenance","anchor":"license-and-maintenance","text":"Which updates you receive depends on the license loaded in Settings > License:\nPlatform | Updates require\nWindows | Any valid Babel license\nmacOS and Linux | An Ultimate edition license or a demo license. Server and Data Center licenses do not qualify.\nAn installation without a license reports that a license is required to install updates. On macOS and Linux, a license of any other edition, including Server and Data Center, reports that Babel Desktop for that platform requires the Ultimate edition.\nReleases that require active maintenance are offered only when the maintenance period of your license covers the release date. The maintenance period ends on the maintenance expiration date of the license or, when the license has none, one year after its issue date. If your maintenance has expired, you do not get the new version. The banner and the settings show the expiration date and a link to renew. Babel Desktop also reminds you shortly before maintenance runs out. The installed version keeps working either way."},{"page":194,"heading":"Troubleshooting","anchor":"troubleshooting","text":"Status | Meaning\nBabel Desktop is up to date | No newer version is available for your license.\nVersion ... is available | A newer version is available; it is downloading, or Download now starts the download.\nBabel Desktop ... is ready. Restart to update. | The update is downloaded; restart to install it.\nYour maintenance expired on ... | The new version requires maintenance that your license no longer covers. Renew the maintenance.\nA Babel license is required to install updates | Load a license in Settings > License.\nBabel Desktop for ... requires the Ultimate edition | Updates on macOS and Linux require an Ultimate edition or demo license.\nUpdate check failed: ... | The feed could not be reached or its signature was not valid. Check the network connection and try again later.\nUpdates are disabled (...) | The installation is managed by an MSI, DEB or RPM package, or the application is not an installed build.\nUpdate failures are also written to the Activity log."},{"page":195,"heading":"","anchor":"","text":"Babel Licensing API Reference\nThe Babel Licensing Service exposes a REST API to manage licenses, products, customers, orders, releases and the rest of the licensing data, to run the licensing operations of protected applications, and to serve application updates. This page covers what every endpoint has in common. The pages linked at the bottom list the endpoints one by one."},{"page":195,"heading":"Base URL and Versioning","anchor":"base-url-and-versioning","text":"Every route starts with the version segment /v1:\nhttps://your-licensing-server/v1/...\nThe host and port come from the Kestrel section of the service appsettings.json; the default configuration listens on https://localhost:5000 (see Kestrel). The code samples in this reference show paths only, so prepend your server address.\nThe REST API is served only when Application:EnableWebApi is true, the default. With Application:EnableSwagger also enabled, the service publishes the OpenAPI document this reference is generated from at /swagger/v1/swagger.json, and Swagger UI at /swagger.\nInfo: The service also exposes gRPC services for the runtime operations (Authentication, LicenseServer and ReportServer). The Babel.Licensing client library talks to them over gRPC or over HTTP (see UseHttp vs UseGrpc). The default configuration adds a separate HTTP/2 endpoint for gRPC on port 5005, and gRPC-Web is enabled on the main endpoint (Application:EnableGrpcWeb). See gRPC Web and gRPC SSL/TLS."},{"page":195,"heading":"Content Types","anchor":"content-types","text":"Request and response bodies are JSON (application/json) with camelCase property names.\nDates are UTC strings such as 2026-09-01T00:00:00.000Z.\nEnumerations are serialized as numbers, unless Application:SerializeJSonEnumAsString is enabled.\nProperties with a null value are left out of responses while Application:IgnoreJSonDefaultValues is true, as it is in the default configuration.\nA client that sends Accept: application/toon receives TOON instead of JSON. Without that header the response is JSON.\nUploading a release artifact uses multipart/form-data, and the update feed files are text/yaml. See Product Releases and Updates."},{"page":195,"heading":"Authentication","anchor":"authentication","text":"The API accepts two credentials. Which one an endpoint takes is shown under each endpoint as Authentication.\nCredential | Header | Obtained from | Used by\nAPI key | x-api-key: <key> | The web application, Babel Desktop, or POST /v1/api-keys | Management API, product releases, release downloads, webhooks; also licensing operations and reports\nBearer token (JWT) | Authorization: Bearer <token> | POST /v1/auth/login | Signed-in user routes under /v1/auth; licensing operations and reports\nThe header name x-api-key can be changed with Application:ApiKeyHeaderName.\nWarning: The Management API, product release, release download and webhook routes accept only an API key. A bearer token is refused there with 401, even the token of an administrator.\nAPI keys\nAn API key belongs to a user, its owner. A request authenticated by the key acts with the roles of that owner, and the key adds its own permission bits on top:\nPermission | Value | Allows\nRead | 1 | GET\nWrite | 2 | PUT, PATCH\nDelete | 4 | DELETE\nCreate | 8 | POST\nAll | 15 | every method\nThe permission follows the HTTP method, not what the route does: POST /v1/products/{productId}/releases/{releaseId}/downloads/verify changes nothing but still needs Create. Permission bits are checked on the Management API, release download and webhook routes. A key without the bit for the method receives 403."},{"page":195,"heading":"Authentication","anchor":"authentication","text":"A key is refused with 401 when it is unknown, revoked or past its expiration date. When a key has no owner it carries no role, so every role-protected route answers 403, and POST /v1/api-keys refuses to create one. When the service creates the administrator account at startup (Application:AdminUsername and Application:AdminPassword), it also creates an API key with all permissions for that user.\nThe service caches a validated key for Application:ApiKeyCacheDuration (3 minutes in the default appsettings.json). A change to a key, such as revoking it or removing a permission, can take that long to apply.\nGet an API key\nCreate the key in the web application, in Babel Desktop, or with POST /v1/api-keys using a key that belongs to an administrator. Give it only the permissions the client needs.\nSend it with every request\ncurl https://your-licensing-server/v1/products?take=10 \\\n  -H 'x-api-key: api_xxxxxxxxxxxxxxxxxxxxxxxx'\nCheck what the key can do\nGET /v1/auth/session answers with the owner, the owner's roles and the key's permission bits. It needs no permission of its own, so any valid key can call it.\n{\n  \"success\": true,\n  \"user\": \"admin\",\n  \"roles\": [ \"Administrator\" ],\n  \"permissions\": 1,\n  \"keyName\": \"read-only\"\n}\nBearer tokens\nPOST /v1/auth/login returns a JWT in token and its lifetime in seconds in expiresIn (Application:TokenExpiration, 30 minutes by default). Send it as Authorization: Bearer <token>.\nUser name and password"},{"page":195,"heading":"Authentication","anchor":"authentication","text":"A user signs in with the user name and password. The token carries the roles of the user and gives access to /v1/auth/user, /v1/auth/session, /v1/auth/logout, the licensing operations and reports.\ncurl -X POST https://your-licensing-server/v1/auth/login \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"username\":\"admin\",\"password\":\"<password>\"}'\nLicense user key\nAn application can sign in with the user key of its license alone, sent as password with no username. The token has no roles: it works for the licensing operations and reports, and nowhere else.\ncurl -X POST https://your-licensing-server/v1/auth/login \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"password\":\"AAAAA-BBBBB-CCCCC-DDDDD\"}'\nGET /v1/auth/user returns the signed-in user with its roles, settings and active API keys. GET /v1/auth/session works with both credentials: with a bearer token it reports the user and roles, and permissions is absent."},{"page":195,"heading":"Roles and Access","anchor":"roles-and-access","text":"The service defines the roles Administrator, LicenseManager and Sales, and every Management API route requires one of them. The roles Customer and Application also exist, but no REST route requires them."},{"page":195,"heading":"Roles and Access","anchor":"roles-and-access","text":"Area | Routes | Credential | Roles\nUpdate feed and feed keys | /v1/updates/..., /v1/extensions/keys | None | Anyone\nLogin | POST /v1/auth/login | None | Anyone\nSigned-in user | /v1/auth/user, POST /v1/auth/logout | Bearer | Any user\nSession | GET /v1/auth/session | Bearer or API key | Any\nLicensing operations | /v1/license/... | Bearer or API key | No role required\nReports sent by applications | POST /v1/report | Bearer or API key | No role required\nCustomers, contacts, products, orders, resources | /v1/customers, /v1/contacts, /v1/products, /v1/orders, /v1/resources | API key | Administrator, LicenseManager, Sales\nLicenses (list, create, update) and license tokens | /v1/licenses, /v1/license-tokens | API key | Administrator, LicenseManager, Sales\nLicense templates (list, template licenses) | GET /v1/license-templates... | API key | Administrator, LicenseManager, Sales\nProduct releases, release assemblies and release license templates | /v1/products/{productId}/releases... | API key | Administrator, LicenseManager, Sales\nLog, server info, email | /v1/log, /v1/info, /v1/email/... | API key | Administrator, LicenseManager, Sales\nLicense deletion | DELETE /v1/licenses/{licenseId} | API key | Administrator, LicenseManager\nLicense templates (create, update, delete) | POST, PUT, DELETE /v1/license-templates | API key | Administrator, LicenseManager\nLicense traces and received reports | /v1/license-traces, /v1/reports | API key | Administrator, LicenseManager"},{"page":195,"heading":"Roles and Access","anchor":"roles-and-access","text":"Release downloads | /v1/products/{productId}/releases/{releaseId}/downloads... | API key | Administrator, LicenseManager\nWebhooks | /v1/webhooks/... | API key | Administrator, LicenseManager\nUsers, user settings, roles, API keys | /v1/users, /v1/roles, /v1/api-keys | API key | Administrator\nAssemblies and service settings | /v1/assemblies, /v1/settings | API key | Administrator\nA request with a valid credential but without the role answers 403."},{"page":195,"heading":"Anonymous Endpoints","anchor":"anonymous-endpoints","text":"These routes take no credential:\nPOST /v1/auth/login.\nThe update feed: GET /v1/updates/{productCode}, the electron-updater feed files and the artifact download. A caller identifies its license, when it has one, with the X-Babel-User-Key header or the userKey query parameter. See Updates.\nGET /v1/extensions/keys, the public keys that sign the feed.\nThe health check at /health (Application:HealthCheckEndPoint), when Application:EnableHealthCheck is true. It is not part of the OpenAPI document; see Health Check.\nThe licensing operations under /v1/license are not anonymous. An application that has only its user key signs in with it first, as shown in Bearer tokens."},{"page":195,"heading":"Querying Lists","anchor":"querying-lists","text":"Most GET routes that return a list accept the same query parameters:\nParameter | Meaning | Example\nfilter | A Dynamic LINQ expression on the entity properties | userKey=\"AAAAA-BBBBB-CCCCC-DDDDD\"\nsort | Comma-separated properties; prefix - for descending, + or nothing for ascending | -createdAt,name\nskip | Number of items to skip | 20\ntake | Maximum number of items to return | 10\nselect | Comma-separated properties to return | id,code,name\ninclude | Comma-separated related entities to load, where the route supports it | Contacts\nWith skip or take and no sort, results are ordered by primary key, so pages stay stable. The response carries the page of items and a total count of the items that match filter, such as totalProductsCount. Each endpoint page lists the parameters that route accepts: the release download list, for example, has no select, and the token lists add countOnly.\nURL-encode the values. curl -G with --data-urlencode does it for you:"},{"page":195,"heading":"Querying Lists","anchor":"querying-lists","text":"# Products whose code starts with \"babel\", newest first, three properties only\ncurl -G https://your-licensing-server/v1/products \\\n  -H 'x-api-key: <key>' \\\n  --data-urlencode 'filter=code.StartsWith(\"babel\")' \\\n  --data-urlencode 'select=id,code,name' \\\n  --data-urlencode 'sort=-id' \\\n  --data-urlencode 'take=10'\n\n# The license with a given user key\ncurl -G https://your-licensing-server/v1/licenses \\\n  -H 'x-api-key: <key>' \\\n  --data-urlencode 'filter=userKey=\"AAAAA-BBBBB-CCCCC-DDDDD\"'\n\n# A customer with its contacts\ncurl -G https://your-licensing-server/v1/customers \\\n  -H 'x-api-key: <key>' \\\n  --data-urlencode 'filter=id=42' \\\n  --data-urlencode 'include=Contacts'\nA filter that names an unknown property is not a validation error: the service answers 500 with the parser message, for example No property or field 'nope' exists in type 'Product'."},{"page":195,"heading":"Updating Resources","anchor":"updating-resources","text":"PUT requests perform partial updates: a field omitted from the request body keeps its stored value. A value you send explicitly, including false or 0, is applied. Send only the fields you want to change.\nThis applies to licenses, license templates, customers, contacts, products, product releases, order products, API keys and webhook events.\nInfo: Before 12.0 an omitted Boolean, number or enumeration field was reset to false/0. For example, updating a license without revoked un-revoked it. Clients that relied on that reset must now send the value explicitly.\nWhen a product release is created without requiresMaintenance, it defaults to true, so the release is available only to licenses in maintenance. For an application product the service refuses requiresMaintenance: false unless Updates:AllowPublicApplicationReleases is enabled. See Releases."},{"page":195,"heading":"Errors","anchor":"errors","text":"Error responses come in three shapes.\nService errors\nEvery route except the anonymous update routes reports errors with a small JSON body:\n{ \"success\": false, \"code\": 400, \"message\": \"Product 999 not found.\" }\ncode repeats the HTTP status. The status depends on the error:\n400 for a request the client can correct, such as a missing or invalid field. Many \"not found\" cases on the Management API also answer 400, with the reason in message.\n401 for a failed login (Invalid username or password., Invalid user key.).\n500 for anything else, including a failed database operation.\n520 plus the gRPC status code for the licensing errors shared with the gRPC services. The body message names the error. See Error Codes.\nHTTP status | gRPC status | Example message\n523 | InvalidArgument | Invalid license key; The machine code is required for license activation\n525 | NotFound | License key not found; License token not found\n526 | AlreadyExists | The license has already been activated\n527 | PermissionDenied | The license has been revoked; The license has expired\n528 | ResourceExhausted | The maximum number of concurrent users for the license has been reached\n529 | FailedPrecondition | The license has not been activated\n535 | DataLoss | The license has been tampered\nValidation problems\nValidation problems use the standard ASP.NET Core application/problem+json body. You get one when the request body cannot be read, for example malformed JSON:"},{"page":195,"heading":"Errors","anchor":"errors","text":"{\n  \"type\": \"https://tools.ietf.org/html/rfc9110#section-15.5.1\",\n  \"title\": \"One or more validation errors occurred.\",\n  \"status\": 400,\n  \"errors\": { \"\": [ \"Unexpected end while parsing unquoted property name. Path '', line 1, position 4.\" ] }\n}\nUpdate route errors\nThe update routes use the { success, code, message } body too, but with ordinary HTTP statuses only: 400 for an unknown platform, channel or version, 403 for a revoked or expired license or a refused download, 404 for an unknown product or artifact. They never answer 52x.\nStatus codes\nStatus | Meaning\n400 | Invalid request, or an entity referenced by the request does not exist\n401 | No credential, an invalid or expired credential, a bearer token on an API-key-only route, or a failed login. Authorization failures have an empty body\n403 | Valid credential without the required role or API key permission; on update routes, a refused license or download\n404 | Unknown route; on update routes, an unknown product or artifact; on webhook routes, an unknown subscription or event\n429 | Too many requests from the client IP; see Rate Limiting\n500 | Unexpected error, invalid filter expression, or a login from an IP blocked after failed attempts\n52x | Licensing error mapped from a gRPC status (table above)"},{"page":195,"heading":"Rate Limiting","anchor":"rate-limiting","text":"The IpFiltering section of appsettings.json protects the service. The defaults are:\nSetting | Default | Effect\nBruteForceProtection:Enabled | true | Counts requests per client IP\nBruteForceProtection:MaxRequestsPerTimeFrame | 60 | Requests allowed in one time frame\nBruteForceProtection:TimeFrameDuration | 00:01:00 | Length of the time frame\nBruteForceProtection:RequestsBlockDuration | 00:15:00 | How long an IP that went over the limit is blocked\nBruteForceProtection:ExcludedPaths | See below | Path prefixes that are never counted or blocked\nWhitelist | 127.0.0.1, ::1 | IPs that are never rate limited, so local clients are exempt\nAuthenticationProtection:MaxFailedAttempts | 5 | Failed logins before the IP is blocked from logging in\nAuthenticationProtection:LoginBlockDuration | 00:05:00 | How long login stays blocked\nThe default excluded paths are the floating license routes (/v1/license/request, /v1/license/release, /v1/license/heartbeat and their gRPC counterparts) and login (/v1/auth/login and the gRPC Authenticate). An application that went over the limit elsewhere can still hold and release its floating seats.\nA blocked client receives 429 Too Many Requests with a Retry-After header in seconds and the text body Too many requests. Retry after N seconds. Wait at least that long before retrying. A blacklisted IP (Blacklist) always receives 403."},{"page":195,"heading":"Rate Limiting","anchor":"rate-limiting","text":"Login protection is separate. After MaxFailedAttempts failed logins, further logins from that IP fail until the block expires, even with the right password. The update routes count unknown, revoked or expired user keys as failed attempts too, and enough of them block logins from that IP in the same way. See IP Filtering for the configuration reference."},{"page":195,"heading":"Webhooks","anchor":"webhooks","text":"The service can call your endpoints when licenses, orders and reports change. Subscriptions are managed with the Webhooks API and require an API key of an Administrator or LicenseManager. For the event types and payloads, see Supported Events and Webhook Payload Reference. Every delivery is signed with HMAC-SHA256 in the X-Babel-Signature header; see Securing Webhooks for how to verify it."},{"page":195,"heading":"API Sections","anchor":"api-sections","text":"Authentication: Login, logout, the signed-in user and the session of a credential\nLicensing: Activation, floating licenses, validation and license information\nManagement: Customers, products, orders, licenses, templates, users, API keys and settings\nProduct Releases: Releases, release assemblies and templates, and downloadable artifacts\nReports: Reports sent by applications\nUpdates: The public update feed: update check, feed files, downloads and signing keys\nWebhooks: Webhook subscriptions, delivery events and event types\nSchemas: Request and response models"},{"page":196,"heading":"POST /v1/auth/login","anchor":"post-v1authlogin","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/auth/login \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{\n  \"username\": \"string\",\n  \"password\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/auth/login',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":196,"heading":"POST /v1/auth/login","anchor":"post-v1authlogin","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/auth/login\";\n      \n      string json = @\"{\n  \"\"username\"\": \"\"string\"\",\n  \"\"password\"\": \"\"string\"\"\n}\";\n      Management.LoginRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.LoginRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.LoginRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    "},{"page":196,"heading":"POST /v1/auth/login","anchor":"post-v1authlogin","text":"    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/auth/login\nLogin to the system.\nBody parameter\n{\n  \"username\": \"string\",\n  \"password\": \"string\"\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.LoginRequest | false | The login request.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"token\":\"string\",\"expiresIn\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"token\": \"string\",\n  \"expiresIn\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.LoginResponse\nAuthentication: none, the endpoint is anonymous."},{"page":196,"heading":"GET /v1/auth/user","anchor":"get-v1authuser","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/auth/user \\\n  -H 'Accept: text/plain'\nJavaScript\nconst headers = {\n  'Accept':'text/plain'\n};\n\nfetch('/v1/auth/user',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":196,"heading":"GET /v1/auth/user","anchor":"get-v1authuser","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/auth/user\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/auth/user\nGet loggedin user information.\nParameters\nName | In | Type | Required | Description\nrequest | query | Management.GetLoggedInUserRequest | false | The logged in user request.\nExample responses\n200 Response"},{"page":196,"heading":"GET /v1/auth/user","anchor":"get-v1authuser","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"user\":{\"id\":\"string\",\"userName\":\"string\",\"email\":\"string\",\"phoneNumber\":\"string\",\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"department\":\"string\",\"birthDate\":\"2019-08-24T14:15:22Z\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"lastDismissMessages\":\"2019-08-24T14:15:22Z\",\"lastLogIn\":\"2019-08-24T14:15:22Z\",\"rank\":0,\"image\":\"string\",\"address\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mobile\":\"string\",\"notes\":\"string\",\"customerId\":0,\"roles\":[\"string\"],\"apiKeys\":[{\"id\":0,\"name\":\"string\",\"key\":\"string\",\"clientSecret\":\"string\",\"createdDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"ownerId\":\"string\",\"revoked\":true,\"permissions\":0,\"description\":\"string\"}],\"settings\":[{\"id\":0,\"category\":\"string\",\"group\":\"string\",\"name\":\"string\",\"value\":\"string\",\"type\":\"string\",\"description\":\"string\",\"readOnly\":true,\"userId\":\"string\"}]}}"},{"page":196,"heading":"GET /v1/auth/user","anchor":"get-v1authuser","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  }\n}\nResponses"},{"page":196,"heading":"GET /v1/auth/user","anchor":"get-v1authuser","text":"Status | Meaning | Description | Schema\n200 | OK | OK | Management.GetLoggedInUserResponse\nAuthentication: Bearer token."},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/auth/user \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript"},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"const inputBody = '{\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/auth/user',\n{"},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/auth/user\";\n      \n      string json = @\"{\n  \"\"user\"\": {\n    \"\"id\"\": \"\"string\"\",\n    \"\"userName\"\": \"\"string\"\",\n    \"\"email\"\": \"\"string\"\",\n    \"\"phoneNumber\"\": \"\"string\"\",\n    \"\"title\"\": \"\"string\"\",\n    \"\"firstName\"\": \"\"string\"\",\n    \"\"lastName\"\": \"\"string\"\",\n    \"\"department\"\": \"\"string\"\",\n    \"\"birthDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"lastDismissMessages\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"lastLogIn\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"rank\"\": 0,\n    \"\"image\"\": \"\"string\"\",\n    \"\"address\"\": \"\"string\"\",\n    \"\"postalCode\"\": \"\"string\"\",\n    \"\"region\"\": \"\"string\"\",\n    \"\"city\"\": \"\"string\"\",\n    \"\"country\"\": \"\"string\"\",\n    \"\"countryCode\"\": \"\"string\"\",\n    \"\"mobile\"\": \"\"string\"\",\n    \"\"notes\"\": \"\"string\"\",\n    \"\"customerId\"\": 0,\n    \"\"roles\"\": [\n      \"\"string\"\"\n    ],\n    \"\"apiKeys\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\","},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"        \"\"key\"\": \"\"string\"\",\n        \"\"clientSecret\"\": \"\"string\"\",\n        \"\"createdDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"ownerId\"\": \"\"string\"\",\n        \"\"revoked\"\": true,\n        \"\"permissions\"\": 0,\n        \"\"description\"\": \"\"string\"\"\n      }\n    ],\n    \"\"settings\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"category\"\": \"\"string\"\",\n        \"\"group\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"value\"\": \"\"string\"\",\n        \"\"type\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"readOnly\"\": true,\n        \"\"userId\"\": \"\"string\"\"\n      }\n    ]\n  }\n}\";\n      Management.UpdateUserSettingsRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.UpdateUserSettingsRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateUserSettingsRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    "},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/auth/user\nUpdate loggedin user information.\nBody parameter"},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"{\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  }\n}\nParameters"},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"Name | In | Type | Required | Description\nbody | body | Management.UpdateUserSettingsRequest | false | The logged in user information request.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"user\":{\"id\":\"string\",\"userName\":\"string\",\"email\":\"string\",\"phoneNumber\":\"string\",\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"department\":\"string\",\"birthDate\":\"2019-08-24T14:15:22Z\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"lastDismissMessages\":\"2019-08-24T14:15:22Z\",\"lastLogIn\":\"2019-08-24T14:15:22Z\",\"rank\":0,\"image\":\"string\",\"address\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mobile\":\"string\",\"notes\":\"string\",\"customerId\":0,\"roles\":[\"string\"],\"apiKeys\":[{\"id\":0,\"name\":\"string\",\"key\":\"string\",\"clientSecret\":\"string\",\"createdDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"ownerId\":\"string\",\"revoked\":true,\"permissions\":0,\"description\":\"string\"}],\"settings\":[{\"id\":0,\"category\":\"string\",\"group\":\"string\",\"name\":\"string\",\"value\":\"string\",\"type\":\"string\",\"description\":\"string\",\"readOnly\":true,\"userId\":\"string\"}]}}"},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  }\n}\nResponses"},{"page":196,"heading":"POST /v1/auth/user","anchor":"post-v1authuser","text":"Status | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateUserSettingsResponse\nAuthentication: Bearer token."},{"page":196,"heading":"GET /v1/auth/session","anchor":"get-v1authsession","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/auth/session \\\n  -H 'Accept: text/plain'\nJavaScript\nconst headers = {\n  'Accept':'text/plain'\n};\n\nfetch('/v1/auth/session',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":196,"heading":"GET /v1/auth/session","anchor":"get-v1authsession","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/auth/session\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/auth/session\nGet the capabilities of the credential that made the call.\nAnswers a bearer token and an API key alike, which is why it names both schemes: the rest of\nthis controller speaks to tokens only, and a client holding just an API key has no other way\nto learn what it may do."},{"page":196,"heading":"GET /v1/auth/session","anchor":"get-v1authsession","text":"It carries no Policy = \"ApiKey\" on purpose. That policy demands the Read permission on\nevery GET, so a key permitted only to create would not be able to ask what it is permitted to\ndo. This is the one endpoint that serves no data, so it authenticates without requiring a\npermission of its own.\nIt also, deliberately, does not answer with the caller's API keys the way\nM:Babel.Licensing.Service.Controllers.V1.AuthController.GetLoggedInUser(Babel.Licensing.Service.Management.GetLoggedInUserRequest) does: the caller may have proved possession of a single key, and\nthat must not hand back the secrets of every other key the same owner holds.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"user\":\"string\",\"roles\":[\"string\"],\"permissions\":0,\"keyName\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"user\": \"string\",\n  \"roles\": [\n    \"string\"\n  ],\n  \"permissions\": 0,\n  \"keyName\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetSessionResponse\nAuthentication: Bearer token or API key (x-api-key)."},{"page":196,"heading":"POST /v1/auth/logout","anchor":"post-v1authlogout","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/auth/logout \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/auth/logout',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":196,"heading":"POST /v1/auth/logout","anchor":"post-v1authlogout","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/auth/logout\";\n      \n      string json = @\"{}\";\n      Management.LogoutRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.LogoutRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.LogoutRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response"},{"page":196,"heading":"POST /v1/auth/logout","anchor":"post-v1authlogout","text":"    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/auth/logout\nLogout from the system.\nBody parameter\n{}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.LogoutRequest | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.LogoutResponse\nAuthentication: Bearer token."},{"page":197,"heading":"","anchor":"","text":"The operations a protected application calls at run time: activation, floating seats, validation and license information."},{"page":197,"heading":"Pages","anchor":"pages","text":"Activation: Activate and deactivate a license on a machine.\nFloating Licenses: Request, release and keep alive a floating license seat.\nValidation and Info: Validate a license and read its information."},{"page":197,"heading":"Endpoints","anchor":"endpoints","text":"Endpoint | Page\nPOST /v1/license/activate | Activation\nPOST /v1/license/deactivate | Activation\nPOST /v1/license/request | Floating Licenses\nPOST /v1/license/release | Floating Licenses\nPOST /v1/license/heartbeat | Floating Licenses\nPOST /v1/license/validate | Validation and Info\nPOST /v1/license/info | Validation and Info"},{"page":198,"heading":"POST /v1/license/activate","anchor":"post-v1licenseactivate","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/license/activate \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/license/activate',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":198,"heading":"POST /v1/license/activate","anchor":"post-v1licenseactivate","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/license/activate\";\n      \n      string json = @\"{\n  \"\"userKey\"\": \"\"string\"\",\n  \"\"machineId\"\": \"\"string\"\",\n  \"\"clientId\"\": \"\"string\"\",\n  \"\"clientName\"\": \"\"string\"\"\n}\";\n      Licensing.ActivateLicenseRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Licensing.ActivateLicenseRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.ActivateLicenseRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":198,"heading":"POST /v1/license/activate","anchor":"post-v1licenseactivate","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/license/activate\nBody parameter\n{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Licensing.ActivateLicenseRequest | false | none\nExample responses\n200 Response\n{\"success\":true,\"licenseToken\":\"string\",\"tokenExpireAt\":{\"seconds\":0,\"nanos\":0},\"activeClientCount\":0,\"maxClientCount\":0,\"license\":{\"licenseId\":\"string\",\"licensingMode\":0,\"expireAt\":{\"seconds\":0,\"nanos\":0},\"supportExpireAt\":{\"seconds\":0,\"nanos\":0},\"licenseKey\":[0]}}\n{\n  \"success\": true,\n  \"licenseToken\": \"string\",\n  \"tokenExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0,\n  \"license\": {\n    \"licenseId\": \"string\",\n    \"licensingMode\": 0,\n    \"expireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"supportExpireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"licenseKey\": [\n      0\n    ]\n  }\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.ActivateLicenseResponse"},{"page":198,"heading":"POST /v1/license/activate","anchor":"post-v1licenseactivate","text":"Authentication: Bearer token or API key (x-api-key)."},{"page":198,"heading":"POST /v1/license/deactivate","anchor":"post-v1licensedeactivate","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/license/deactivate \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/license/deactivate',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":198,"heading":"POST /v1/license/deactivate","anchor":"post-v1licensedeactivate","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/license/deactivate\";\n      \n      string json = @\"{\n  \"\"userKey\"\": \"\"string\"\",\n  \"\"machineId\"\": \"\"string\"\",\n  \"\"clientId\"\": \"\"string\"\",\n  \"\"clientName\"\": \"\"string\"\"\n}\";\n      Licensing.DeactivateLicenseRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Licensing.DeactivateLicenseRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.DeactivateLicenseRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":198,"heading":"POST /v1/license/deactivate","anchor":"post-v1licensedeactivate","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/license/deactivate\nBody parameter\n{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Licensing.DeactivateLicenseRequest | false | none\nExample responses\n200 Response\n{\"licenseId\":\"string\",\"activeClientCount\":0,\"maxClientCount\":0}\n{\n  \"licenseId\": \"string\",\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.DeactivateLicenseResponse\nAuthentication: Bearer token or API key (x-api-key)."},{"page":199,"heading":"POST /v1/license/request","anchor":"post-v1licenserequest","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/license/request \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/license/request',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":199,"heading":"POST /v1/license/request","anchor":"post-v1licenserequest","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/license/request\";\n      \n      string json = @\"{\n  \"\"userKey\"\": \"\"string\"\",\n  \"\"machineId\"\": \"\"string\"\",\n  \"\"clientId\"\": \"\"string\"\",\n  \"\"clientName\"\": \"\"string\"\"\n}\";\n      Licensing.RequestLicenseRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Licensing.RequestLicenseRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.RequestLicenseRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":199,"heading":"POST /v1/license/request","anchor":"post-v1licenserequest","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/license/request\nBody parameter\n{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Licensing.RequestLicenseRequest | false | none\nExample responses\n200 Response\n{\"granted\":true,\"licenseToken\":\"string\",\"tokenExpireAt\":{\"seconds\":0,\"nanos\":0},\"heartbeatInterval\":{\"seconds\":0,\"nanos\":0},\"activeClientCount\":0,\"maxClientCount\":0,\"license\":{\"licenseId\":\"string\",\"licensingMode\":0,\"expireAt\":{\"seconds\":0,\"nanos\":0},\"supportExpireAt\":{\"seconds\":0,\"nanos\":0},\"licenseKey\":[0]}}\n{\n  \"granted\": true,\n  \"licenseToken\": \"string\",\n  \"tokenExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"heartbeatInterval\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0,\n  \"license\": {\n    \"licenseId\": \"string\",\n    \"licensingMode\": 0,\n    \"expireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"supportExpireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"licenseKey\": [\n      0\n    ]\n  }\n}\nResponses"},{"page":199,"heading":"POST /v1/license/request","anchor":"post-v1licenserequest","text":"Status | Meaning | Description | Schema\n200 | OK | OK | Licensing.RequestLicenseResponse\nAuthentication: Bearer token or API key (x-api-key)."},{"page":199,"heading":"POST /v1/license/release","anchor":"post-v1licenserelease","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/license/release \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{\n  \"licenseToken\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/license/release',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":199,"heading":"POST /v1/license/release","anchor":"post-v1licenserelease","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/license/release\";\n      \n      string json = @\"{\n  \"\"licenseToken\"\": \"\"string\"\",\n  \"\"machineId\"\": \"\"string\"\",\n  \"\"clientId\"\": \"\"string\"\",\n  \"\"clientName\"\": \"\"string\"\"\n}\";\n      Licensing.ReleaseLicenseRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Licensing.ReleaseLicenseRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.ReleaseLicenseRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":199,"heading":"POST /v1/license/release","anchor":"post-v1licenserelease","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/license/release\nBody parameter\n{\n  \"licenseToken\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Licensing.ReleaseLicenseRequest | false | none\nExample responses\n200 Response\n{\"licenseId\":\"string\",\"activeClientCount\":0,\"maxClientCount\":0}\n{\n  \"licenseId\": \"string\",\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.ReleaseLicenseResponse\nAuthentication: Bearer token or API key (x-api-key)."},{"page":199,"heading":"POST /v1/license/heartbeat","anchor":"post-v1licenseheartbeat","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/license/heartbeat \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{\n  \"licenseToken\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/license/heartbeat',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":199,"heading":"POST /v1/license/heartbeat","anchor":"post-v1licenseheartbeat","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/license/heartbeat\";\n      \n      string json = @\"{\n  \"\"licenseToken\"\": \"\"string\"\",\n  \"\"machineId\"\": \"\"string\"\",\n  \"\"clientId\"\": \"\"string\"\",\n  \"\"clientName\"\": \"\"string\"\"\n}\";\n      Licensing.HeartbeatRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Licensing.HeartbeatRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.HeartbeatRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":199,"heading":"POST /v1/license/heartbeat","anchor":"post-v1licenseheartbeat","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/license/heartbeat\nBody parameter\n{\n  \"licenseToken\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Licensing.HeartbeatRequest | false | none\nExample responses\n200 Response\n{\"active\":true,\"activeClientCount\":0,\"maxClientCount\":0,\"tokenExpireAt\":{\"seconds\":0,\"nanos\":0},\"heartbeatInterval\":{\"seconds\":0,\"nanos\":0}}\n{\n  \"active\": true,\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0,\n  \"tokenExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"heartbeatInterval\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  }\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.HeartbeatResponse\nAuthentication: Bearer token or API key (x-api-key)."},{"page":200,"heading":"POST /v1/license/validate","anchor":"post-v1licensevalidate","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/license/validate \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/license/validate',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":200,"heading":"POST /v1/license/validate","anchor":"post-v1licensevalidate","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/license/validate\";\n      \n      string json = @\"{\n  \"\"userKey\"\": \"\"string\"\",\n  \"\"machineId\"\": \"\"string\"\",\n  \"\"clientId\"\": \"\"string\"\",\n  \"\"clientName\"\": \"\"string\"\"\n}\";\n      Licensing.ValidateLicenseRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Licensing.ValidateLicenseRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.ValidateLicenseRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":200,"heading":"POST /v1/license/validate","anchor":"post-v1licensevalidate","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/license/validate\nBody parameter\n{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Licensing.ValidateLicenseRequest | false | none\nExample responses\n200 Response\n{\"success\":true,\"licenseToken\":\"string\",\"tokenExpireAt\":{\"seconds\":0,\"nanos\":0},\"activeClientCount\":0,\"maxClientCount\":0,\"license\":{\"licenseId\":\"string\",\"licensingMode\":0,\"expireAt\":{\"seconds\":0,\"nanos\":0},\"supportExpireAt\":{\"seconds\":0,\"nanos\":0},\"licenseKey\":[0]}}\n{\n  \"success\": true,\n  \"licenseToken\": \"string\",\n  \"tokenExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0,\n  \"license\": {\n    \"licenseId\": \"string\",\n    \"licensingMode\": 0,\n    \"expireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"supportExpireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"licenseKey\": [\n      0\n    ]\n  }\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.ValidateLicenseResponse"},{"page":200,"heading":"POST /v1/license/validate","anchor":"post-v1licensevalidate","text":"Authentication: Bearer token or API key (x-api-key)."},{"page":200,"heading":"POST /v1/license/info","anchor":"post-v1licenseinfo","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/license/info \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/license/info',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":200,"heading":"POST /v1/license/info","anchor":"post-v1licenseinfo","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/license/info\";\n      \n      string json = @\"{\n  \"\"userKey\"\": \"\"string\"\",\n  \"\"machineId\"\": \"\"string\"\",\n  \"\"clientId\"\": \"\"string\"\",\n  \"\"clientName\"\": \"\"string\"\"\n}\";\n      Licensing.LicenseInfoRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Licensing.LicenseInfoRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.LicenseInfoRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":200,"heading":"POST /v1/license/info","anchor":"post-v1licenseinfo","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/license/info\nBody parameter\n{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Licensing.LicenseInfoRequest | false | none\nExample responses\n200 Response\n{\"licenseTokens\":[{\"token\":\"string\",\"licenseId\":\"string\",\"revoked\":true,\"clientId\":\"string\",\"clientAddr\":\"string\",\"clientName\":\"string\",\"machineId\":\"string\",\"issuedAt\":{\"seconds\":0,\"nanos\":0},\"expireAt\":{\"seconds\":0,\"nanos\":0},\"lastHearbeat\":{\"seconds\":0,\"nanos\":0}}],\"licenseId\":\"string\",\"maxClientCount\":0,\"activeClientCount\":0,\"licensingMode\":0,\"revoked\":true,\"issuedAt\":{\"seconds\":0,\"nanos\":0},\"expireAt\":{\"seconds\":0,\"nanos\":0},\"supportExpireAt\":{\"seconds\":0,\"nanos\":0}}"},{"page":200,"heading":"POST /v1/license/info","anchor":"post-v1licenseinfo","text":"{\n  \"licenseTokens\": [\n    {\n      \"token\": \"string\",\n      \"licenseId\": \"string\",\n      \"revoked\": true,\n      \"clientId\": \"string\",\n      \"clientAddr\": \"string\",\n      \"clientName\": \"string\",\n      \"machineId\": \"string\",\n      \"issuedAt\": {\n        \"seconds\": 0,\n        \"nanos\": 0\n      },\n      \"expireAt\": {\n        \"seconds\": 0,\n        \"nanos\": 0\n      },\n      \"lastHearbeat\": {\n        \"seconds\": 0,\n        \"nanos\": 0\n      }\n    }\n  ],\n  \"licenseId\": \"string\",\n  \"maxClientCount\": 0,\n  \"activeClientCount\": 0,\n  \"licensingMode\": 0,\n  \"revoked\": true,\n  \"issuedAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"expireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"supportExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  }\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.LicenseInfoResponse\nAuthentication: Bearer token or API key (x-api-key)."},{"page":201,"heading":"","anchor":"","text":"The Management API administers the licensing data: customers, contacts, products, orders, licenses, license tokens and templates, assemblies, resources, received reports, users, roles, API keys, the log and the service settings.\nEvery route takes an API key in the x-api-key header; a bearer token is refused. The key needs the permission bit for the HTTP method, and its owner needs one of the roles the route allows. See Authentication and Roles and Access. List routes accept filter, sort, skip, take, select and, on some routes, include; see Querying Lists.\nInfo: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":201,"heading":"Pages","anchor":"pages","text":"Customers: Customers, their contacts, orders and licenses.\nContacts: Contacts of customers.\nProducts: Products and the orders that include them.\nOrders: Create, update, list and delete orders.\nOrder Products and Licenses: The products of an order and the licenses issued for it.\nLicenses: Create, update, list and delete licenses.\nLicense Tokens: Activation and floating tokens issued for licenses.\nLicense Traces: License usage traces and their geolocation.\nLicense Templates: License templates and the licenses created from them.\nAssemblies: Assemblies that licenses and releases refer to.\nResources: Stored resources such as signature keys and files.\nReceived Reports: Reports sent by applications, and their geolocation.\nUsers: Users and user settings.\nRoles: Roles and role membership of users.\nAPI Keys: Create, update, list and revoke API keys.\nLog: Read and clear the service log.\nSettings and Server Info: Service settings and server information.\nEmail: Send email and license email."},{"page":201,"heading":"Endpoints","anchor":"endpoints","text":"Endpoint | Page\nGET /v1/customers | Customers\nPOST /v1/customers | Customers\nPUT /v1/customers | Customers\nGET /v1/customers/{customerId}/contacts | Customers\nGET /v1/customers/{customerId}/orders | Customers\nGET /v1/customers/{customerId}/licenses | Customers\nDELETE /v1/customers/{customerId} | Customers\nGET /v1/contacts | Contacts\nPOST /v1/contacts | Contacts\nPUT /v1/contacts | Contacts\nDELETE /v1/contacts/{contactId} | Contacts\nGET /v1/products | Products\nPOST /v1/products | Products\nPUT /v1/products | Products\nDELETE /v1/products/{productId} | Products\nGET /v1/products/{productId}/orders | Products\nGET /v1/orders | Orders\nPOST /v1/orders | Orders\nPUT /v1/orders | Orders\nDELETE /v1/orders/{orderId} | Orders\nGET /v1/orders/{orderId}/products | Order Products and Licenses\nPOST /v1/orders/{orderId}/products/{productId} | Order Products and Licenses\nPUT /v1/orders/{orderId}/products/{productId} | Order Products and Licenses\nDELETE /v1/orders/{orderId}/products/{productId} | Order Products and Licenses\nGET /v1/orders/{orderId}/licenses | Order Products and Licenses\nGET /v1/licenses | Licenses\nPOST /v1/licenses | Licenses\nPUT /v1/licenses | Licenses\nDELETE /v1/licenses/{licenseId} | Licenses\nGET /v1/license-tokens | License Tokens\nGET /v1/licenses/{licenseId}/tokens | License Tokens\nPOST /v1/licenses/{licenseId}/tokens | License Tokens\nDELETE /v1/licenses/{licenseId}/tokens/{tokenId} | License Tokens\nGET /v1/license-traces | License Traces"},{"page":201,"heading":"Endpoints","anchor":"endpoints","text":"DELETE /v1/license-traces | License Traces\nPOST /v1/license-traces/geolocation | License Traces\nGET /v1/license-templates | License Templates\nPOST /v1/license-templates | License Templates\nPUT /v1/license-templates | License Templates\nGET /v1/license-templates/{templateId}/licenses | License Templates\nDELETE /v1/license-templates/{templateId} | License Templates\nGET /v1/assemblies | Assemblies\nPOST /v1/assemblies | Assemblies\nPUT /v1/assemblies | Assemblies\nDELETE /v1/assemblies/{assemblyId} | Assemblies\nGET /v1/resources | Resources\nPOST /v1/resources | Resources\nPUT /v1/resources | Resources\nDELETE /v1/resources/{resourceId} | Resources\nGET /v1/reports | Received Reports\nPOST /v1/reports/geolocation | Received Reports\nDELETE /v1/reports/{reportId} | Received Reports\nGET /v1/users | Users\nPOST /v1/users | Users\nPUT /v1/users | Users\nDELETE /v1/users/{userId} | Users\nGET /v1/users/{userId}/settings | Users\nPOST /v1/users/{userId}/settings | Users\nPUT /v1/users/{userId}/settings | Users\nDELETE /v1/users/{userId}/settings/{settingId} | Users\nGET /v1/roles | Roles\nGET /v1/users/{userId}/roles | Roles\nPOST /v1/users/{userId}/roles | Roles\nDELETE /v1/users/{userId}/roles | Roles\nGET /v1/api-keys | API Keys\nPOST /v1/api-keys | API Keys\nPUT /v1/api-keys | API Keys\nDELETE /v1/api-keys/{apiKeyId} | API Keys\nGET /v1/log/levels | Log\nGET /v1/log | Log\nDELETE /v1/log | Log\nGET /v1/settings | Settings and Server Info\nPUT /v1/settings | Settings and Server Info"},{"page":201,"heading":"Endpoints","anchor":"endpoints","text":"GET /v1/info | Settings and Server Info\nPOST /v1/email/send | Email\nPOST /v1/email/license | Email"},{"page":202,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":202,"heading":"GET /v1/customers","anchor":"get-v1customers","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/customers \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/customers',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":202,"heading":"GET /v1/customers","anchor":"get-v1customers","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/customers\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/customers\nRetrieves a list of customers based on the provided request parameters.\nParameters"},{"page":202,"heading":"GET /v1/customers","anchor":"get-v1customers","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"customers\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]}],\"totalCustomersCount\":0}"},{"page":202,"heading":"GET /v1/customers","anchor":"get-v1customers","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"customers\": [\n    {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalCustomersCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetCustomersResponse\nAuthentication: API key (x-api-key)."},{"page":202,"heading":"POST /v1/customers","anchor":"post-v1customers","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/customers \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":202,"heading":"POST /v1/customers","anchor":"post-v1customers","text":"const inputBody = '{\n  \"customer\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"company\": \"string\",\n    \"code\": \"string\",\n    \"vatCode\": \"string\",\n    \"invoiceCode\": \"string\",\n    \"rating\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"address\": \"string\",\n    \"address1\": \"string\",\n    \"address2\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mapCoordinates\": \"string\",\n    \"mapZoomLevel\": 0.1,\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"website\": \"string\",\n    \"notes\": \"string\",\n    \"isReseller\": true,\n    \"image\": \"string\",\n    \"meta\": \"string\",\n    \"contacts\": [\n      {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"details\": \"string\",\n        \"notify\": true,\n        \"customerId\": 0,\n        \"meta\": \"string\"\n      }\n    ]\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/customers',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":202,"heading":"POST /v1/customers","anchor":"post-v1customers","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/customers\";\n      \n      string json = @\"{\n  \"\"customer\"\": {\n    \"\"id\"\": 0,\n    \"\"title\"\": \"\"string\"\",\n    \"\"firstName\"\": \"\"string\"\",\n    \"\"lastName\"\": \"\"string\"\",\n    \"\"company\"\": \"\"string\"\",\n    \"\"code\"\": \"\"string\"\",\n    \"\"vatCode\"\": \"\"string\"\",\n    \"\"invoiceCode\"\": \"\"string\"\",\n    \"\"rating\"\": 0,\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"address\"\": \"\"string\"\",\n    \"\"address1\"\": \"\"string\"\",\n    \"\"address2\"\": \"\"string\"\",\n    \"\"postalCode\"\": \"\"string\"\",\n    \"\"region\"\": \"\"string\"\",\n    \"\"city\"\": \"\"string\"\",\n    \"\"country\"\": \"\"string\"\",\n    \"\"countryCode\"\": \"\"string\"\",\n    \"\"mapCoordinates\"\": \"\"string\"\",\n    \"\"mapZoomLevel\"\": 0.1,\n    \"\"email\"\": \"\"string\"\",\n    \"\"phone\"\": \"\"string\"\",\n    \"\"mobile\"\": \"\"string\"\",\n    \"\"fax\"\": \"\"string\"\",\n    \"\"website\"\": \"\"string\"\",\n    \"\"notes\"\": \"\"string\"\",\n    \"\"isReseller\"\": true,\n    \"\"image\"\": \"\"string\"\",\n    \"\"meta\"\": \"\"string\"\",\n    \"\"contacts\"\": ["},{"page":202,"heading":"POST /v1/customers","anchor":"post-v1customers","text":"      {\n        \"\"id\"\": 0,\n        \"\"title\"\": \"\"string\"\",\n        \"\"firstName\"\": \"\"string\"\",\n        \"\"lastName\"\": \"\"string\"\",\n        \"\"email\"\": \"\"string\"\",\n        \"\"phone\"\": \"\"string\"\",\n        \"\"mobile\"\": \"\"string\"\",\n        \"\"fax\"\": \"\"string\"\",\n        \"\"details\"\": \"\"string\"\",\n        \"\"notify\"\": true,\n        \"\"customerId\"\": 0,\n        \"\"meta\"\": \"\"string\"\"\n      }\n    ]\n  }\n}\";\n      Management.InsertCustomerRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertCustomerRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.InsertCustomerRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object"},{"page":202,"heading":"POST /v1/customers","anchor":"post-v1customers","text":"        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/customers\nInserts a new customer based on the provided request parameters.\nBody parameter\n{\n  \"customer\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"company\": \"string\",\n    \"code\": \"string\",\n    \"vatCode\": \"string\",\n    \"invoiceCode\": \"string\",\n    \"rating\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"address\": \"string\",\n    \"address1\": \"string\",\n    \"address2\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mapCoordinates\": \"string\",\n    \"mapZoomLevel\": 0.1,\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"website\": \"string\",\n    \"notes\": \"string\",\n    \"isReseller\": true,\n    \"image\": \"string\",\n    \"meta\": \"string\",\n    \"contacts\": [\n      {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"details\": \"string\",\n        \"notify\": true,\n        \"customerId\": 0,\n        \"meta\": \"string\"\n      }\n    ]\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.InsertCustomerRequest | false | The request parameters for inserting a new customer.\nExample responses"},{"page":202,"heading":"POST /v1/customers","anchor":"post-v1customers","text":"200 Response\n{\"customerId\":0,\"success\":true,\"code\":0,\"message\":\"string\",\"customerCode\":\"string\"}\n{\n  \"customerId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"customerCode\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertCustomerResponse\nAuthentication: API key (x-api-key)."},{"page":202,"heading":"PUT /v1/customers","anchor":"put-v1customers","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/customers \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":202,"heading":"PUT /v1/customers","anchor":"put-v1customers","text":"const inputBody = '{\n  \"customer\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"company\": \"string\",\n    \"code\": \"string\",\n    \"vatCode\": \"string\",\n    \"invoiceCode\": \"string\",\n    \"rating\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"address\": \"string\",\n    \"address1\": \"string\",\n    \"address2\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mapCoordinates\": \"string\",\n    \"mapZoomLevel\": 0.1,\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"website\": \"string\",\n    \"notes\": \"string\",\n    \"isReseller\": true,\n    \"image\": \"string\",\n    \"meta\": \"string\",\n    \"contacts\": [\n      {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"details\": \"string\",\n        \"notify\": true,\n        \"customerId\": 0,\n        \"meta\": \"string\"\n      }\n    ]\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/customers',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":202,"heading":"PUT /v1/customers","anchor":"put-v1customers","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/customers\";\n\n      \n      string json = @\"{\n  \"\"customer\"\": {\n    \"\"id\"\": 0,\n    \"\"title\"\": \"\"string\"\",\n    \"\"firstName\"\": \"\"string\"\",\n    \"\"lastName\"\": \"\"string\"\",\n    \"\"company\"\": \"\"string\"\",\n    \"\"code\"\": \"\"string\"\",\n    \"\"vatCode\"\": \"\"string\"\",\n    \"\"invoiceCode\"\": \"\"string\"\",\n    \"\"rating\"\": 0,\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"address\"\": \"\"string\"\",\n    \"\"address1\"\": \"\"string\"\",\n    \"\"address2\"\": \"\"string\"\",\n    \"\"postalCode\"\": \"\"string\"\",\n    \"\"region\"\": \"\"string\"\",\n    \"\"city\"\": \"\"string\"\",\n    \"\"country\"\": \"\"string\"\",\n    \"\"countryCode\"\": \"\"string\"\",\n    \"\"mapCoordinates\"\": \"\"string\"\",\n    \"\"mapZoomLevel\"\": 0.1,\n    \"\"email\"\": \"\"string\"\",\n    \"\"phone\"\": \"\"string\"\",\n    \"\"mobile\"\": \"\"string\"\",\n    \"\"fax\"\": \"\"string\"\",\n    \"\"website\"\": \"\"string\"\",\n    \"\"notes\"\": \"\"string\"\",\n    \"\"isReseller\"\": true,\n    \"\"image\"\": \"\"string\"\",\n    \"\"meta\"\": \"\"string\"\","},{"page":202,"heading":"PUT /v1/customers","anchor":"put-v1customers","text":"    \"\"contacts\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"title\"\": \"\"string\"\",\n        \"\"firstName\"\": \"\"string\"\",\n        \"\"lastName\"\": \"\"string\"\",\n        \"\"email\"\": \"\"string\"\",\n        \"\"phone\"\": \"\"string\"\",\n        \"\"mobile\"\": \"\"string\"\",\n        \"\"fax\"\": \"\"string\"\",\n        \"\"details\"\": \"\"string\"\",\n        \"\"notify\"\": true,\n        \"\"customerId\"\": 0,\n        \"\"meta\"\": \"\"string\"\"\n      }\n    ]\n  }\n}\";\n      Management.UpdateCustomerRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateCustomerRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateCustomerRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {"},{"page":202,"heading":"PUT /v1/customers","anchor":"put-v1customers","text":"        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/customers\nUpdates an existing customer based on the provided request parameters.\nBody parameter\n{\n  \"customer\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"company\": \"string\",\n    \"code\": \"string\",\n    \"vatCode\": \"string\",\n    \"invoiceCode\": \"string\",\n    \"rating\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"address\": \"string\",\n    \"address1\": \"string\",\n    \"address2\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mapCoordinates\": \"string\",\n    \"mapZoomLevel\": 0.1,\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"website\": \"string\",\n    \"notes\": \"string\",\n    \"isReseller\": true,\n    \"image\": \"string\",\n    \"meta\": \"string\",\n    \"contacts\": [\n      {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"details\": \"string\",\n        \"notify\": true,\n        \"customerId\": 0,\n        \"meta\": \"string\"\n      }\n    ]\n  }\n}\nParameters"},{"page":202,"heading":"PUT /v1/customers","anchor":"put-v1customers","text":"Name | In | Type | Required | Description\nbody | body | Management.UpdateCustomerRequest | false | The request parameters for updating a customer.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateCustomerResponse\nAuthentication: API key (x-api-key)."},{"page":202,"heading":"GET /v1/customers/{customerId}/contacts","anchor":"get-v1customerscustomeridcontacts","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/customers/{customerId}/contacts \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/customers/{customerId}/contacts',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":202,"heading":"GET /v1/customers/{customerId}/contacts","anchor":"get-v1customerscustomeridcontacts","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/customers/{customerId}/contacts\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/customers/\\{customerId\\}/contacts\nRetrieves a list of customer contacts based on the provided request parameters.\nParameters"},{"page":202,"heading":"GET /v1/customers/{customerId}/contacts","anchor":"get-v1customerscustomeridcontacts","text":"Name | In | Type | Required | Description\ncustomerId | path | integer(int32) | true | The customer ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}],\"totalContactsCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"contacts\": [\n    {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"details\": \"string\",\n      \"notify\": true,\n      \"customerId\": 0,\n      \"meta\": \"string\"\n    }\n  ],\n  \"totalContactsCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetCustomerContactsResponse\nAuthentication: API key (x-api-key)."},{"page":202,"heading":"GET /v1/customers/{customerId}/orders","anchor":"get-v1customerscustomeridorders","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/customers/{customerId}/orders \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/customers/{customerId}/orders',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":202,"heading":"GET /v1/customers/{customerId}/orders","anchor":"get-v1customerscustomeridorders","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/customers/{customerId}/orders\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/customers/\\{customerId\\}/orders\nRetrieves a list of customer orders based on the provided request parameters.\nParameters"},{"page":202,"heading":"GET /v1/customers/{customerId}/orders","anchor":"get-v1customerscustomeridorders","text":"Name | In | Type | Required | Description\ncustomerId | path | integer(int32) | true | The customer ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response"},{"page":202,"heading":"GET /v1/customers/{customerId}/orders","anchor":"get-v1customerscustomeridorders","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"orders\":[{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0}],\"totalOrdersCount\":0}"},{"page":202,"heading":"GET /v1/customers/{customerId}/orders","anchor":"get-v1customerscustomeridorders","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"orders\": [\n    {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": ["},{"page":202,"heading":"GET /v1/customers/{customerId}/orders","anchor":"get-v1customerscustomeridorders","text":"          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  ],\n  \"totalOrdersCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetCustomerOrdersResponse\nAuthentication: API key (x-api-key)."},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/customers/{customerId}/licenses \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/customers/{customerId}/licenses',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/customers/{customerId}/licenses\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/customers/\\{customerId\\}/licenses\nRetrieves a list of customer licenses based on the provided request parameters.\nParameters"},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"Name | In | Type | Required | Description\ncustomerId | path | integer(int32) | true | The customer ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response"},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"licenses\":[{\"id\":0,\"licenseId\":\"string\",\"licenseType\":\"string\",\"format\":0,\"description\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"supportExpireDate\":\"2019-08-24T14:15:22Z\",\"revoked\":true,\"trace\":true,\"licenseKey\":\"string\",\"maxAllowedSites\":0,\"userKey\":\"string\",\"licensingMode\":0,\"licenseeName\":\"string\",\"licenseeCompany\":\"string\",\"licenseeEmail\":\"string\",\"hash\":\"string\",\"meta\":\"string\",\"templateId\":0,\"signatureKeysId\":0,\"customerId\":0,\"orderId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapC"},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"oordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0},\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"template\":{\"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\":\"string\",\"template\":\"string\",\"productId\":"},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"licensee\":{\"name\":\"string\",\"company\":\"string\",\"contactInfo\":\"string\",\"url\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]}],\"totalLicensesCount\":0}"},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenses\": [\n    {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\","},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\""},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\","},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":202,"heading":"GET /v1/customers/{customerId}/licenses","anchor":"get-v1customerscustomeridlicenses","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicensesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetCustomerLicensesResponse\nAuthentication: API key (x-api-key)."},{"page":202,"heading":"DELETE /v1/customers/{customerId}","anchor":"delete-v1customerscustomerid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/customers/{customerId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/customers/{customerId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":202,"heading":"DELETE /v1/customers/{customerId}","anchor":"delete-v1customerscustomerid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/customers/{customerId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/customers/\\{customerId\\}\nDeletes an existing customer based on the provided request parameters.\nParameters\nName | In | Type | Required | Description\ncustomerId | path | integer(int32) | true | The customer ID."},{"page":202,"heading":"DELETE /v1/customers/{customerId}","anchor":"delete-v1customerscustomerid","text":"Example responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteCustomerResponse\nAuthentication: API key (x-api-key)."},{"page":203,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":203,"heading":"GET /v1/contacts","anchor":"get-v1contacts","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/contacts \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/contacts',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":203,"heading":"GET /v1/contacts","anchor":"get-v1contacts","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/contacts\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/contacts\nRetrieves a list of contacts based on the provided request parameters.\nParameters"},{"page":203,"heading":"GET /v1/contacts","anchor":"get-v1contacts","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}],\"totalContactsCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"contacts\": [\n    {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"details\": \"string\",\n      \"notify\": true,\n      \"customerId\": 0,\n      \"meta\": \"string\"\n    }\n  ],\n  \"totalContactsCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetContactsResponse\nAuthentication: API key (x-api-key)."},{"page":203,"heading":"POST /v1/contacts","anchor":"post-v1contacts","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/contacts \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"contact\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"details\": \"string\",\n    \"notify\": true,\n    \"customerId\": 0,\n    \"meta\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/contacts',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":203,"heading":"POST /v1/contacts","anchor":"post-v1contacts","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/contacts\";\n      \n      string json = @\"{\n  \"\"contact\"\": {\n    \"\"id\"\": 0,\n    \"\"title\"\": \"\"string\"\",\n    \"\"firstName\"\": \"\"string\"\",\n    \"\"lastName\"\": \"\"string\"\",\n    \"\"email\"\": \"\"string\"\",\n    \"\"phone\"\": \"\"string\"\",\n    \"\"mobile\"\": \"\"string\"\",\n    \"\"fax\"\": \"\"string\"\",\n    \"\"details\"\": \"\"string\"\",\n    \"\"notify\"\": true,\n    \"\"customerId\"\": 0,\n    \"\"meta\"\": \"\"string\"\"\n  }\n}\";\n      Management.InsertContactRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertContactRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json"},{"page":203,"heading":"POST /v1/contacts","anchor":"post-v1contacts","text":"    private StringContent SerializeObject(Management.InsertContactRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/contacts\nInserts a new contact based on the provided request parameters.\nBody parameter\n{\n  \"contact\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"details\": \"string\",\n    \"notify\": true,\n    \"customerId\": 0,\n    \"meta\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.InsertContactRequest | false | The request parameters for inserting a new contact.\nExample responses\n200 Response\n{\"contactId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"contactId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertContactResponse\nAuthentication: API key (x-api-key)."},{"page":203,"heading":"PUT /v1/contacts","anchor":"put-v1contacts","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/contacts \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"contact\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"details\": \"string\",\n    \"notify\": true,\n    \"customerId\": 0,\n    \"meta\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/contacts',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":203,"heading":"PUT /v1/contacts","anchor":"put-v1contacts","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/contacts\";\n\n      \n      string json = @\"{\n  \"\"contact\"\": {\n    \"\"id\"\": 0,\n    \"\"title\"\": \"\"string\"\",\n    \"\"firstName\"\": \"\"string\"\",\n    \"\"lastName\"\": \"\"string\"\",\n    \"\"email\"\": \"\"string\"\",\n    \"\"phone\"\": \"\"string\"\",\n    \"\"mobile\"\": \"\"string\"\",\n    \"\"fax\"\": \"\"string\"\",\n    \"\"details\"\": \"\"string\"\",\n    \"\"notify\"\": true,\n    \"\"customerId\"\": 0,\n    \"\"meta\"\": \"\"string\"\"\n  }\n}\";\n      Management.UpdateContactRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateContactRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response"},{"page":203,"heading":"PUT /v1/contacts","anchor":"put-v1contacts","text":"        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateContactRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/contacts\nUpdates an existing contact based on the provided request parameters.\nBody parameter\n{\n  \"contact\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"details\": \"string\",\n    \"notify\": true,\n    \"customerId\": 0,\n    \"meta\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.UpdateContactRequest | false | The request parameters for updating a contact.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses"},{"page":203,"heading":"PUT /v1/contacts","anchor":"put-v1contacts","text":"Status | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateContactResponse\nAuthentication: API key (x-api-key)."},{"page":203,"heading":"DELETE /v1/contacts/{contactId}","anchor":"delete-v1contactscontactid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/contacts/{contactId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/contacts/{contactId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":203,"heading":"DELETE /v1/contacts/{contactId}","anchor":"delete-v1contactscontactid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/contacts/{contactId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/contacts/\\{contactId\\}\nDeletes an existing contact based on the provided request parameters.\nParameters\nName | In | Type | Required | Description\ncontactId | path | integer(int32) | true | The ID of the contact to delete."},{"page":203,"heading":"DELETE /v1/contacts/{contactId}","anchor":"delete-v1contactscontactid","text":"Example responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteContactResponse\nAuthentication: API key (x-api-key)."},{"page":204,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":204,"heading":"GET /v1/products","anchor":"get-v1products","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/products \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":204,"heading":"GET /v1/products","anchor":"get-v1products","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/products\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/products\nGets the products based on the provided request.\nParameters"},{"page":204,"heading":"GET /v1/products","anchor":"get-v1products","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response"},{"page":204,"heading":"GET /v1/products","anchor":"get-v1products","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"products\":[{\"id\":0,\"code\":\"string\",\"name\":\"string\",\"description\":\"string\",\"url\":\"string\",\"copyright\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"image\":\"string\",\"price\":0.1,\"resellerPrice\":0.1,\"currency\":\"string\",\"signatureKeysId\":0,\"meta\":\"string\",\"isApplication\":true,\"updateChannelDefault\":\"string\",\"renewalUrl\":\"string\",\"signatureKeys\":{\"id\":0,\"name\":\"string\",\"type\":\"string\",\"code\":\"string\",\"description\":\"string\",\"source\":\"string\",\"password\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"data\":\"string\",\"dataFormat\":\"string\",\"meta\":\"string\"},\"productOrders\":[{\"productId\":0,\"orderId\":0,\"quantity\":0,\"unitPrice\":0.1,\"discount\":0.1,\"taxes\":0.1,\"description\":\"string\",\"product\":{},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"count"},{"page":204,"heading":"GET /v1/products","anchor":"get-v1products","text":"ry\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0}}]}],\"totalProductsCount\":0}"},{"page":204,"heading":"GET /v1/products","anchor":"get-v1products","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"products\": [\n    {\n      \"id\": 0,\n      \"code\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"url\": \"string\",\n      \"copyright\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"image\": \"string\",\n      \"price\": 0.1,\n      \"resellerPrice\": 0.1,\n      \"currency\": \"string\",\n      \"signatureKeysId\": 0,\n      \"meta\": \"string\",\n      \"isApplication\": true,\n      \"updateChannelDefault\": \"string\",\n      \"renewalUrl\": \"string\",\n      \"signatureKeys\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"type\": \"string\",\n        \"code\": \"string\",\n        \"description\": \"string\",\n        \"source\": \"string\",\n        \"password\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"data\": \"string\",\n        \"dataFormat\": \"string\",\n        \"meta\": \"string\"\n      },\n      \"productOrders\": [\n        {\n          \"productId\": 0,\n          \"orderId\": 0,\n          \"quantity\": 0,\n          \"unitPrice\": 0.1,\n          \"discount\": 0.1,\n          \"taxes\": 0.1,\n          \"description\": \"string\",\n          \"product\": {},\n          \"order\": {\n            \"id\": 0,\n            \"orderNumber\": \"string\",\n            \"status\": \"string\",\n            \"processedBy\": \"string\",\n            \"purchaseOrder\": \"string\",\n            \"total\": 0.1,\n            \"currency\": \"string\",\n            \"createdAt\": \"2019-08-24T14:15:22Z\","},{"page":204,"heading":"GET /v1/products","anchor":"get-v1products","text":"            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"invoiceNumber\": \"string\",\n            \"paymentType\": \"string\",\n            \"paymentNumber\": \"string\",\n            \"paymentStatus\": \"string\",\n            \"paymentDate\": \"2019-08-24T14:15:22Z\",\n            \"description\": \"string\",\n            \"customerId\": 0,\n            \"customer\": {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"company\": \"string\",\n              \"code\": \"string\",\n              \"vatCode\": \"string\",\n              \"invoiceCode\": \"string\",\n              \"rating\": 0,\n              \"createdAt\": \"2019-08-24T14:15:22Z\",\n              \"updatedAt\": \"2019-08-24T14:15:22Z\",\n              \"address\": \"string\",\n              \"address1\": \"string\",\n              \"address2\": \"string\",\n              \"postalCode\": \"string\",\n              \"region\": \"string\",\n              \"city\": \"string\",\n              \"country\": \"string\",\n              \"countryCode\": \"string\",\n              \"mapCoordinates\": \"string\",\n              \"mapZoomLevel\": 0.1,\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"website\": \"string\",\n              \"notes\": \"string\",\n              \"isReseller\": true,\n              \"image\": \"string\",\n              \"meta\": \"string\",\n              \"contacts\": [\n                {\n                  \"id\": 0,"},{"page":204,"heading":"GET /v1/products","anchor":"get-v1products","text":"                  \"title\": \"string\",\n                  \"firstName\": \"string\",\n                  \"lastName\": \"string\",\n                  \"email\": \"string\",\n                  \"phone\": \"string\",\n                  \"mobile\": \"string\",\n                  \"fax\": \"string\",\n                  \"details\": \"string\",\n                  \"notify\": true,\n                  \"customerId\": 0,\n                  \"meta\": \"string\"\n                }\n              ]\n            },\n            \"resellerId\": 0\n          }\n        }\n      ]\n    }\n  ],\n  \"totalProductsCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetProductsResponse\nAuthentication: API key (x-api-key)."},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/products \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"const inputBody = '{\n  \"product\": {\n    \"id\": 0,\n    \"code\": \"string\",\n    \"name\": \"string\",\n    \"description\": \"string\",\n    \"url\": \"string\",\n    \"copyright\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"image\": \"string\",\n    \"price\": 0.1,\n    \"resellerPrice\": 0.1,\n    \"currency\": \"string\",\n    \"signatureKeysId\": 0,\n    \"meta\": \"string\",\n    \"isApplication\": true,\n    \"updateChannelDefault\": \"string\",\n    \"renewalUrl\": \"string\",\n    \"signatureKeys\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"code\": \"string\",\n      \"description\": \"string\",\n      \"source\": \"string\",\n      \"password\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"data\": \"string\",\n      \"dataFormat\": \"string\",\n      \"meta\": \"string\"\n    },\n    \"productOrders\": [\n      {\n        \"productId\": 0,\n        \"orderId\": 0,\n        \"quantity\": 0,\n        \"unitPrice\": 0.1,\n        \"discount\": 0.1,\n        \"taxes\": 0.1,\n        \"description\": \"string\",\n        \"product\": {},\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\","},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"          \"paymentStatus\": \"string\",\n          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\","},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"                \"details\": \"string\",\n                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        }\n      }\n    ]\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/products\";\n      \n      string json = @\"{\n  \"\"product\"\": {\n    \"\"id\"\": 0,\n    \"\"code\"\": \"\"string\"\",\n    \"\"name\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"url\"\": \"\"string\"\",\n    \"\"copyright\"\": \"\"string\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"image\"\": \"\"string\"\",\n    \"\"price\"\": 0.1,\n    \"\"resellerPrice\"\": 0.1,\n    \"\"currency\"\": \"\"string\"\",\n    \"\"signatureKeysId\"\": 0,\n    \"\"meta\"\": \"\"string\"\",\n    \"\"isApplication\"\": true,\n    \"\"updateChannelDefault\"\": \"\"string\"\",\n    \"\"renewalUrl\"\": \"\"string\"\",\n    \"\"signatureKeys\"\": {\n      \"\"id\"\": 0,\n      \"\"name\"\": \"\"string\"\",\n      \"\"type\"\": \"\"string\"\",\n      \"\"code\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"source\"\": \"\"string\"\",\n      \"\"password\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"data\"\": \"\"string\"\",\n      \"\"dataFormat\"\": \"\"string\"\",\n      \"\"meta\"\": \"\"string\"\"\n    },"},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"    \"\"productOrders\"\": [\n      {\n        \"\"productId\"\": 0,\n        \"\"orderId\"\": 0,\n        \"\"quantity\"\": 0,\n        \"\"unitPrice\"\": 0.1,\n        \"\"discount\"\": 0.1,\n        \"\"taxes\"\": 0.1,\n        \"\"description\"\": \"\"string\"\",\n        \"\"product\"\": {},\n        \"\"order\"\": {\n          \"\"id\"\": 0,\n          \"\"orderNumber\"\": \"\"string\"\",\n          \"\"status\"\": \"\"string\"\",\n          \"\"processedBy\"\": \"\"string\"\",\n          \"\"purchaseOrder\"\": \"\"string\"\",\n          \"\"total\"\": 0.1,\n          \"\"currency\"\": \"\"string\"\",\n          \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"invoiceNumber\"\": \"\"string\"\",\n          \"\"paymentType\"\": \"\"string\"\",\n          \"\"paymentNumber\"\": \"\"string\"\",\n          \"\"paymentStatus\"\": \"\"string\"\",\n          \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"description\"\": \"\"string\"\",\n          \"\"customerId\"\": 0,\n          \"\"customer\"\": {\n            \"\"id\"\": 0,\n            \"\"title\"\": \"\"string\"\",\n            \"\"firstName\"\": \"\"string\"\",\n            \"\"lastName\"\": \"\"string\"\",\n            \"\"company\"\": \"\"string\"\",\n            \"\"code\"\": \"\"string\"\",\n            \"\"vatCode\"\": \"\"string\"\",\n            \"\"invoiceCode\"\": \"\"string\"\",\n            \"\"rating\"\": 0,\n            \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n            \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n            \"\"address\"\": \"\"string\"\",\n            \"\"address1\"\": \"\"string\"\",\n            \"\"address2\"\": \"\"string\"\",\n            \"\"postalCode\"\": \"\"string\"\","},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"            \"\"region\"\": \"\"string\"\",\n            \"\"city\"\": \"\"string\"\",\n            \"\"country\"\": \"\"string\"\",\n            \"\"countryCode\"\": \"\"string\"\",\n            \"\"mapCoordinates\"\": \"\"string\"\",\n            \"\"mapZoomLevel\"\": 0.1,\n            \"\"email\"\": \"\"string\"\",\n            \"\"phone\"\": \"\"string\"\",\n            \"\"mobile\"\": \"\"string\"\",\n            \"\"fax\"\": \"\"string\"\",\n            \"\"website\"\": \"\"string\"\",\n            \"\"notes\"\": \"\"string\"\",\n            \"\"isReseller\"\": true,\n            \"\"image\"\": \"\"string\"\",\n            \"\"meta\"\": \"\"string\"\",\n            \"\"contacts\"\": [\n              {\n                \"\"id\"\": 0,\n                \"\"title\"\": \"\"string\"\",\n                \"\"firstName\"\": \"\"string\"\",\n                \"\"lastName\"\": \"\"string\"\",\n                \"\"email\"\": \"\"string\"\",\n                \"\"phone\"\": \"\"string\"\",\n                \"\"mobile\"\": \"\"string\"\",\n                \"\"fax\"\": \"\"string\"\",\n                \"\"details\"\": \"\"string\"\",\n                \"\"notify\"\": true,\n                \"\"customerId\"\": 0,\n                \"\"meta\"\": \"\"string\"\"\n              }\n            ]\n          },\n          \"\"resellerId\"\": 0\n        }\n      }\n    ]\n  }\n}\";\n      Management.InsertProductRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertProductRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n"},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.InsertProductRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/products\nInserts a new product.\nBody parameter"},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"{\n  \"product\": {\n    \"id\": 0,\n    \"code\": \"string\",\n    \"name\": \"string\",\n    \"description\": \"string\",\n    \"url\": \"string\",\n    \"copyright\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"image\": \"string\",\n    \"price\": 0.1,\n    \"resellerPrice\": 0.1,\n    \"currency\": \"string\",\n    \"signatureKeysId\": 0,\n    \"meta\": \"string\",\n    \"isApplication\": true,\n    \"updateChannelDefault\": \"string\",\n    \"renewalUrl\": \"string\",\n    \"signatureKeys\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"code\": \"string\",\n      \"description\": \"string\",\n      \"source\": \"string\",\n      \"password\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"data\": \"string\",\n      \"dataFormat\": \"string\",\n      \"meta\": \"string\"\n    },\n    \"productOrders\": [\n      {\n        \"productId\": 0,\n        \"orderId\": 0,\n        \"quantity\": 0,\n        \"unitPrice\": 0.1,\n        \"discount\": 0.1,\n        \"taxes\": 0.1,\n        \"description\": \"string\",\n        \"product\": {},\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\","},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\","},{"page":204,"heading":"POST /v1/products","anchor":"post-v1products","text":"                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        }\n      }\n    ]\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.InsertProductRequest | false | The request containing the product to insert.\nExample responses\n200 Response\n{\"productId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"productId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertProductResponse\nAuthentication: API key (x-api-key)."},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/products \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"const inputBody = '{\n  \"product\": {\n    \"id\": 0,\n    \"code\": \"string\",\n    \"name\": \"string\",\n    \"description\": \"string\",\n    \"url\": \"string\",\n    \"copyright\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"image\": \"string\",\n    \"price\": 0.1,\n    \"resellerPrice\": 0.1,\n    \"currency\": \"string\",\n    \"signatureKeysId\": 0,\n    \"meta\": \"string\",\n    \"isApplication\": true,\n    \"updateChannelDefault\": \"string\",\n    \"renewalUrl\": \"string\",\n    \"signatureKeys\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"code\": \"string\",\n      \"description\": \"string\",\n      \"source\": \"string\",\n      \"password\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"data\": \"string\",\n      \"dataFormat\": \"string\",\n      \"meta\": \"string\"\n    },\n    \"productOrders\": [\n      {\n        \"productId\": 0,\n        \"orderId\": 0,\n        \"quantity\": 0,\n        \"unitPrice\": 0.1,\n        \"discount\": 0.1,\n        \"taxes\": 0.1,\n        \"description\": \"string\",\n        \"product\": {},\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\","},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"          \"paymentStatus\": \"string\",\n          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\","},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"                \"details\": \"string\",\n                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        }\n      }\n    ]\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/products\";\n\n      \n      string json = @\"{\n  \"\"product\"\": {\n    \"\"id\"\": 0,\n    \"\"code\"\": \"\"string\"\",\n    \"\"name\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"url\"\": \"\"string\"\",\n    \"\"copyright\"\": \"\"string\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"image\"\": \"\"string\"\",\n    \"\"price\"\": 0.1,\n    \"\"resellerPrice\"\": 0.1,\n    \"\"currency\"\": \"\"string\"\",\n    \"\"signatureKeysId\"\": 0,\n    \"\"meta\"\": \"\"string\"\",\n    \"\"isApplication\"\": true,\n    \"\"updateChannelDefault\"\": \"\"string\"\",\n    \"\"renewalUrl\"\": \"\"string\"\",\n    \"\"signatureKeys\"\": {\n      \"\"id\"\": 0,\n      \"\"name\"\": \"\"string\"\",\n      \"\"type\"\": \"\"string\"\",\n      \"\"code\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"source\"\": \"\"string\"\",\n      \"\"password\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"data\"\": \"\"string\"\",\n      \"\"dataFormat\"\": \"\"string\"\",\n      \"\"meta\"\": \"\"string\"\""},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"    },\n    \"\"productOrders\"\": [\n      {\n        \"\"productId\"\": 0,\n        \"\"orderId\"\": 0,\n        \"\"quantity\"\": 0,\n        \"\"unitPrice\"\": 0.1,\n        \"\"discount\"\": 0.1,\n        \"\"taxes\"\": 0.1,\n        \"\"description\"\": \"\"string\"\",\n        \"\"product\"\": {},\n        \"\"order\"\": {\n          \"\"id\"\": 0,\n          \"\"orderNumber\"\": \"\"string\"\",\n          \"\"status\"\": \"\"string\"\",\n          \"\"processedBy\"\": \"\"string\"\",\n          \"\"purchaseOrder\"\": \"\"string\"\",\n          \"\"total\"\": 0.1,\n          \"\"currency\"\": \"\"string\"\",\n          \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"invoiceNumber\"\": \"\"string\"\",\n          \"\"paymentType\"\": \"\"string\"\",\n          \"\"paymentNumber\"\": \"\"string\"\",\n          \"\"paymentStatus\"\": \"\"string\"\",\n          \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"description\"\": \"\"string\"\",\n          \"\"customerId\"\": 0,\n          \"\"customer\"\": {\n            \"\"id\"\": 0,\n            \"\"title\"\": \"\"string\"\",\n            \"\"firstName\"\": \"\"string\"\",\n            \"\"lastName\"\": \"\"string\"\",\n            \"\"company\"\": \"\"string\"\",\n            \"\"code\"\": \"\"string\"\",\n            \"\"vatCode\"\": \"\"string\"\",\n            \"\"invoiceCode\"\": \"\"string\"\",\n            \"\"rating\"\": 0,\n            \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n            \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n            \"\"address\"\": \"\"string\"\",\n            \"\"address1\"\": \"\"string\"\",\n            \"\"address2\"\": \"\"string\"\",\n            \"\"postalCode\"\": \"\"string\"\","},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"            \"\"region\"\": \"\"string\"\",\n            \"\"city\"\": \"\"string\"\",\n            \"\"country\"\": \"\"string\"\",\n            \"\"countryCode\"\": \"\"string\"\",\n            \"\"mapCoordinates\"\": \"\"string\"\",\n            \"\"mapZoomLevel\"\": 0.1,\n            \"\"email\"\": \"\"string\"\",\n            \"\"phone\"\": \"\"string\"\",\n            \"\"mobile\"\": \"\"string\"\",\n            \"\"fax\"\": \"\"string\"\",\n            \"\"website\"\": \"\"string\"\",\n            \"\"notes\"\": \"\"string\"\",\n            \"\"isReseller\"\": true,\n            \"\"image\"\": \"\"string\"\",\n            \"\"meta\"\": \"\"string\"\",\n            \"\"contacts\"\": [\n              {\n                \"\"id\"\": 0,\n                \"\"title\"\": \"\"string\"\",\n                \"\"firstName\"\": \"\"string\"\",\n                \"\"lastName\"\": \"\"string\"\",\n                \"\"email\"\": \"\"string\"\",\n                \"\"phone\"\": \"\"string\"\",\n                \"\"mobile\"\": \"\"string\"\",\n                \"\"fax\"\": \"\"string\"\",\n                \"\"details\"\": \"\"string\"\",\n                \"\"notify\"\": true,\n                \"\"customerId\"\": 0,\n                \"\"meta\"\": \"\"string\"\"\n              }\n            ]\n          },\n          \"\"resellerId\"\": 0\n        }\n      }\n    ]\n  }\n}\";\n      Management.UpdateProductRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateProductRequest content, string url)\n    {\n        //Serialize Object"},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateProductRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/products\nUpdates an existing product.\nBody parameter"},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"{\n  \"product\": {\n    \"id\": 0,\n    \"code\": \"string\",\n    \"name\": \"string\",\n    \"description\": \"string\",\n    \"url\": \"string\",\n    \"copyright\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"image\": \"string\",\n    \"price\": 0.1,\n    \"resellerPrice\": 0.1,\n    \"currency\": \"string\",\n    \"signatureKeysId\": 0,\n    \"meta\": \"string\",\n    \"isApplication\": true,\n    \"updateChannelDefault\": \"string\",\n    \"renewalUrl\": \"string\",\n    \"signatureKeys\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"code\": \"string\",\n      \"description\": \"string\",\n      \"source\": \"string\",\n      \"password\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"data\": \"string\",\n      \"dataFormat\": \"string\",\n      \"meta\": \"string\"\n    },\n    \"productOrders\": [\n      {\n        \"productId\": 0,\n        \"orderId\": 0,\n        \"quantity\": 0,\n        \"unitPrice\": 0.1,\n        \"discount\": 0.1,\n        \"taxes\": 0.1,\n        \"description\": \"string\",\n        \"product\": {},\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\","},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\","},{"page":204,"heading":"PUT /v1/products","anchor":"put-v1products","text":"                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        }\n      }\n    ]\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.UpdateProductRequest | false | The request containing the product to update.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateProductResponse\nAuthentication: API key (x-api-key)."},{"page":204,"heading":"DELETE /v1/products/{productId}","anchor":"delete-v1productsproductid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/products/{productId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":204,"heading":"DELETE /v1/products/{productId}","anchor":"delete-v1productsproductid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/products/{productId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/products/\\{productId\\}\nDeletes an existing product.\nParameters\nName | In | Type | Required | Description\nproductId | path | integer(int32) | true | The ID of the product to delete.\nExample responses\n200 Response"},{"page":204,"heading":"DELETE /v1/products/{productId}","anchor":"delete-v1productsproductid","text":"{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteProductResponse\nAuthentication: API key (x-api-key)."},{"page":204,"heading":"GET /v1/products/{productId}/orders","anchor":"get-v1productsproductidorders","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/products/{productId}/orders \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/orders',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":204,"heading":"GET /v1/products/{productId}/orders","anchor":"get-v1productsproductidorders","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/products/{productId}/orders\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/products/\\{productId\\}/orders\nGets the product orders based on the provided request.\nParameters"},{"page":204,"heading":"GET /v1/products/{productId}/orders","anchor":"get-v1productsproductidorders","text":"Name | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response"},{"page":204,"heading":"GET /v1/products/{productId}/orders","anchor":"get-v1productsproductidorders","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"productOrders\":[{\"productId\":0,\"orderId\":0,\"quantity\":0,\"unitPrice\":0.1,\"discount\":0.1,\"taxes\":0.1,\"description\":\"string\",\"product\":{\"id\":0,\"code\":\"string\",\"name\":\"string\",\"description\":\"string\",\"url\":\"string\",\"copyright\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"image\":\"string\",\"price\":0.1,\"resellerPrice\":0.1,\"currency\":\"string\",\"signatureKeysId\":0,\"meta\":\"string\",\"isApplication\":true,\"updateChannelDefault\":\"string\",\"renewalUrl\":\"string\",\"signatureKeys\":{\"id\":0,\"name\":\"string\",\"type\":\"string\",\"code\":\"string\",\"description\":\"string\",\"source\":\"string\",\"password\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"data\":\"string\",\"dataFormat\":\"string\",\"meta\":\"string\"},\"productOrders\":[{}]},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\""},{"page":204,"heading":"GET /v1/products/{productId}/orders","anchor":"get-v1productsproductidorders","text":",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0}}],\"totalProductOrdersCount\":0}"},{"page":204,"heading":"GET /v1/products/{productId}/orders","anchor":"get-v1productsproductidorders","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"productOrders\": [\n    {\n      \"productId\": 0,\n      \"orderId\": 0,\n      \"quantity\": 0,\n      \"unitPrice\": 0.1,\n      \"discount\": 0.1,\n      \"taxes\": 0.1,\n      \"description\": \"string\",\n      \"product\": {\n        \"id\": 0,\n        \"code\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"url\": \"string\",\n        \"copyright\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"image\": \"string\",\n        \"price\": 0.1,\n        \"resellerPrice\": 0.1,\n        \"currency\": \"string\",\n        \"signatureKeysId\": 0,\n        \"meta\": \"string\",\n        \"isApplication\": true,\n        \"updateChannelDefault\": \"string\",\n        \"renewalUrl\": \"string\",\n        \"signatureKeys\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"type\": \"string\",\n          \"code\": \"string\",\n          \"description\": \"string\",\n          \"source\": \"string\",\n          \"password\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"data\": \"string\",\n          \"dataFormat\": \"string\",\n          \"meta\": \"string\"\n        },\n        \"productOrders\": [\n          {}\n        ]\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\","},{"page":204,"heading":"GET /v1/products/{productId}/orders","anchor":"get-v1productsproductidorders","text":"        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\","},{"page":204,"heading":"GET /v1/products/{productId}/orders","anchor":"get-v1productsproductidorders","text":"              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      }\n    }\n  ],\n  \"totalProductOrdersCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetProductOrdersResponse\nAuthentication: API key (x-api-key)."},{"page":205,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":205,"heading":"GET /v1/orders","anchor":"get-v1orders","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/orders \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/orders',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":205,"heading":"GET /v1/orders","anchor":"get-v1orders","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/orders\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/orders\nGets the orders based on the provided request parameters.\nParameters"},{"page":205,"heading":"GET /v1/orders","anchor":"get-v1orders","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response"},{"page":205,"heading":"GET /v1/orders","anchor":"get-v1orders","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"orders\":[{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0}],\"totalOrdersCount\":0}"},{"page":205,"heading":"GET /v1/orders","anchor":"get-v1orders","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"orders\": [\n    {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": ["},{"page":205,"heading":"GET /v1/orders","anchor":"get-v1orders","text":"          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  ],\n  \"totalOrdersCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetOrdersResponse\nAuthentication: API key (x-api-key)."},{"page":205,"heading":"POST /v1/orders","anchor":"post-v1orders","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/orders \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":205,"heading":"POST /v1/orders","anchor":"post-v1orders","text":"const inputBody = '{\n  \"order\": {\n    \"id\": 0,\n    \"orderNumber\": \"string\",\n    \"status\": \"string\",\n    \"processedBy\": \"string\",\n    \"purchaseOrder\": \"string\",\n    \"total\": 0.1,\n    \"currency\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"invoiceNumber\": \"string\",\n    \"paymentType\": \"string\",\n    \"paymentNumber\": \"string\",\n    \"paymentStatus\": \"string\",\n    \"paymentDate\": \"2019-08-24T14:15:22Z\",\n    \"description\": \"string\",\n    \"customerId\": 0,\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\","},{"page":205,"heading":"POST /v1/orders","anchor":"post-v1orders","text":"          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"resellerId\": 0\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/orders',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":205,"heading":"POST /v1/orders","anchor":"post-v1orders","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/orders\";\n      \n      string json = @\"{\n  \"\"order\"\": {\n    \"\"id\"\": 0,\n    \"\"orderNumber\"\": \"\"string\"\",\n    \"\"status\"\": \"\"string\"\",\n    \"\"processedBy\"\": \"\"string\"\",\n    \"\"purchaseOrder\"\": \"\"string\"\",\n    \"\"total\"\": 0.1,\n    \"\"currency\"\": \"\"string\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"invoiceNumber\"\": \"\"string\"\",\n    \"\"paymentType\"\": \"\"string\"\",\n    \"\"paymentNumber\"\": \"\"string\"\",\n    \"\"paymentStatus\"\": \"\"string\"\",\n    \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"customerId\"\": 0,\n    \"\"customer\"\": {\n      \"\"id\"\": 0,\n      \"\"title\"\": \"\"string\"\",\n      \"\"firstName\"\": \"\"string\"\",\n      \"\"lastName\"\": \"\"string\"\",\n      \"\"company\"\": \"\"string\"\",\n      \"\"code\"\": \"\"string\"\",\n      \"\"vatCode\"\": \"\"string\"\",\n      \"\"invoiceCode\"\": \"\"string\"\",\n      \"\"rating\"\": 0,\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\","},{"page":205,"heading":"POST /v1/orders","anchor":"post-v1orders","text":"      \"\"address\"\": \"\"string\"\",\n      \"\"address1\"\": \"\"string\"\",\n      \"\"address2\"\": \"\"string\"\",\n      \"\"postalCode\"\": \"\"string\"\",\n      \"\"region\"\": \"\"string\"\",\n      \"\"city\"\": \"\"string\"\",\n      \"\"country\"\": \"\"string\"\",\n      \"\"countryCode\"\": \"\"string\"\",\n      \"\"mapCoordinates\"\": \"\"string\"\",\n      \"\"mapZoomLevel\"\": 0.1,\n      \"\"email\"\": \"\"string\"\",\n      \"\"phone\"\": \"\"string\"\",\n      \"\"mobile\"\": \"\"string\"\",\n      \"\"fax\"\": \"\"string\"\",\n      \"\"website\"\": \"\"string\"\",\n      \"\"notes\"\": \"\"string\"\",\n      \"\"isReseller\"\": true,\n      \"\"image\"\": \"\"string\"\",\n      \"\"meta\"\": \"\"string\"\",\n      \"\"contacts\"\": [\n        {\n          \"\"id\"\": 0,\n          \"\"title\"\": \"\"string\"\",\n          \"\"firstName\"\": \"\"string\"\",\n          \"\"lastName\"\": \"\"string\"\",\n          \"\"email\"\": \"\"string\"\",\n          \"\"phone\"\": \"\"string\"\",\n          \"\"mobile\"\": \"\"string\"\",\n          \"\"fax\"\": \"\"string\"\",\n          \"\"details\"\": \"\"string\"\",\n          \"\"notify\"\": true,\n          \"\"customerId\"\": 0,\n          \"\"meta\"\": \"\"string\"\"\n        }\n      ]\n    },\n    \"\"resellerId\"\": 0\n  }\n}\";\n      Management.InsertOrderRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertOrderRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request"},{"page":205,"heading":"POST /v1/orders","anchor":"post-v1orders","text":"        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.InsertOrderRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/orders\nInserts a new order.\nBody parameter"},{"page":205,"heading":"POST /v1/orders","anchor":"post-v1orders","text":"{\n  \"order\": {\n    \"id\": 0,\n    \"orderNumber\": \"string\",\n    \"status\": \"string\",\n    \"processedBy\": \"string\",\n    \"purchaseOrder\": \"string\",\n    \"total\": 0.1,\n    \"currency\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"invoiceNumber\": \"string\",\n    \"paymentType\": \"string\",\n    \"paymentNumber\": \"string\",\n    \"paymentStatus\": \"string\",\n    \"paymentDate\": \"2019-08-24T14:15:22Z\",\n    \"description\": \"string\",\n    \"customerId\": 0,\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\","},{"page":205,"heading":"POST /v1/orders","anchor":"post-v1orders","text":"          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"resellerId\": 0\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.InsertOrderRequest | false | The request containing the details of the order to insert.\nExample responses\n200 Response\n{\"orderId\":0,\"success\":true,\"code\":0,\"message\":\"string\",\"orderNumber\":\"string\"}\n{\n  \"orderId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"orderNumber\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertOrderResponse\nAuthentication: API key (x-api-key)."},{"page":205,"heading":"PUT /v1/orders","anchor":"put-v1orders","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/orders \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":205,"heading":"PUT /v1/orders","anchor":"put-v1orders","text":"const inputBody = '{\n  \"order\": {\n    \"id\": 0,\n    \"orderNumber\": \"string\",\n    \"status\": \"string\",\n    \"processedBy\": \"string\",\n    \"purchaseOrder\": \"string\",\n    \"total\": 0.1,\n    \"currency\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"invoiceNumber\": \"string\",\n    \"paymentType\": \"string\",\n    \"paymentNumber\": \"string\",\n    \"paymentStatus\": \"string\",\n    \"paymentDate\": \"2019-08-24T14:15:22Z\",\n    \"description\": \"string\",\n    \"customerId\": 0,\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\","},{"page":205,"heading":"PUT /v1/orders","anchor":"put-v1orders","text":"          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"resellerId\": 0\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/orders',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":205,"heading":"PUT /v1/orders","anchor":"put-v1orders","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/orders\";\n\n      \n      string json = @\"{\n  \"\"order\"\": {\n    \"\"id\"\": 0,\n    \"\"orderNumber\"\": \"\"string\"\",\n    \"\"status\"\": \"\"string\"\",\n    \"\"processedBy\"\": \"\"string\"\",\n    \"\"purchaseOrder\"\": \"\"string\"\",\n    \"\"total\"\": 0.1,\n    \"\"currency\"\": \"\"string\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"invoiceNumber\"\": \"\"string\"\",\n    \"\"paymentType\"\": \"\"string\"\",\n    \"\"paymentNumber\"\": \"\"string\"\",\n    \"\"paymentStatus\"\": \"\"string\"\",\n    \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"customerId\"\": 0,\n    \"\"customer\"\": {\n      \"\"id\"\": 0,\n      \"\"title\"\": \"\"string\"\",\n      \"\"firstName\"\": \"\"string\"\",\n      \"\"lastName\"\": \"\"string\"\",\n      \"\"company\"\": \"\"string\"\",\n      \"\"code\"\": \"\"string\"\",\n      \"\"vatCode\"\": \"\"string\"\",\n      \"\"invoiceCode\"\": \"\"string\"\",\n      \"\"rating\"\": 0,\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\","},{"page":205,"heading":"PUT /v1/orders","anchor":"put-v1orders","text":"      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"address\"\": \"\"string\"\",\n      \"\"address1\"\": \"\"string\"\",\n      \"\"address2\"\": \"\"string\"\",\n      \"\"postalCode\"\": \"\"string\"\",\n      \"\"region\"\": \"\"string\"\",\n      \"\"city\"\": \"\"string\"\",\n      \"\"country\"\": \"\"string\"\",\n      \"\"countryCode\"\": \"\"string\"\",\n      \"\"mapCoordinates\"\": \"\"string\"\",\n      \"\"mapZoomLevel\"\": 0.1,\n      \"\"email\"\": \"\"string\"\",\n      \"\"phone\"\": \"\"string\"\",\n      \"\"mobile\"\": \"\"string\"\",\n      \"\"fax\"\": \"\"string\"\",\n      \"\"website\"\": \"\"string\"\",\n      \"\"notes\"\": \"\"string\"\",\n      \"\"isReseller\"\": true,\n      \"\"image\"\": \"\"string\"\",\n      \"\"meta\"\": \"\"string\"\",\n      \"\"contacts\"\": [\n        {\n          \"\"id\"\": 0,\n          \"\"title\"\": \"\"string\"\",\n          \"\"firstName\"\": \"\"string\"\",\n          \"\"lastName\"\": \"\"string\"\",\n          \"\"email\"\": \"\"string\"\",\n          \"\"phone\"\": \"\"string\"\",\n          \"\"mobile\"\": \"\"string\"\",\n          \"\"fax\"\": \"\"string\"\",\n          \"\"details\"\": \"\"string\"\",\n          \"\"notify\"\": true,\n          \"\"customerId\"\": 0,\n          \"\"meta\"\": \"\"string\"\"\n        }\n      ]\n    },\n    \"\"resellerId\"\": 0\n  }\n}\";\n      Management.UpdateOrderRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateOrderRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n"},{"page":205,"heading":"PUT /v1/orders","anchor":"put-v1orders","text":"        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateOrderRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/orders\nUpdates an existing order.\nBody parameter"},{"page":205,"heading":"PUT /v1/orders","anchor":"put-v1orders","text":"{\n  \"order\": {\n    \"id\": 0,\n    \"orderNumber\": \"string\",\n    \"status\": \"string\",\n    \"processedBy\": \"string\",\n    \"purchaseOrder\": \"string\",\n    \"total\": 0.1,\n    \"currency\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"invoiceNumber\": \"string\",\n    \"paymentType\": \"string\",\n    \"paymentNumber\": \"string\",\n    \"paymentStatus\": \"string\",\n    \"paymentDate\": \"2019-08-24T14:15:22Z\",\n    \"description\": \"string\",\n    \"customerId\": 0,\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\","},{"page":205,"heading":"PUT /v1/orders","anchor":"put-v1orders","text":"          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"resellerId\": 0\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.UpdateOrderRequest | false | The request containing the details of the order to update.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateOrderResponse\nAuthentication: API key (x-api-key)."},{"page":205,"heading":"DELETE /v1/orders/{orderId}","anchor":"delete-v1ordersorderid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/orders/{orderId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/orders/{orderId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":205,"heading":"DELETE /v1/orders/{orderId}","anchor":"delete-v1ordersorderid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/orders/{orderId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/orders/\\{orderId\\}\nDeletes an existing order.\nParameters\nName | In | Type | Required | Description\norderId | path | integer(int32) | true | The order ID.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}"},{"page":205,"heading":"DELETE /v1/orders/{orderId}","anchor":"delete-v1ordersorderid","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteOrderResponse\nAuthentication: API key (x-api-key)."},{"page":206,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":206,"heading":"GET /v1/orders/{orderId}/products","anchor":"get-v1ordersorderidproducts","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/orders/{orderId}/products \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/orders/{orderId}/products',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":206,"heading":"GET /v1/orders/{orderId}/products","anchor":"get-v1ordersorderidproducts","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/orders/{orderId}/products\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/orders/\\{orderId\\}/products\nGets the products for a specific order.\nParameters"},{"page":206,"heading":"GET /v1/orders/{orderId}/products","anchor":"get-v1ordersorderidproducts","text":"Name | In | Type | Required | Description\norderId | path | integer(int32) | true | The order ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\ninclude | query | string | false | none\nExample responses\n200 Response"},{"page":206,"heading":"GET /v1/orders/{orderId}/products","anchor":"get-v1ordersorderidproducts","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"orderProducts\":[{\"productId\":0,\"orderId\":0,\"quantity\":0,\"unitPrice\":0.1,\"discount\":0.1,\"taxes\":0.1,\"description\":\"string\",\"product\":{\"id\":0,\"code\":\"string\",\"name\":\"string\",\"description\":\"string\",\"url\":\"string\",\"copyright\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"image\":\"string\",\"price\":0.1,\"resellerPrice\":0.1,\"currency\":\"string\",\"signatureKeysId\":0,\"meta\":\"string\",\"isApplication\":true,\"updateChannelDefault\":\"string\",\"renewalUrl\":\"string\",\"signatureKeys\":{\"id\":0,\"name\":\"string\",\"type\":\"string\",\"code\":\"string\",\"description\":\"string\",\"source\":\"string\",\"password\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"data\":\"string\",\"dataFormat\":\"string\",\"meta\":\"string\"},\"productOrders\":[{}]},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\""},{"page":206,"heading":"GET /v1/orders/{orderId}/products","anchor":"get-v1ordersorderidproducts","text":",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0}}],\"totalOrderProductsCount\":0}"},{"page":206,"heading":"GET /v1/orders/{orderId}/products","anchor":"get-v1ordersorderidproducts","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"orderProducts\": [\n    {\n      \"productId\": 0,\n      \"orderId\": 0,\n      \"quantity\": 0,\n      \"unitPrice\": 0.1,\n      \"discount\": 0.1,\n      \"taxes\": 0.1,\n      \"description\": \"string\",\n      \"product\": {\n        \"id\": 0,\n        \"code\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"url\": \"string\",\n        \"copyright\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"image\": \"string\",\n        \"price\": 0.1,\n        \"resellerPrice\": 0.1,\n        \"currency\": \"string\",\n        \"signatureKeysId\": 0,\n        \"meta\": \"string\",\n        \"isApplication\": true,\n        \"updateChannelDefault\": \"string\",\n        \"renewalUrl\": \"string\",\n        \"signatureKeys\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"type\": \"string\",\n          \"code\": \"string\",\n          \"description\": \"string\",\n          \"source\": \"string\",\n          \"password\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"data\": \"string\",\n          \"dataFormat\": \"string\",\n          \"meta\": \"string\"\n        },\n        \"productOrders\": [\n          {}\n        ]\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\","},{"page":206,"heading":"GET /v1/orders/{orderId}/products","anchor":"get-v1ordersorderidproducts","text":"        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\","},{"page":206,"heading":"GET /v1/orders/{orderId}/products","anchor":"get-v1ordersorderidproducts","text":"              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      }\n    }\n  ],\n  \"totalOrderProductsCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetOrderProductsResponse\nAuthentication: API key (x-api-key)."},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/orders/{orderId}/products/{productId} \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"const inputBody = '{\n  \"productOrder\": {\n    \"productId\": 0,\n    \"orderId\": 0,\n    \"quantity\": 0,\n    \"unitPrice\": 0.1,\n    \"discount\": 0.1,\n    \"taxes\": 0.1,\n    \"description\": \"string\",\n    \"product\": {\n      \"id\": 0,\n      \"code\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"url\": \"string\",\n      \"copyright\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"image\": \"string\",\n      \"price\": 0.1,\n      \"resellerPrice\": 0.1,\n      \"currency\": \"string\",\n      \"signatureKeysId\": 0,\n      \"meta\": \"string\",\n      \"isApplication\": true,\n      \"updateChannelDefault\": \"string\",\n      \"renewalUrl\": \"string\",\n      \"signatureKeys\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"type\": \"string\",\n        \"code\": \"string\",\n        \"description\": \"string\",\n        \"source\": \"string\",\n        \"password\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"data\": \"string\",\n        \"dataFormat\": \"string\",\n        \"meta\": \"string\"\n      },\n      \"productOrders\": [\n        {}\n      ]\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\","},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  }\n}';"},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"const headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/orders/{orderId}/products/{productId}',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/orders/{orderId}/products/{productId}\";\n      \n      string json = @\"{\n  \"\"productOrder\"\": {\n    \"\"productId\"\": 0,\n    \"\"orderId\"\": 0,\n    \"\"quantity\"\": 0,\n    \"\"unitPrice\"\": 0.1,\n    \"\"discount\"\": 0.1,\n    \"\"taxes\"\": 0.1,\n    \"\"description\"\": \"\"string\"\",\n    \"\"product\"\": {\n      \"\"id\"\": 0,\n      \"\"code\"\": \"\"string\"\",\n      \"\"name\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"url\"\": \"\"string\"\",\n      \"\"copyright\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"image\"\": \"\"string\"\",\n      \"\"price\"\": 0.1,\n      \"\"resellerPrice\"\": 0.1,\n      \"\"currency\"\": \"\"string\"\",\n      \"\"signatureKeysId\"\": 0,\n      \"\"meta\"\": \"\"string\"\",\n      \"\"isApplication\"\": true,\n      \"\"updateChannelDefault\"\": \"\"string\"\",\n      \"\"renewalUrl\"\": \"\"string\"\",\n      \"\"signatureKeys\"\": {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\",\n        \"\"type\"\": \"\"string\"\",\n        \"\"code\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\","},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"        \"\"source\"\": \"\"string\"\",\n        \"\"password\"\": \"\"string\"\",\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"data\"\": \"\"string\"\",\n        \"\"dataFormat\"\": \"\"string\"\",\n        \"\"meta\"\": \"\"string\"\"\n      },\n      \"\"productOrders\"\": [\n        {}\n      ]\n    },\n    \"\"order\"\": {\n      \"\"id\"\": 0,\n      \"\"orderNumber\"\": \"\"string\"\",\n      \"\"status\"\": \"\"string\"\",\n      \"\"processedBy\"\": \"\"string\"\",\n      \"\"purchaseOrder\"\": \"\"string\"\",\n      \"\"total\"\": 0.1,\n      \"\"currency\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"invoiceNumber\"\": \"\"string\"\",\n      \"\"paymentType\"\": \"\"string\"\",\n      \"\"paymentNumber\"\": \"\"string\"\",\n      \"\"paymentStatus\"\": \"\"string\"\",\n      \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"customerId\"\": 0,\n      \"\"customer\"\": {\n        \"\"id\"\": 0,\n        \"\"title\"\": \"\"string\"\",\n        \"\"firstName\"\": \"\"string\"\",\n        \"\"lastName\"\": \"\"string\"\",\n        \"\"company\"\": \"\"string\"\",\n        \"\"code\"\": \"\"string\"\",\n        \"\"vatCode\"\": \"\"string\"\",\n        \"\"invoiceCode\"\": \"\"string\"\",\n        \"\"rating\"\": 0,\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"address\"\": \"\"string\"\",\n        \"\"address1\"\": \"\"string\"\",\n        \"\"address2\"\": \"\"string\"\",\n        \"\"postalCode\"\": \"\"string\"\",\n        \"\"region\"\": \"\"string\"\",\n        \"\"city\"\": \"\"string\"\","},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"        \"\"country\"\": \"\"string\"\",\n        \"\"countryCode\"\": \"\"string\"\",\n        \"\"mapCoordinates\"\": \"\"string\"\",\n        \"\"mapZoomLevel\"\": 0.1,\n        \"\"email\"\": \"\"string\"\",\n        \"\"phone\"\": \"\"string\"\",\n        \"\"mobile\"\": \"\"string\"\",\n        \"\"fax\"\": \"\"string\"\",\n        \"\"website\"\": \"\"string\"\",\n        \"\"notes\"\": \"\"string\"\",\n        \"\"isReseller\"\": true,\n        \"\"image\"\": \"\"string\"\",\n        \"\"meta\"\": \"\"string\"\",\n        \"\"contacts\"\": [\n          {\n            \"\"id\"\": 0,\n            \"\"title\"\": \"\"string\"\",\n            \"\"firstName\"\": \"\"string\"\",\n            \"\"lastName\"\": \"\"string\"\",\n            \"\"email\"\": \"\"string\"\",\n            \"\"phone\"\": \"\"string\"\",\n            \"\"mobile\"\": \"\"string\"\",\n            \"\"fax\"\": \"\"string\"\",\n            \"\"details\"\": \"\"string\"\",\n            \"\"notify\"\": true,\n            \"\"customerId\"\": 0,\n            \"\"meta\"\": \"\"string\"\"\n          }\n        ]\n      },\n      \"\"resellerId\"\": 0\n    }\n  }\n}\";\n      Management.InsertProductOrderRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertProductOrderRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json"},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"    private StringContent SerializeObject(Management.InsertProductOrderRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/orders/\\{orderId\\}/products/\\{productId\\}\nInserts a new product order.\nBody parameter"},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"{\n  \"productOrder\": {\n    \"productId\": 0,\n    \"orderId\": 0,\n    \"quantity\": 0,\n    \"unitPrice\": 0.1,\n    \"discount\": 0.1,\n    \"taxes\": 0.1,\n    \"description\": \"string\",\n    \"product\": {\n      \"id\": 0,\n      \"code\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"url\": \"string\",\n      \"copyright\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"image\": \"string\",\n      \"price\": 0.1,\n      \"resellerPrice\": 0.1,\n      \"currency\": \"string\",\n      \"signatureKeysId\": 0,\n      \"meta\": \"string\",\n      \"isApplication\": true,\n      \"updateChannelDefault\": \"string\",\n      \"renewalUrl\": \"string\",\n      \"signatureKeys\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"type\": \"string\",\n        \"code\": \"string\",\n        \"description\": \"string\",\n        \"source\": \"string\",\n        \"password\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"data\": \"string\",\n        \"dataFormat\": \"string\",\n        \"meta\": \"string\"\n      },\n      \"productOrders\": [\n        {}\n      ]\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\","},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  }\n}\nParameters"},{"page":206,"heading":"POST /v1/orders/{orderId}/products/{productId}","anchor":"post-v1ordersorderidproductsproductid","text":"Name | In | Type | Required | Description\norderId | path | integer(int32) | true | The order ID.\nproductId | path | integer(int32) | true | The product ID.\nbody | body | Management.InsertProductOrderRequest | false | The request containing the details of the product order to insert.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertProductOrderResponse\nAuthentication: API key (x-api-key)."},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/orders/{orderId}/products/{productId} \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"const inputBody = '{\n  \"productOrder\": {\n    \"productId\": 0,\n    \"orderId\": 0,\n    \"quantity\": 0,\n    \"unitPrice\": 0.1,\n    \"discount\": 0.1,\n    \"taxes\": 0.1,\n    \"description\": \"string\",\n    \"product\": {\n      \"id\": 0,\n      \"code\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"url\": \"string\",\n      \"copyright\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"image\": \"string\",\n      \"price\": 0.1,\n      \"resellerPrice\": 0.1,\n      \"currency\": \"string\",\n      \"signatureKeysId\": 0,\n      \"meta\": \"string\",\n      \"isApplication\": true,\n      \"updateChannelDefault\": \"string\",\n      \"renewalUrl\": \"string\",\n      \"signatureKeys\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"type\": \"string\",\n        \"code\": \"string\",\n        \"description\": \"string\",\n        \"source\": \"string\",\n        \"password\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"data\": \"string\",\n        \"dataFormat\": \"string\",\n        \"meta\": \"string\"\n      },\n      \"productOrders\": [\n        {}\n      ]\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\","},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  }\n}';"},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"const headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/orders/{orderId}/products/{productId}',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/orders/{orderId}/products/{productId}\";\n\n      \n      string json = @\"{\n  \"\"productOrder\"\": {\n    \"\"productId\"\": 0,\n    \"\"orderId\"\": 0,\n    \"\"quantity\"\": 0,\n    \"\"unitPrice\"\": 0.1,\n    \"\"discount\"\": 0.1,\n    \"\"taxes\"\": 0.1,\n    \"\"description\"\": \"\"string\"\",\n    \"\"product\"\": {\n      \"\"id\"\": 0,\n      \"\"code\"\": \"\"string\"\",\n      \"\"name\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"url\"\": \"\"string\"\",\n      \"\"copyright\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"image\"\": \"\"string\"\",\n      \"\"price\"\": 0.1,\n      \"\"resellerPrice\"\": 0.1,\n      \"\"currency\"\": \"\"string\"\",\n      \"\"signatureKeysId\"\": 0,\n      \"\"meta\"\": \"\"string\"\",\n      \"\"isApplication\"\": true,\n      \"\"updateChannelDefault\"\": \"\"string\"\",\n      \"\"renewalUrl\"\": \"\"string\"\",\n      \"\"signatureKeys\"\": {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\",\n        \"\"type\"\": \"\"string\"\",\n        \"\"code\"\": \"\"string\"\","},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"        \"\"description\"\": \"\"string\"\",\n        \"\"source\"\": \"\"string\"\",\n        \"\"password\"\": \"\"string\"\",\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"data\"\": \"\"string\"\",\n        \"\"dataFormat\"\": \"\"string\"\",\n        \"\"meta\"\": \"\"string\"\"\n      },\n      \"\"productOrders\"\": [\n        {}\n      ]\n    },\n    \"\"order\"\": {\n      \"\"id\"\": 0,\n      \"\"orderNumber\"\": \"\"string\"\",\n      \"\"status\"\": \"\"string\"\",\n      \"\"processedBy\"\": \"\"string\"\",\n      \"\"purchaseOrder\"\": \"\"string\"\",\n      \"\"total\"\": 0.1,\n      \"\"currency\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"invoiceNumber\"\": \"\"string\"\",\n      \"\"paymentType\"\": \"\"string\"\",\n      \"\"paymentNumber\"\": \"\"string\"\",\n      \"\"paymentStatus\"\": \"\"string\"\",\n      \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"customerId\"\": 0,\n      \"\"customer\"\": {\n        \"\"id\"\": 0,\n        \"\"title\"\": \"\"string\"\",\n        \"\"firstName\"\": \"\"string\"\",\n        \"\"lastName\"\": \"\"string\"\",\n        \"\"company\"\": \"\"string\"\",\n        \"\"code\"\": \"\"string\"\",\n        \"\"vatCode\"\": \"\"string\"\",\n        \"\"invoiceCode\"\": \"\"string\"\",\n        \"\"rating\"\": 0,\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"address\"\": \"\"string\"\",\n        \"\"address1\"\": \"\"string\"\",\n        \"\"address2\"\": \"\"string\"\",\n        \"\"postalCode\"\": \"\"string\"\",\n        \"\"region\"\": \"\"string\"\","},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"        \"\"city\"\": \"\"string\"\",\n        \"\"country\"\": \"\"string\"\",\n        \"\"countryCode\"\": \"\"string\"\",\n        \"\"mapCoordinates\"\": \"\"string\"\",\n        \"\"mapZoomLevel\"\": 0.1,\n        \"\"email\"\": \"\"string\"\",\n        \"\"phone\"\": \"\"string\"\",\n        \"\"mobile\"\": \"\"string\"\",\n        \"\"fax\"\": \"\"string\"\",\n        \"\"website\"\": \"\"string\"\",\n        \"\"notes\"\": \"\"string\"\",\n        \"\"isReseller\"\": true,\n        \"\"image\"\": \"\"string\"\",\n        \"\"meta\"\": \"\"string\"\",\n        \"\"contacts\"\": [\n          {\n            \"\"id\"\": 0,\n            \"\"title\"\": \"\"string\"\",\n            \"\"firstName\"\": \"\"string\"\",\n            \"\"lastName\"\": \"\"string\"\",\n            \"\"email\"\": \"\"string\"\",\n            \"\"phone\"\": \"\"string\"\",\n            \"\"mobile\"\": \"\"string\"\",\n            \"\"fax\"\": \"\"string\"\",\n            \"\"details\"\": \"\"string\"\",\n            \"\"notify\"\": true,\n            \"\"customerId\"\": 0,\n            \"\"meta\"\": \"\"string\"\"\n          }\n        ]\n      },\n      \"\"resellerId\"\": 0\n    }\n  }\n}\";\n      Management.UpdateProductOrderRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateProductOrderRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response"},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateProductOrderRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/orders/\\{orderId\\}/products/\\{productId\\}\nUpdates an existing product order.\nBody parameter"},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"{\n  \"productOrder\": {\n    \"productId\": 0,\n    \"orderId\": 0,\n    \"quantity\": 0,\n    \"unitPrice\": 0.1,\n    \"discount\": 0.1,\n    \"taxes\": 0.1,\n    \"description\": \"string\",\n    \"product\": {\n      \"id\": 0,\n      \"code\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"url\": \"string\",\n      \"copyright\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"image\": \"string\",\n      \"price\": 0.1,\n      \"resellerPrice\": 0.1,\n      \"currency\": \"string\",\n      \"signatureKeysId\": 0,\n      \"meta\": \"string\",\n      \"isApplication\": true,\n      \"updateChannelDefault\": \"string\",\n      \"renewalUrl\": \"string\",\n      \"signatureKeys\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"type\": \"string\",\n        \"code\": \"string\",\n        \"description\": \"string\",\n        \"source\": \"string\",\n        \"password\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"data\": \"string\",\n        \"dataFormat\": \"string\",\n        \"meta\": \"string\"\n      },\n      \"productOrders\": [\n        {}\n      ]\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\","},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  }\n}\nParameters"},{"page":206,"heading":"PUT /v1/orders/{orderId}/products/{productId}","anchor":"put-v1ordersorderidproductsproductid","text":"Name | In | Type | Required | Description\norderId | path | integer(int32) | true | The order ID.\nproductId | path | integer(int32) | true | The product ID.\nbody | body | Management.UpdateProductOrderRequest | false | The request containing the details of the product order to update.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateProductOrderResponse\nAuthentication: API key (x-api-key)."},{"page":206,"heading":"DELETE /v1/orders/{orderId}/products/{productId}","anchor":"delete-v1ordersorderidproductsproductid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/orders/{orderId}/products/{productId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/orders/{orderId}/products/{productId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":206,"heading":"DELETE /v1/orders/{orderId}/products/{productId}","anchor":"delete-v1ordersorderidproductsproductid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/orders/{orderId}/products/{productId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/orders/\\{orderId\\}/products/\\{productId\\}\nDeletes a specific product order.\nParameters"},{"page":206,"heading":"DELETE /v1/orders/{orderId}/products/{productId}","anchor":"delete-v1ordersorderidproductsproductid","text":"Name | In | Type | Required | Description\norderId | path | integer(int32) | true | The order ID.\nproductId | path | integer(int32) | true | The product ID.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteProductOrderResponse\nAuthentication: API key (x-api-key)."},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/orders/{orderId}/licenses \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/orders/{orderId}/licenses',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/orders/{orderId}/licenses\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/orders/\\{orderId\\}/licenses\nGets the licenses for a specific order.\nParameters"},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"Name | In | Type | Required | Description\norderId | path | integer(int32) | true | The order ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response"},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"licenses\":[{\"id\":0,\"licenseId\":\"string\",\"licenseType\":\"string\",\"format\":0,\"description\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"supportExpireDate\":\"2019-08-24T14:15:22Z\",\"revoked\":true,\"trace\":true,\"licenseKey\":\"string\",\"maxAllowedSites\":0,\"userKey\":\"string\",\"licensingMode\":0,\"licenseeName\":\"string\",\"licenseeCompany\":\"string\",\"licenseeEmail\":\"string\",\"hash\":\"string\",\"meta\":\"string\",\"templateId\":0,\"signatureKeysId\":0,\"customerId\":0,\"orderId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapC"},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"oordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0},\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"template\":{\"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\":\"string\",\"template\":\"string\",\"productId\":"},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"licensee\":{\"name\":\"string\",\"company\":\"string\",\"contactInfo\":\"string\",\"url\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]}],\"totalLicensesCount\":0}"},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenses\": [\n    {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\","},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\""},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\","},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":206,"heading":"GET /v1/orders/{orderId}/licenses","anchor":"get-v1ordersorderidlicenses","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicensesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetOrderLicensesResponse\nAuthentication: API key (x-api-key)."},{"page":207,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/licenses \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/licenses',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/licenses\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/licenses\nRetrieves licenses based on the provided request parameters.\nParameters"},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response"},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"licenses\":[{\"id\":0,\"licenseId\":\"string\",\"licenseType\":\"string\",\"format\":0,\"description\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"supportExpireDate\":\"2019-08-24T14:15:22Z\",\"revoked\":true,\"trace\":true,\"licenseKey\":\"string\",\"maxAllowedSites\":0,\"userKey\":\"string\",\"licensingMode\":0,\"licenseeName\":\"string\",\"licenseeCompany\":\"string\",\"licenseeEmail\":\"string\",\"hash\":\"string\",\"meta\":\"string\",\"templateId\":0,\"signatureKeysId\":0,\"customerId\":0,\"orderId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapC"},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"oordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0},\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"template\":{\"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\":\"string\",\"template\":\"string\",\"productId\":"},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"licensee\":{\"name\":\"string\",\"company\":\"string\",\"contactInfo\":\"string\",\"url\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]}],\"totalLicensesCount\":0}"},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenses\": [\n    {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\","},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\""},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\","},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":207,"heading":"GET /v1/licenses","anchor":"get-v1licenses","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicensesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetLicensesResponse\nAuthentication: API key (x-api-key)."},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/licenses \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"const inputBody = '{\n  \"license\": {\n    \"id\": 0,\n    \"licenseId\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"description\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n    \"revoked\": true,\n    \"trace\": true,\n    \"licenseKey\": \"string\",\n    \"maxAllowedSites\": 0,\n    \"userKey\": \"string\",\n    \"licensingMode\": 0,\n    \"licenseeName\": \"string\",\n    \"licenseeCompany\": \"string\",\n    \"licenseeEmail\": \"string\",\n    \"hash\": \"string\",\n    \"meta\": \"string\",\n    \"templateId\": 0,\n    \"signatureKeysId\": 0,\n    \"customerId\": 0,\n    \"orderId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    },\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"template\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,"},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"licensee\": {\n      \"name\": \"string\",\n      \"company\": \"string\",\n      \"contactInfo\": \"string\",\n      \"url\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/licenses',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/licenses\";\n      \n      string json = @\"{\n  \"\"license\"\": {\n    \"\"id\"\": 0,\n    \"\"licenseId\"\": \"\"string\"\",\n    \"\"licenseType\"\": \"\"string\"\",\n    \"\"format\"\": 0,\n    \"\"description\"\": \"\"string\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"issueDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"supportExpireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"revoked\"\": true,\n    \"\"trace\"\": true,\n    \"\"licenseKey\"\": \"\"string\"\",\n    \"\"maxAllowedSites\"\": 0,\n    \"\"userKey\"\": \"\"string\"\",\n    \"\"licensingMode\"\": 0,\n    \"\"licenseeName\"\": \"\"string\"\",\n    \"\"licenseeCompany\"\": \"\"string\"\",\n    \"\"licenseeEmail\"\": \"\"string\"\",\n    \"\"hash\"\": \"\"string\"\",\n    \"\"meta\"\": \"\"string\"\",\n    \"\"templateId\"\": 0,\n    \"\"signatureKeysId\"\": 0,\n    \"\"customerId\"\": 0,\n    \"\"orderId\"\": 0,\n    \"\"product\"\": {\n      \"\"id\"\": \"\"string\"\",\n      \"\"name\"\": \"\"string\"\",\n      \"\"version\"\": \"\"string\"\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"      \"\"copyright\"\": \"\"string\"\",\n      \"\"url\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\"\n    },\n    \"\"order\"\": {\n      \"\"id\"\": 0,\n      \"\"orderNumber\"\": \"\"string\"\",\n      \"\"status\"\": \"\"string\"\",\n      \"\"processedBy\"\": \"\"string\"\",\n      \"\"purchaseOrder\"\": \"\"string\"\",\n      \"\"total\"\": 0.1,\n      \"\"currency\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"invoiceNumber\"\": \"\"string\"\",\n      \"\"paymentType\"\": \"\"string\"\",\n      \"\"paymentNumber\"\": \"\"string\"\",\n      \"\"paymentStatus\"\": \"\"string\"\",\n      \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"customerId\"\": 0,\n      \"\"customer\"\": {\n        \"\"id\"\": 0,\n        \"\"title\"\": \"\"string\"\",\n        \"\"firstName\"\": \"\"string\"\",\n        \"\"lastName\"\": \"\"string\"\",\n        \"\"company\"\": \"\"string\"\",\n        \"\"code\"\": \"\"string\"\",\n        \"\"vatCode\"\": \"\"string\"\",\n        \"\"invoiceCode\"\": \"\"string\"\",\n        \"\"rating\"\": 0,\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"address\"\": \"\"string\"\",\n        \"\"address1\"\": \"\"string\"\",\n        \"\"address2\"\": \"\"string\"\",\n        \"\"postalCode\"\": \"\"string\"\",\n        \"\"region\"\": \"\"string\"\",\n        \"\"city\"\": \"\"string\"\",\n        \"\"country\"\": \"\"string\"\",\n        \"\"countryCode\"\": \"\"string\"\",\n        \"\"mapCoordinates\"\": \"\"string\"\",\n        \"\"mapZoomLevel\"\": 0.1,\n        \"\"email\"\": \"\"string\"\",\n        \"\"phone\"\": \"\"string\"\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"        \"\"mobile\"\": \"\"string\"\",\n        \"\"fax\"\": \"\"string\"\",\n        \"\"website\"\": \"\"string\"\",\n        \"\"notes\"\": \"\"string\"\",\n        \"\"isReseller\"\": true,\n        \"\"image\"\": \"\"string\"\",\n        \"\"meta\"\": \"\"string\"\",\n        \"\"contacts\"\": [\n          {\n            \"\"id\"\": 0,\n            \"\"title\"\": \"\"string\"\",\n            \"\"firstName\"\": \"\"string\"\",\n            \"\"lastName\"\": \"\"string\"\",\n            \"\"email\"\": \"\"string\"\",\n            \"\"phone\"\": \"\"string\"\",\n            \"\"mobile\"\": \"\"string\"\",\n            \"\"fax\"\": \"\"string\"\",\n            \"\"details\"\": \"\"string\"\",\n            \"\"notify\"\": true,\n            \"\"customerId\"\": 0,\n            \"\"meta\"\": \"\"string\"\"\n          }\n        ]\n      },\n      \"\"resellerId\"\": 0\n    },\n    \"\"customer\"\": {\n      \"\"id\"\": 0,\n      \"\"title\"\": \"\"string\"\",\n      \"\"firstName\"\": \"\"string\"\",\n      \"\"lastName\"\": \"\"string\"\",\n      \"\"company\"\": \"\"string\"\",\n      \"\"code\"\": \"\"string\"\",\n      \"\"vatCode\"\": \"\"string\"\",\n      \"\"invoiceCode\"\": \"\"string\"\",\n      \"\"rating\"\": 0,\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"address\"\": \"\"string\"\",\n      \"\"address1\"\": \"\"string\"\",\n      \"\"address2\"\": \"\"string\"\",\n      \"\"postalCode\"\": \"\"string\"\",\n      \"\"region\"\": \"\"string\"\",\n      \"\"city\"\": \"\"string\"\",\n      \"\"country\"\": \"\"string\"\",\n      \"\"countryCode\"\": \"\"string\"\",\n      \"\"mapCoordinates\"\": \"\"string\"\",\n      \"\"mapZoomLevel\"\": 0.1,\n      \"\"email\"\": \"\"string\"\",\n      \"\"phone\"\": \"\"string\"\",\n      \"\"mobile\"\": \"\"string\"\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"      \"\"fax\"\": \"\"string\"\",\n      \"\"website\"\": \"\"string\"\",\n      \"\"notes\"\": \"\"string\"\",\n      \"\"isReseller\"\": true,\n      \"\"image\"\": \"\"string\"\",\n      \"\"meta\"\": \"\"string\"\",\n      \"\"contacts\"\": [\n        {\n          \"\"id\"\": 0,\n          \"\"title\"\": \"\"string\"\",\n          \"\"firstName\"\": \"\"string\"\",\n          \"\"lastName\"\": \"\"string\"\",\n          \"\"email\"\": \"\"string\"\",\n          \"\"phone\"\": \"\"string\"\",\n          \"\"mobile\"\": \"\"string\"\",\n          \"\"fax\"\": \"\"string\"\",\n          \"\"details\"\": \"\"string\"\",\n          \"\"notify\"\": true,\n          \"\"customerId\"\": 0,\n          \"\"meta\"\": \"\"string\"\"\n        }\n      ]\n    },\n    \"\"template\"\": {\n      \"\"id\"\": 0,\n      \"\"name\"\": \"\"string\"\",\n      \"\"code\"\": \"\"string\"\",\n      \"\"licenseType\"\": \"\"string\"\",\n      \"\"format\"\": 0,\n      \"\"licensingMode\"\": 0,\n      \"\"licenseFileName\"\": \"\"string\"\",\n      \"\"issueDate\"\": true,\n      \"\"expireDays\"\": 0,\n      \"\"supportDays\"\": 0,\n      \"\"generateKeyInfo\"\": true,\n      \"\"userKey\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"template\"\": \"\"string\"\",\n      \"\"productId\"\": 0,\n      \"\"signatureKeysId\"\": 0,\n      \"\"releaseId\"\": 0,\n      \"\"product\"\": {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"version\"\": \"\"string\"\",\n        \"\"copyright\"\": \"\"string\"\",\n        \"\"url\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\"\n      },\n      \"\"components\"\": [\n        \"\"string\"\"\n      ],\n      \"\"assemblies\"\": [\n        {\n          \"\"id\"\": 0,\n          \"\"name\"\": \"\"string\"\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"          \"\"version\"\": \"\"string\"\",\n          \"\"culture\"\": \"\"string\"\",\n          \"\"publicKeyToken\"\": \"\"string\"\",\n          \"\"mappingFileId\"\": 0,\n          \"\"debugSymbolsKey\"\": \"\"string\"\"\n        }\n      ],\n      \"\"fields\"\": [\n        {\n          \"\"name\"\": \"\"string\"\",\n          \"\"value\"\": \"\"string\"\"\n        }\n      ],\n      \"\"features\"\": [\n        {\n          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"description\"\": \"\"string\"\",\n          \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"key\"\": \"\"string\"\",\n          \"\"data\"\": \"\"string\"\"\n        }\n      ],\n      \"\"restrictions\"\": [\n        {\n          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"properties\"\": {\n            \"\"property1\"\": \"\"string\"\",\n            \"\"property2\"\": \"\"string\"\"\n          },\n          \"\"customXmlContent\"\": \"\"string\"\"\n        }\n      ]\n    },\n    \"\"licensee\"\": {\n      \"\"name\"\": \"\"string\"\",\n      \"\"company\"\": \"\"string\"\",\n      \"\"contactInfo\"\": \"\"string\"\",\n      \"\"url\"\": \"\"string\"\"\n    },\n    \"\"components\"\": [\n      \"\"string\"\"\n    ],\n    \"\"assemblies\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\",\n        \"\"version\"\": \"\"string\"\",\n        \"\"culture\"\": \"\"string\"\",\n        \"\"publicKeyToken\"\": \"\"string\"\",\n        \"\"mappingFileId\"\": 0,\n        \"\"debugSymbolsKey\"\": \"\"string\"\"\n      }\n    ],\n    \"\"fields\"\": [\n      {\n        \"\"name\"\": \"\"string\"\",\n        \"\"value\"\": \"\"string\"\"\n      }\n    ],"},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"    \"\"features\"\": [\n      {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"key\"\": \"\"string\"\",\n        \"\"data\"\": \"\"string\"\"\n      }\n    ],\n    \"\"restrictions\"\": [\n      {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"properties\"\": {\n          \"\"property1\"\": \"\"string\"\",\n          \"\"property2\"\": \"\"string\"\"\n        },\n        \"\"customXmlContent\"\": \"\"string\"\"\n      }\n    ]\n  }\n}\";\n      Management.InsertLicenseRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertLicenseRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.InsertLicenseRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response"},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/licenses\nInserts a new license based on the provided request parameters.\nBody parameter"},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"{\n  \"license\": {\n    \"id\": 0,\n    \"licenseId\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"description\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n    \"revoked\": true,\n    \"trace\": true,\n    \"licenseKey\": \"string\",\n    \"maxAllowedSites\": 0,\n    \"userKey\": \"string\",\n    \"licensingMode\": 0,\n    \"licenseeName\": \"string\",\n    \"licenseeCompany\": \"string\",\n    \"licenseeEmail\": \"string\",\n    \"hash\": \"string\",\n    \"meta\": \"string\",\n    \"templateId\": 0,\n    \"signatureKeysId\": 0,\n    \"customerId\": 0,\n    \"orderId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    },\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"template\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {"},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"licensee\": {\n      \"name\": \"string\",\n      \"company\": \"string\",\n      \"contactInfo\": \"string\",\n      \"url\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\","},{"page":207,"heading":"POST /v1/licenses","anchor":"post-v1licenses","text":"        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.InsertLicenseRequest | false | The request containing the parameters for inserting a license.\nExample responses\n200 Response\n{\"licenseId\":0,\"success\":true,\"code\":0,\"message\":\"string\",\"licenseKeyId\":\"string\",\"userKey\":\"string\",\"licenseKey\":\"string\"}\n{\n  \"licenseId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseKeyId\": \"string\",\n  \"userKey\": \"string\",\n  \"licenseKey\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertLicenseResponse\nAuthentication: API key (x-api-key)."},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/licenses \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"const inputBody = '{\n  \"license\": {\n    \"id\": 0,\n    \"licenseId\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"description\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n    \"revoked\": true,\n    \"trace\": true,\n    \"licenseKey\": \"string\",\n    \"maxAllowedSites\": 0,\n    \"userKey\": \"string\",\n    \"licensingMode\": 0,\n    \"licenseeName\": \"string\",\n    \"licenseeCompany\": \"string\",\n    \"licenseeEmail\": \"string\",\n    \"hash\": \"string\",\n    \"meta\": \"string\",\n    \"templateId\": 0,\n    \"signatureKeysId\": 0,\n    \"customerId\": 0,\n    \"orderId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\","},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    },\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\","},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"template\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,"},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"licensee\": {\n      \"name\": \"string\",\n      \"company\": \"string\",\n      \"contactInfo\": \"string\",\n      \"url\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\","},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/licenses',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/licenses\";\n\n      \n      string json = @\"{\n  \"\"license\"\": {\n    \"\"id\"\": 0,\n    \"\"licenseId\"\": \"\"string\"\",\n    \"\"licenseType\"\": \"\"string\"\",\n    \"\"format\"\": 0,\n    \"\"description\"\": \"\"string\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"issueDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"supportExpireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"revoked\"\": true,\n    \"\"trace\"\": true,\n    \"\"licenseKey\"\": \"\"string\"\",\n    \"\"maxAllowedSites\"\": 0,\n    \"\"userKey\"\": \"\"string\"\",\n    \"\"licensingMode\"\": 0,\n    \"\"licenseeName\"\": \"\"string\"\",\n    \"\"licenseeCompany\"\": \"\"string\"\",\n    \"\"licenseeEmail\"\": \"\"string\"\",\n    \"\"hash\"\": \"\"string\"\",\n    \"\"meta\"\": \"\"string\"\",\n    \"\"templateId\"\": 0,\n    \"\"signatureKeysId\"\": 0,\n    \"\"customerId\"\": 0,\n    \"\"orderId\"\": 0,\n    \"\"product\"\": {\n      \"\"id\"\": \"\"string\"\",\n      \"\"name\"\": \"\"string\"\","},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"      \"\"version\"\": \"\"string\"\",\n      \"\"copyright\"\": \"\"string\"\",\n      \"\"url\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\"\n    },\n    \"\"order\"\": {\n      \"\"id\"\": 0,\n      \"\"orderNumber\"\": \"\"string\"\",\n      \"\"status\"\": \"\"string\"\",\n      \"\"processedBy\"\": \"\"string\"\",\n      \"\"purchaseOrder\"\": \"\"string\"\",\n      \"\"total\"\": 0.1,\n      \"\"currency\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"invoiceNumber\"\": \"\"string\"\",\n      \"\"paymentType\"\": \"\"string\"\",\n      \"\"paymentNumber\"\": \"\"string\"\",\n      \"\"paymentStatus\"\": \"\"string\"\",\n      \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"customerId\"\": 0,\n      \"\"customer\"\": {\n        \"\"id\"\": 0,\n        \"\"title\"\": \"\"string\"\",\n        \"\"firstName\"\": \"\"string\"\",\n        \"\"lastName\"\": \"\"string\"\",\n        \"\"company\"\": \"\"string\"\",\n        \"\"code\"\": \"\"string\"\",\n        \"\"vatCode\"\": \"\"string\"\",\n        \"\"invoiceCode\"\": \"\"string\"\",\n        \"\"rating\"\": 0,\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"address\"\": \"\"string\"\",\n        \"\"address1\"\": \"\"string\"\",\n        \"\"address2\"\": \"\"string\"\",\n        \"\"postalCode\"\": \"\"string\"\",\n        \"\"region\"\": \"\"string\"\",\n        \"\"city\"\": \"\"string\"\",\n        \"\"country\"\": \"\"string\"\",\n        \"\"countryCode\"\": \"\"string\"\",\n        \"\"mapCoordinates\"\": \"\"string\"\",\n        \"\"mapZoomLevel\"\": 0.1,\n        \"\"email\"\": \"\"string\"\","},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"        \"\"phone\"\": \"\"string\"\",\n        \"\"mobile\"\": \"\"string\"\",\n        \"\"fax\"\": \"\"string\"\",\n        \"\"website\"\": \"\"string\"\",\n        \"\"notes\"\": \"\"string\"\",\n        \"\"isReseller\"\": true,\n        \"\"image\"\": \"\"string\"\",\n        \"\"meta\"\": \"\"string\"\",\n        \"\"contacts\"\": [\n          {\n            \"\"id\"\": 0,\n            \"\"title\"\": \"\"string\"\",\n            \"\"firstName\"\": \"\"string\"\",\n            \"\"lastName\"\": \"\"string\"\",\n            \"\"email\"\": \"\"string\"\",\n            \"\"phone\"\": \"\"string\"\",\n            \"\"mobile\"\": \"\"string\"\",\n            \"\"fax\"\": \"\"string\"\",\n            \"\"details\"\": \"\"string\"\",\n            \"\"notify\"\": true,\n            \"\"customerId\"\": 0,\n            \"\"meta\"\": \"\"string\"\"\n          }\n        ]\n      },\n      \"\"resellerId\"\": 0\n    },\n    \"\"customer\"\": {\n      \"\"id\"\": 0,\n      \"\"title\"\": \"\"string\"\",\n      \"\"firstName\"\": \"\"string\"\",\n      \"\"lastName\"\": \"\"string\"\",\n      \"\"company\"\": \"\"string\"\",\n      \"\"code\"\": \"\"string\"\",\n      \"\"vatCode\"\": \"\"string\"\",\n      \"\"invoiceCode\"\": \"\"string\"\",\n      \"\"rating\"\": 0,\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"address\"\": \"\"string\"\",\n      \"\"address1\"\": \"\"string\"\",\n      \"\"address2\"\": \"\"string\"\",\n      \"\"postalCode\"\": \"\"string\"\",\n      \"\"region\"\": \"\"string\"\",\n      \"\"city\"\": \"\"string\"\",\n      \"\"country\"\": \"\"string\"\",\n      \"\"countryCode\"\": \"\"string\"\",\n      \"\"mapCoordinates\"\": \"\"string\"\",\n      \"\"mapZoomLevel\"\": 0.1,\n      \"\"email\"\": \"\"string\"\",\n      \"\"phone\"\": \"\"string\"\","},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"      \"\"mobile\"\": \"\"string\"\",\n      \"\"fax\"\": \"\"string\"\",\n      \"\"website\"\": \"\"string\"\",\n      \"\"notes\"\": \"\"string\"\",\n      \"\"isReseller\"\": true,\n      \"\"image\"\": \"\"string\"\",\n      \"\"meta\"\": \"\"string\"\",\n      \"\"contacts\"\": [\n        {\n          \"\"id\"\": 0,\n          \"\"title\"\": \"\"string\"\",\n          \"\"firstName\"\": \"\"string\"\",\n          \"\"lastName\"\": \"\"string\"\",\n          \"\"email\"\": \"\"string\"\",\n          \"\"phone\"\": \"\"string\"\",\n          \"\"mobile\"\": \"\"string\"\",\n          \"\"fax\"\": \"\"string\"\",\n          \"\"details\"\": \"\"string\"\",\n          \"\"notify\"\": true,\n          \"\"customerId\"\": 0,\n          \"\"meta\"\": \"\"string\"\"\n        }\n      ]\n    },\n    \"\"template\"\": {\n      \"\"id\"\": 0,\n      \"\"name\"\": \"\"string\"\",\n      \"\"code\"\": \"\"string\"\",\n      \"\"licenseType\"\": \"\"string\"\",\n      \"\"format\"\": 0,\n      \"\"licensingMode\"\": 0,\n      \"\"licenseFileName\"\": \"\"string\"\",\n      \"\"issueDate\"\": true,\n      \"\"expireDays\"\": 0,\n      \"\"supportDays\"\": 0,\n      \"\"generateKeyInfo\"\": true,\n      \"\"userKey\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\",\n      \"\"template\"\": \"\"string\"\",\n      \"\"productId\"\": 0,\n      \"\"signatureKeysId\"\": 0,\n      \"\"releaseId\"\": 0,\n      \"\"product\"\": {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"version\"\": \"\"string\"\",\n        \"\"copyright\"\": \"\"string\"\",\n        \"\"url\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\"\n      },\n      \"\"components\"\": [\n        \"\"string\"\"\n      ],\n      \"\"assemblies\"\": [\n        {\n          \"\"id\"\": 0,"},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"          \"\"name\"\": \"\"string\"\",\n          \"\"version\"\": \"\"string\"\",\n          \"\"culture\"\": \"\"string\"\",\n          \"\"publicKeyToken\"\": \"\"string\"\",\n          \"\"mappingFileId\"\": 0,\n          \"\"debugSymbolsKey\"\": \"\"string\"\"\n        }\n      ],\n      \"\"fields\"\": [\n        {\n          \"\"name\"\": \"\"string\"\",\n          \"\"value\"\": \"\"string\"\"\n        }\n      ],\n      \"\"features\"\": [\n        {\n          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"description\"\": \"\"string\"\",\n          \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"key\"\": \"\"string\"\",\n          \"\"data\"\": \"\"string\"\"\n        }\n      ],\n      \"\"restrictions\"\": [\n        {\n          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"properties\"\": {\n            \"\"property1\"\": \"\"string\"\",\n            \"\"property2\"\": \"\"string\"\"\n          },\n          \"\"customXmlContent\"\": \"\"string\"\"\n        }\n      ]\n    },\n    \"\"licensee\"\": {\n      \"\"name\"\": \"\"string\"\",\n      \"\"company\"\": \"\"string\"\",\n      \"\"contactInfo\"\": \"\"string\"\",\n      \"\"url\"\": \"\"string\"\"\n    },\n    \"\"components\"\": [\n      \"\"string\"\"\n    ],\n    \"\"assemblies\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\",\n        \"\"version\"\": \"\"string\"\",\n        \"\"culture\"\": \"\"string\"\",\n        \"\"publicKeyToken\"\": \"\"string\"\",\n        \"\"mappingFileId\"\": 0,\n        \"\"debugSymbolsKey\"\": \"\"string\"\"\n      }\n    ],\n    \"\"fields\"\": [\n      {\n        \"\"name\"\": \"\"string\"\",\n        \"\"value\"\": \"\"string\"\""},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"      }\n    ],\n    \"\"features\"\": [\n      {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"key\"\": \"\"string\"\",\n        \"\"data\"\": \"\"string\"\"\n      }\n    ],\n    \"\"restrictions\"\": [\n      {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"properties\"\": {\n          \"\"property1\"\": \"\"string\"\",\n          \"\"property2\"\": \"\"string\"\"\n        },\n        \"\"customXmlContent\"\": \"\"string\"\"\n      }\n    ]\n  }\n}\";\n      Management.UpdateLicenseRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateLicenseRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateLicenseRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/licenses\nUpdates an existing license based on the provided request parameters.\nFields omitted from the body keep their stored values. For example, an update that does not include revoked leaves the revocation state unchanged. See Updating Resources.\nBody parameter"},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"{\n  \"license\": {\n    \"id\": 0,\n    \"licenseId\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"description\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n    \"revoked\": true,\n    \"trace\": true,\n    \"licenseKey\": \"string\",\n    \"maxAllowedSites\": 0,\n    \"userKey\": \"string\",\n    \"licensingMode\": 0,\n    \"licenseeName\": \"string\",\n    \"licenseeCompany\": \"string\",\n    \"licenseeEmail\": \"string\",\n    \"hash\": \"string\",\n    \"meta\": \"string\",\n    \"templateId\": 0,\n    \"signatureKeysId\": 0,\n    \"customerId\": 0,\n    \"orderId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\","},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    },\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\","},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"template\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {"},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"licensee\": {\n      \"name\": \"string\",\n      \"company\": \"string\",\n      \"contactInfo\": \"string\",\n      \"url\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\","},{"page":207,"heading":"PUT /v1/licenses","anchor":"put-v1licenses","text":"        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.UpdateLicenseRequest | false | The request containing the parameters for updating a license.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"licenseKeyId\":\"string\",\"userKey\":\"string\",\"licenseKey\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseKeyId\": \"string\",\n  \"userKey\": \"string\",\n  \"licenseKey\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateLicenseResponse\nAuthentication: API key (x-api-key)."},{"page":207,"heading":"DELETE /v1/licenses/{licenseId}","anchor":"delete-v1licenseslicenseid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/licenses/{licenseId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/licenses/{licenseId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":207,"heading":"DELETE /v1/licenses/{licenseId}","anchor":"delete-v1licenseslicenseid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/licenses/{licenseId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/licenses/\\{licenseId\\}\nDeletes an existing license based on the provided request parameters.\nParameters\nName | In | Type | Required | Description\nlicenseId | path | integer(int32) | true | The license ID.\nExample responses"},{"page":207,"heading":"DELETE /v1/licenses/{licenseId}","anchor":"delete-v1licenseslicenseid","text":"200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteLicenseResponse\nAuthentication: API key (x-api-key)."},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/license-tokens \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/license-tokens',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/license-tokens\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/license-tokens\nRetrieves license tokens based on the provided request parameters.\nParameters"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\ncountOnly | query | boolean | false | none\nExample responses\n200 Response"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"licenseTokens\":[{\"id\":0,\"token\":\"string\",\"address\":\"string\",\"clientId\":\"string\",\"clientName\":\"string\",\"machineId\":\"string\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"lastHeartbeat\":\"2019-08-24T14:15:22Z\",\"hash\":\"string\",\"licenseId\":0,\"license\":{\"id\":0,\"licenseId\":\"string\",\"licenseType\":\"string\",\"format\":0,\"description\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"supportExpireDate\":\"2019-08-24T14:15:22Z\",\"revoked\":true,\"trace\":true,\"licenseKey\":\"string\",\"maxAllowedSites\":0,\"userKey\":\"string\",\"licensingMode\":0,\"licenseeName\":\"string\",\"licenseeCompany\":\"string\",\"licenseeEmail\":\"string\",\"hash\":\"string\",\"meta\":\"string\",\"templateId\":0,\"signatureKeysId\":0,\"customerId\":0,\"orderId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"inv"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"oiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0},\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"template\":{\""},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\":\"string\",\"template\":\"string\",\"productId\":0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"licensee\":{\"name\":\"string\",\"company\":\"string\",\"contactInfo\":\"string\",\"url\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\""},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"nodeLockedLicenseId\":0,\"nodeLockedLicense\":{\"id\":0,\"licenseId\":\"string\",\"licenseType\":\"string\",\"format\":0,\"description\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"supportExpireDate\":\"2019-08-24T14:15:22Z\",\"revoked\":true,\"trace\":true,\"licenseKey\":\"string\",\"maxAllowedSites\":0,\"userKey\":\"string\",\"licensingMode\":0,\"licenseeName\":\"string\",\"licenseeCompany\":\"string\",\"licenseeEmail\":\"string\",\"hash\":\"string\",\"meta\":\"string\",\"templateId\":0,\"signatureKeysId\":0,\"customerId\":0,\"orderId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"coun"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"try\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0},\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"template\":{\"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\""},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":":\"string\",\"template\":\"string\",\"productId\":0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"licensee\":{\"name\":\"string\",\"company\":\"string\",\"contactInfo\":\"string\",\"url\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]}}],\"licenseTokensCount\":0,\"totalLicenseTokensCount\":0}"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseTokens\": [\n    {\n      \"id\": 0,\n      \"token\": \"string\",\n      \"address\": \"string\",\n      \"clientId\": \"string\",\n      \"clientName\": \"string\",\n      \"machineId\": \"string\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"lastHeartbeat\": \"2019-08-24T14:15:22Z\",\n      \"hash\": \"string\",\n      \"licenseId\": 0,\n      \"license\": {\n        \"id\": 0,\n        \"licenseId\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"description\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"issueDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n        \"revoked\": true,\n        \"trace\": true,\n        \"licenseKey\": \"string\",\n        \"maxAllowedSites\": 0,\n        \"userKey\": \"string\",\n        \"licensingMode\": 0,\n        \"licenseeName\": \"string\",\n        \"licenseeCompany\": \"string\",\n        \"licenseeEmail\": \"string\",\n        \"hash\": \"string\",\n        \"meta\": \"string\",\n        \"templateId\": 0,\n        \"signatureKeysId\": 0,\n        \"customerId\": 0,\n        \"orderId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"order\": {\n          \"id\": 0,"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\",\n          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\","},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\",\n                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        },\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\","},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"template\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"code\": \"string\",\n          \"licenseType\": \"string\",\n          \"format\": 0,\n          \"licensingMode\": 0,\n          \"licenseFileName\": \"string\",\n          \"issueDate\": true,\n          \"expireDays\": 0,\n          \"supportDays\": 0,\n          \"generateKeyInfo\": true,\n          \"userKey\": \"string\",\n          \"description\": \"string\",\n          \"template\": \"string\",\n          \"productId\": 0,\n          \"signatureKeysId\": 0,\n          \"releaseId\": 0,\n          \"product\": {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"copyright\": \"string\",\n            \"url\": \"string\",\n            \"description\": \"string\"\n          },\n          \"components\": [\n            \"string\"\n          ],\n          \"assemblies\": [\n            {\n              \"id\": 0,\n              \"name\": \"string\",\n              \"version\": \"string\","},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"              \"culture\": \"string\",\n              \"publicKeyToken\": \"string\",\n              \"mappingFileId\": 0,\n              \"debugSymbolsKey\": \"string\"\n            }\n          ],\n          \"fields\": [\n            {\n              \"name\": \"string\",\n              \"value\": \"string\"\n            }\n          ],\n          \"features\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"description\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"key\": \"string\",\n              \"data\": \"string\"\n            }\n          ],\n          \"restrictions\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"properties\": {\n                \"property1\": \"string\",\n                \"property2\": \"string\"\n              },\n              \"customXmlContent\": \"string\"\n            }\n          ]\n        },\n        \"licensee\": {\n          \"name\": \"string\",\n          \"company\": \"string\",\n          \"contactInfo\": \"string\",\n          \"url\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"nodeLockedLicenseId\": 0,\n      \"nodeLockedLicense\": {\n        \"id\": 0,\n        \"licenseId\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"description\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"issueDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n        \"revoked\": true,\n        \"trace\": true,\n        \"licenseKey\": \"string\",\n        \"maxAllowedSites\": 0,\n        \"userKey\": \"string\",\n        \"licensingMode\": 0,\n        \"licenseeName\": \"string\",\n        \"licenseeCompany\": \"string\",\n        \"licenseeEmail\": \"string\",\n        \"hash\": \"string\",\n        \"meta\": \"string\",\n        \"templateId\": 0,\n        \"signatureKeysId\": 0,"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"        \"customerId\": 0,\n        \"orderId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\",\n          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\","},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\",\n                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        },\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\","},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"template\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"code\": \"string\",\n          \"licenseType\": \"string\",\n          \"format\": 0,\n          \"licensingMode\": 0,\n          \"licenseFileName\": \"string\",\n          \"issueDate\": true,\n          \"expireDays\": 0,\n          \"supportDays\": 0,\n          \"generateKeyInfo\": true,\n          \"userKey\": \"string\",\n          \"description\": \"string\",\n          \"template\": \"string\",\n          \"productId\": 0,\n          \"signatureKeysId\": 0,\n          \"releaseId\": 0,\n          \"product\": {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"version\": \"string\","},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"            \"copyright\": \"string\",\n            \"url\": \"string\",\n            \"description\": \"string\"\n          },\n          \"components\": [\n            \"string\"\n          ],\n          \"assemblies\": [\n            {\n              \"id\": 0,\n              \"name\": \"string\",\n              \"version\": \"string\",\n              \"culture\": \"string\",\n              \"publicKeyToken\": \"string\",\n              \"mappingFileId\": 0,\n              \"debugSymbolsKey\": \"string\"\n            }\n          ],\n          \"fields\": [\n            {\n              \"name\": \"string\",\n              \"value\": \"string\"\n            }\n          ],\n          \"features\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"description\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"key\": \"string\",\n              \"data\": \"string\"\n            }\n          ],\n          \"restrictions\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"properties\": {\n                \"property1\": \"string\",\n                \"property2\": \"string\"\n              },\n              \"customXmlContent\": \"string\"\n            }\n          ]\n        },\n        \"licensee\": {\n          \"name\": \"string\",\n          \"company\": \"string\",\n          \"contactInfo\": \"string\",\n          \"url\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {"},{"page":208,"heading":"GET /v1/license-tokens","anchor":"get-v1license-tokens","text":"            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      }\n    }\n  ],\n  \"licenseTokensCount\": 0,\n  \"totalLicenseTokensCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetLicenseTokensResponse\nAuthentication: API key (x-api-key)."},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/licenses/{licenseId}/tokens \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/licenses/{licenseId}/tokens',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/licenses/{licenseId}/tokens\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/licenses/\\{licenseId\\}/tokens\nRetrieves license tokens based on the provided request parameters.\nParameters"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"Name | In | Type | Required | Description\nlicenseId | path | integer(int32) | true | The license ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\ncountOnly | query | boolean | false | none\nExample responses\n200 Response"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"licenseTokens\":[{\"id\":0,\"token\":\"string\",\"address\":\"string\",\"clientId\":\"string\",\"clientName\":\"string\",\"machineId\":\"string\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"lastHeartbeat\":\"2019-08-24T14:15:22Z\",\"hash\":\"string\",\"licenseId\":0,\"license\":{\"id\":0,\"licenseId\":\"string\",\"licenseType\":\"string\",\"format\":0,\"description\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"supportExpireDate\":\"2019-08-24T14:15:22Z\",\"revoked\":true,\"trace\":true,\"licenseKey\":\"string\",\"maxAllowedSites\":0,\"userKey\":\"string\",\"licensingMode\":0,\"licenseeName\":\"string\",\"licenseeCompany\":\"string\",\"licenseeEmail\":\"string\",\"hash\":\"string\",\"meta\":\"string\",\"templateId\":0,\"signatureKeysId\":0,\"customerId\":0,\"orderId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"inv"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"oiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0},\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"template\":{\""},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\":\"string\",\"template\":\"string\",\"productId\":0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"licensee\":{\"name\":\"string\",\"company\":\"string\",\"contactInfo\":\"string\",\"url\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\""},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"nodeLockedLicenseId\":0,\"nodeLockedLicense\":{\"id\":0,\"licenseId\":\"string\",\"licenseType\":\"string\",\"format\":0,\"description\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"supportExpireDate\":\"2019-08-24T14:15:22Z\",\"revoked\":true,\"trace\":true,\"licenseKey\":\"string\",\"maxAllowedSites\":0,\"userKey\":\"string\",\"licensingMode\":0,\"licenseeName\":\"string\",\"licenseeCompany\":\"string\",\"licenseeEmail\":\"string\",\"hash\":\"string\",\"meta\":\"string\",\"templateId\":0,\"signatureKeysId\":0,\"customerId\":0,\"orderId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"coun"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"try\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0},\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"template\":{\"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\""},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":":\"string\",\"template\":\"string\",\"productId\":0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"licensee\":{\"name\":\"string\",\"company\":\"string\",\"contactInfo\":\"string\",\"url\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]}}],\"licenseTokensCount\":0,\"totalLicenseTokensCount\":0}"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseTokens\": [\n    {\n      \"id\": 0,\n      \"token\": \"string\",\n      \"address\": \"string\",\n      \"clientId\": \"string\",\n      \"clientName\": \"string\",\n      \"machineId\": \"string\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"lastHeartbeat\": \"2019-08-24T14:15:22Z\",\n      \"hash\": \"string\",\n      \"licenseId\": 0,\n      \"license\": {\n        \"id\": 0,\n        \"licenseId\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"description\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"issueDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n        \"revoked\": true,\n        \"trace\": true,\n        \"licenseKey\": \"string\",\n        \"maxAllowedSites\": 0,\n        \"userKey\": \"string\",\n        \"licensingMode\": 0,\n        \"licenseeName\": \"string\",\n        \"licenseeCompany\": \"string\",\n        \"licenseeEmail\": \"string\",\n        \"hash\": \"string\",\n        \"meta\": \"string\",\n        \"templateId\": 0,\n        \"signatureKeysId\": 0,\n        \"customerId\": 0,\n        \"orderId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"order\": {\n          \"id\": 0,"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\",\n          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\","},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\",\n                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        },\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\","},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"template\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"code\": \"string\",\n          \"licenseType\": \"string\",\n          \"format\": 0,\n          \"licensingMode\": 0,\n          \"licenseFileName\": \"string\",\n          \"issueDate\": true,\n          \"expireDays\": 0,\n          \"supportDays\": 0,\n          \"generateKeyInfo\": true,\n          \"userKey\": \"string\",\n          \"description\": \"string\",\n          \"template\": \"string\",\n          \"productId\": 0,\n          \"signatureKeysId\": 0,\n          \"releaseId\": 0,\n          \"product\": {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"copyright\": \"string\",\n            \"url\": \"string\",\n            \"description\": \"string\"\n          },\n          \"components\": [\n            \"string\"\n          ],\n          \"assemblies\": [\n            {\n              \"id\": 0,\n              \"name\": \"string\",\n              \"version\": \"string\","},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"              \"culture\": \"string\",\n              \"publicKeyToken\": \"string\",\n              \"mappingFileId\": 0,\n              \"debugSymbolsKey\": \"string\"\n            }\n          ],\n          \"fields\": [\n            {\n              \"name\": \"string\",\n              \"value\": \"string\"\n            }\n          ],\n          \"features\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"description\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"key\": \"string\",\n              \"data\": \"string\"\n            }\n          ],\n          \"restrictions\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"properties\": {\n                \"property1\": \"string\",\n                \"property2\": \"string\"\n              },\n              \"customXmlContent\": \"string\"\n            }\n          ]\n        },\n        \"licensee\": {\n          \"name\": \"string\",\n          \"company\": \"string\",\n          \"contactInfo\": \"string\",\n          \"url\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"nodeLockedLicenseId\": 0,\n      \"nodeLockedLicense\": {\n        \"id\": 0,\n        \"licenseId\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"description\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"issueDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n        \"revoked\": true,\n        \"trace\": true,\n        \"licenseKey\": \"string\",\n        \"maxAllowedSites\": 0,\n        \"userKey\": \"string\",\n        \"licensingMode\": 0,\n        \"licenseeName\": \"string\",\n        \"licenseeCompany\": \"string\",\n        \"licenseeEmail\": \"string\",\n        \"hash\": \"string\",\n        \"meta\": \"string\",\n        \"templateId\": 0,\n        \"signatureKeysId\": 0,"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"        \"customerId\": 0,\n        \"orderId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\",\n          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\","},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\",\n                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        },\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\","},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"template\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"code\": \"string\",\n          \"licenseType\": \"string\",\n          \"format\": 0,\n          \"licensingMode\": 0,\n          \"licenseFileName\": \"string\",\n          \"issueDate\": true,\n          \"expireDays\": 0,\n          \"supportDays\": 0,\n          \"generateKeyInfo\": true,\n          \"userKey\": \"string\",\n          \"description\": \"string\",\n          \"template\": \"string\",\n          \"productId\": 0,\n          \"signatureKeysId\": 0,\n          \"releaseId\": 0,\n          \"product\": {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"version\": \"string\","},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"            \"copyright\": \"string\",\n            \"url\": \"string\",\n            \"description\": \"string\"\n          },\n          \"components\": [\n            \"string\"\n          ],\n          \"assemblies\": [\n            {\n              \"id\": 0,\n              \"name\": \"string\",\n              \"version\": \"string\",\n              \"culture\": \"string\",\n              \"publicKeyToken\": \"string\",\n              \"mappingFileId\": 0,\n              \"debugSymbolsKey\": \"string\"\n            }\n          ],\n          \"fields\": [\n            {\n              \"name\": \"string\",\n              \"value\": \"string\"\n            }\n          ],\n          \"features\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"description\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"key\": \"string\",\n              \"data\": \"string\"\n            }\n          ],\n          \"restrictions\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"properties\": {\n                \"property1\": \"string\",\n                \"property2\": \"string\"\n              },\n              \"customXmlContent\": \"string\"\n            }\n          ]\n        },\n        \"licensee\": {\n          \"name\": \"string\",\n          \"company\": \"string\",\n          \"contactInfo\": \"string\",\n          \"url\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {"},{"page":208,"heading":"GET /v1/licenses/{licenseId}/tokens","anchor":"get-v1licenseslicenseidtokens","text":"            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      }\n    }\n  ],\n  \"licenseTokensCount\": 0,\n  \"totalLicenseTokensCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetLicenseTokensResponse\nAuthentication: API key (x-api-key)."},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/licenses/{licenseId}/tokens \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"const inputBody = '{\n  \"licenseToken\": {\n    \"id\": 0,\n    \"token\": \"string\",\n    \"address\": \"string\",\n    \"clientId\": \"string\",\n    \"clientName\": \"string\",\n    \"machineId\": \"string\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"lastHeartbeat\": \"2019-08-24T14:15:22Z\",\n    \"hash\": \"string\",\n    \"licenseId\": 0,\n    \"license\": {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\""},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"nodeLockedLicenseId\": 0,\n    \"nodeLockedLicense\": {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"        \"code\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/licenses/{licenseId}/tokens',\n{\n  method: 'POST',\n  body: inputBody,"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/licenses/{licenseId}/tokens\";\n      \n      string json = @\"{\n  \"\"licenseToken\"\": {\n    \"\"id\"\": 0,\n    \"\"token\"\": \"\"string\"\",\n    \"\"address\"\": \"\"string\"\",\n    \"\"clientId\"\": \"\"string\"\",\n    \"\"clientName\"\": \"\"string\"\",\n    \"\"machineId\"\": \"\"string\"\",\n    \"\"issueDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"lastHeartbeat\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"hash\"\": \"\"string\"\",\n    \"\"licenseId\"\": 0,\n    \"\"license\"\": {\n      \"\"id\"\": 0,\n      \"\"licenseId\"\": \"\"string\"\",\n      \"\"licenseType\"\": \"\"string\"\",\n      \"\"format\"\": 0,\n      \"\"description\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"issueDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"supportExpireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"revoked\"\": true,\n      \"\"trace\"\": true,\n      \"\"licenseKey\"\": \"\"string\"\",\n      \"\"maxAllowedSites\"\": 0,"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"      \"\"userKey\"\": \"\"string\"\",\n      \"\"licensingMode\"\": 0,\n      \"\"licenseeName\"\": \"\"string\"\",\n      \"\"licenseeCompany\"\": \"\"string\"\",\n      \"\"licenseeEmail\"\": \"\"string\"\",\n      \"\"hash\"\": \"\"string\"\",\n      \"\"meta\"\": \"\"string\"\",\n      \"\"templateId\"\": 0,\n      \"\"signatureKeysId\"\": 0,\n      \"\"customerId\"\": 0,\n      \"\"orderId\"\": 0,\n      \"\"product\"\": {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"version\"\": \"\"string\"\",\n        \"\"copyright\"\": \"\"string\"\",\n        \"\"url\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\"\n      },\n      \"\"order\"\": {\n        \"\"id\"\": 0,\n        \"\"orderNumber\"\": \"\"string\"\",\n        \"\"status\"\": \"\"string\"\",\n        \"\"processedBy\"\": \"\"string\"\",\n        \"\"purchaseOrder\"\": \"\"string\"\",\n        \"\"total\"\": 0.1,\n        \"\"currency\"\": \"\"string\"\",\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"invoiceNumber\"\": \"\"string\"\",\n        \"\"paymentType\"\": \"\"string\"\",\n        \"\"paymentNumber\"\": \"\"string\"\",\n        \"\"paymentStatus\"\": \"\"string\"\",\n        \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"customerId\"\": 0,\n        \"\"customer\"\": {\n          \"\"id\"\": 0,\n          \"\"title\"\": \"\"string\"\",\n          \"\"firstName\"\": \"\"string\"\",\n          \"\"lastName\"\": \"\"string\"\",\n          \"\"company\"\": \"\"string\"\",\n          \"\"code\"\": \"\"string\"\",\n          \"\"vatCode\"\": \"\"string\"\",\n          \"\"invoiceCode\"\": \"\"string\"\",\n          \"\"rating\"\": 0,"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"          \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"address\"\": \"\"string\"\",\n          \"\"address1\"\": \"\"string\"\",\n          \"\"address2\"\": \"\"string\"\",\n          \"\"postalCode\"\": \"\"string\"\",\n          \"\"region\"\": \"\"string\"\",\n          \"\"city\"\": \"\"string\"\",\n          \"\"country\"\": \"\"string\"\",\n          \"\"countryCode\"\": \"\"string\"\",\n          \"\"mapCoordinates\"\": \"\"string\"\",\n          \"\"mapZoomLevel\"\": 0.1,\n          \"\"email\"\": \"\"string\"\",\n          \"\"phone\"\": \"\"string\"\",\n          \"\"mobile\"\": \"\"string\"\",\n          \"\"fax\"\": \"\"string\"\",\n          \"\"website\"\": \"\"string\"\",\n          \"\"notes\"\": \"\"string\"\",\n          \"\"isReseller\"\": true,\n          \"\"image\"\": \"\"string\"\",\n          \"\"meta\"\": \"\"string\"\",\n          \"\"contacts\"\": [\n            {\n              \"\"id\"\": 0,\n              \"\"title\"\": \"\"string\"\",\n              \"\"firstName\"\": \"\"string\"\",\n              \"\"lastName\"\": \"\"string\"\",\n              \"\"email\"\": \"\"string\"\",\n              \"\"phone\"\": \"\"string\"\",\n              \"\"mobile\"\": \"\"string\"\",\n              \"\"fax\"\": \"\"string\"\",\n              \"\"details\"\": \"\"string\"\",\n              \"\"notify\"\": true,\n              \"\"customerId\"\": 0,\n              \"\"meta\"\": \"\"string\"\"\n            }\n          ]\n        },\n        \"\"resellerId\"\": 0\n      },\n      \"\"customer\"\": {\n        \"\"id\"\": 0,\n        \"\"title\"\": \"\"string\"\",\n        \"\"firstName\"\": \"\"string\"\",\n        \"\"lastName\"\": \"\"string\"\",\n        \"\"company\"\": \"\"string\"\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"        \"\"code\"\": \"\"string\"\",\n        \"\"vatCode\"\": \"\"string\"\",\n        \"\"invoiceCode\"\": \"\"string\"\",\n        \"\"rating\"\": 0,\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"address\"\": \"\"string\"\",\n        \"\"address1\"\": \"\"string\"\",\n        \"\"address2\"\": \"\"string\"\",\n        \"\"postalCode\"\": \"\"string\"\",\n        \"\"region\"\": \"\"string\"\",\n        \"\"city\"\": \"\"string\"\",\n        \"\"country\"\": \"\"string\"\",\n        \"\"countryCode\"\": \"\"string\"\",\n        \"\"mapCoordinates\"\": \"\"string\"\",\n        \"\"mapZoomLevel\"\": 0.1,\n        \"\"email\"\": \"\"string\"\",\n        \"\"phone\"\": \"\"string\"\",\n        \"\"mobile\"\": \"\"string\"\",\n        \"\"fax\"\": \"\"string\"\",\n        \"\"website\"\": \"\"string\"\",\n        \"\"notes\"\": \"\"string\"\",\n        \"\"isReseller\"\": true,\n        \"\"image\"\": \"\"string\"\",\n        \"\"meta\"\": \"\"string\"\",\n        \"\"contacts\"\": [\n          {\n            \"\"id\"\": 0,\n            \"\"title\"\": \"\"string\"\",\n            \"\"firstName\"\": \"\"string\"\",\n            \"\"lastName\"\": \"\"string\"\",\n            \"\"email\"\": \"\"string\"\",\n            \"\"phone\"\": \"\"string\"\",\n            \"\"mobile\"\": \"\"string\"\",\n            \"\"fax\"\": \"\"string\"\",\n            \"\"details\"\": \"\"string\"\",\n            \"\"notify\"\": true,\n            \"\"customerId\"\": 0,\n            \"\"meta\"\": \"\"string\"\"\n          }\n        ]\n      },\n      \"\"template\"\": {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\",\n        \"\"code\"\": \"\"string\"\",\n        \"\"licenseType\"\": \"\"string\"\",\n        \"\"format\"\": 0,"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"        \"\"licensingMode\"\": 0,\n        \"\"licenseFileName\"\": \"\"string\"\",\n        \"\"issueDate\"\": true,\n        \"\"expireDays\"\": 0,\n        \"\"supportDays\"\": 0,\n        \"\"generateKeyInfo\"\": true,\n        \"\"userKey\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"template\"\": \"\"string\"\",\n        \"\"productId\"\": 0,\n        \"\"signatureKeysId\"\": 0,\n        \"\"releaseId\"\": 0,\n        \"\"product\"\": {\n          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"version\"\": \"\"string\"\",\n          \"\"copyright\"\": \"\"string\"\",\n          \"\"url\"\": \"\"string\"\",\n          \"\"description\"\": \"\"string\"\"\n        },\n        \"\"components\"\": [\n          \"\"string\"\"\n        ],\n        \"\"assemblies\"\": [\n          {\n            \"\"id\"\": 0,\n            \"\"name\"\": \"\"string\"\",\n            \"\"version\"\": \"\"string\"\",\n            \"\"culture\"\": \"\"string\"\",\n            \"\"publicKeyToken\"\": \"\"string\"\",\n            \"\"mappingFileId\"\": 0,\n            \"\"debugSymbolsKey\"\": \"\"string\"\"\n          }\n        ],\n        \"\"fields\"\": [\n          {\n            \"\"name\"\": \"\"string\"\",\n            \"\"value\"\": \"\"string\"\"\n          }\n        ],\n        \"\"features\"\": [\n          {\n            \"\"id\"\": \"\"string\"\",\n            \"\"name\"\": \"\"string\"\",\n            \"\"description\"\": \"\"string\"\",\n            \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n            \"\"key\"\": \"\"string\"\",\n            \"\"data\"\": \"\"string\"\"\n          }\n        ],\n        \"\"restrictions\"\": [\n          {\n            \"\"id\"\": \"\"string\"\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"            \"\"name\"\": \"\"string\"\",\n            \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n            \"\"properties\"\": {\n              \"\"property1\"\": \"\"string\"\",\n              \"\"property2\"\": \"\"string\"\"\n            },\n            \"\"customXmlContent\"\": \"\"string\"\"\n          }\n        ]\n      },\n      \"\"licensee\"\": {\n        \"\"name\"\": \"\"string\"\",\n        \"\"company\"\": \"\"string\"\",\n        \"\"contactInfo\"\": \"\"string\"\",\n        \"\"url\"\": \"\"string\"\"\n      },\n      \"\"components\"\": [\n        \"\"string\"\"\n      ],\n      \"\"assemblies\"\": [\n        {\n          \"\"id\"\": 0,\n          \"\"name\"\": \"\"string\"\",\n          \"\"version\"\": \"\"string\"\",\n          \"\"culture\"\": \"\"string\"\",\n          \"\"publicKeyToken\"\": \"\"string\"\",\n          \"\"mappingFileId\"\": 0,\n          \"\"debugSymbolsKey\"\": \"\"string\"\"\n        }\n      ],\n      \"\"fields\"\": [\n        {\n          \"\"name\"\": \"\"string\"\",\n          \"\"value\"\": \"\"string\"\"\n        }\n      ],\n      \"\"features\"\": [\n        {\n          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"description\"\": \"\"string\"\",\n          \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"key\"\": \"\"string\"\",\n          \"\"data\"\": \"\"string\"\"\n        }\n      ],\n      \"\"restrictions\"\": [\n        {\n          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"properties\"\": {\n            \"\"property1\"\": \"\"string\"\",\n            \"\"property2\"\": \"\"string\"\"\n          },\n          \"\"customXmlContent\"\": \"\"string\"\"\n        }\n      ]"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"    },\n    \"\"nodeLockedLicenseId\"\": 0,\n    \"\"nodeLockedLicense\"\": {\n      \"\"id\"\": 0,\n      \"\"licenseId\"\": \"\"string\"\",\n      \"\"licenseType\"\": \"\"string\"\",\n      \"\"format\"\": 0,\n      \"\"description\"\": \"\"string\"\",\n      \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"issueDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"supportExpireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n      \"\"revoked\"\": true,\n      \"\"trace\"\": true,\n      \"\"licenseKey\"\": \"\"string\"\",\n      \"\"maxAllowedSites\"\": 0,\n      \"\"userKey\"\": \"\"string\"\",\n      \"\"licensingMode\"\": 0,\n      \"\"licenseeName\"\": \"\"string\"\",\n      \"\"licenseeCompany\"\": \"\"string\"\",\n      \"\"licenseeEmail\"\": \"\"string\"\",\n      \"\"hash\"\": \"\"string\"\",\n      \"\"meta\"\": \"\"string\"\",\n      \"\"templateId\"\": 0,\n      \"\"signatureKeysId\"\": 0,\n      \"\"customerId\"\": 0,\n      \"\"orderId\"\": 0,\n      \"\"product\"\": {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"version\"\": \"\"string\"\",\n        \"\"copyright\"\": \"\"string\"\",\n        \"\"url\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\"\n      },\n      \"\"order\"\": {\n        \"\"id\"\": 0,\n        \"\"orderNumber\"\": \"\"string\"\",\n        \"\"status\"\": \"\"string\"\",\n        \"\"processedBy\"\": \"\"string\"\",\n        \"\"purchaseOrder\"\": \"\"string\"\",\n        \"\"total\"\": 0.1,\n        \"\"currency\"\": \"\"string\"\",\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"invoiceNumber\"\": \"\"string\"\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"        \"\"paymentType\"\": \"\"string\"\",\n        \"\"paymentNumber\"\": \"\"string\"\",\n        \"\"paymentStatus\"\": \"\"string\"\",\n        \"\"paymentDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"customerId\"\": 0,\n        \"\"customer\"\": {\n          \"\"id\"\": 0,\n          \"\"title\"\": \"\"string\"\",\n          \"\"firstName\"\": \"\"string\"\",\n          \"\"lastName\"\": \"\"string\"\",\n          \"\"company\"\": \"\"string\"\",\n          \"\"code\"\": \"\"string\"\",\n          \"\"vatCode\"\": \"\"string\"\",\n          \"\"invoiceCode\"\": \"\"string\"\",\n          \"\"rating\"\": 0,\n          \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"address\"\": \"\"string\"\",\n          \"\"address1\"\": \"\"string\"\",\n          \"\"address2\"\": \"\"string\"\",\n          \"\"postalCode\"\": \"\"string\"\",\n          \"\"region\"\": \"\"string\"\",\n          \"\"city\"\": \"\"string\"\",\n          \"\"country\"\": \"\"string\"\",\n          \"\"countryCode\"\": \"\"string\"\",\n          \"\"mapCoordinates\"\": \"\"string\"\",\n          \"\"mapZoomLevel\"\": 0.1,\n          \"\"email\"\": \"\"string\"\",\n          \"\"phone\"\": \"\"string\"\",\n          \"\"mobile\"\": \"\"string\"\",\n          \"\"fax\"\": \"\"string\"\",\n          \"\"website\"\": \"\"string\"\",\n          \"\"notes\"\": \"\"string\"\",\n          \"\"isReseller\"\": true,\n          \"\"image\"\": \"\"string\"\",\n          \"\"meta\"\": \"\"string\"\",\n          \"\"contacts\"\": [\n            {\n              \"\"id\"\": 0,\n              \"\"title\"\": \"\"string\"\",\n              \"\"firstName\"\": \"\"string\"\",\n              \"\"lastName\"\": \"\"string\"\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"              \"\"email\"\": \"\"string\"\",\n              \"\"phone\"\": \"\"string\"\",\n              \"\"mobile\"\": \"\"string\"\",\n              \"\"fax\"\": \"\"string\"\",\n              \"\"details\"\": \"\"string\"\",\n              \"\"notify\"\": true,\n              \"\"customerId\"\": 0,\n              \"\"meta\"\": \"\"string\"\"\n            }\n          ]\n        },\n        \"\"resellerId\"\": 0\n      },\n      \"\"customer\"\": {\n        \"\"id\"\": 0,\n        \"\"title\"\": \"\"string\"\",\n        \"\"firstName\"\": \"\"string\"\",\n        \"\"lastName\"\": \"\"string\"\",\n        \"\"company\"\": \"\"string\"\",\n        \"\"code\"\": \"\"string\"\",\n        \"\"vatCode\"\": \"\"string\"\",\n        \"\"invoiceCode\"\": \"\"string\"\",\n        \"\"rating\"\": 0,\n        \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"address\"\": \"\"string\"\",\n        \"\"address1\"\": \"\"string\"\",\n        \"\"address2\"\": \"\"string\"\",\n        \"\"postalCode\"\": \"\"string\"\",\n        \"\"region\"\": \"\"string\"\",\n        \"\"city\"\": \"\"string\"\",\n        \"\"country\"\": \"\"string\"\",\n        \"\"countryCode\"\": \"\"string\"\",\n        \"\"mapCoordinates\"\": \"\"string\"\",\n        \"\"mapZoomLevel\"\": 0.1,\n        \"\"email\"\": \"\"string\"\",\n        \"\"phone\"\": \"\"string\"\",\n        \"\"mobile\"\": \"\"string\"\",\n        \"\"fax\"\": \"\"string\"\",\n        \"\"website\"\": \"\"string\"\",\n        \"\"notes\"\": \"\"string\"\",\n        \"\"isReseller\"\": true,\n        \"\"image\"\": \"\"string\"\",\n        \"\"meta\"\": \"\"string\"\",\n        \"\"contacts\"\": [\n          {\n            \"\"id\"\": 0,\n            \"\"title\"\": \"\"string\"\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"            \"\"firstName\"\": \"\"string\"\",\n            \"\"lastName\"\": \"\"string\"\",\n            \"\"email\"\": \"\"string\"\",\n            \"\"phone\"\": \"\"string\"\",\n            \"\"mobile\"\": \"\"string\"\",\n            \"\"fax\"\": \"\"string\"\",\n            \"\"details\"\": \"\"string\"\",\n            \"\"notify\"\": true,\n            \"\"customerId\"\": 0,\n            \"\"meta\"\": \"\"string\"\"\n          }\n        ]\n      },\n      \"\"template\"\": {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\",\n        \"\"code\"\": \"\"string\"\",\n        \"\"licenseType\"\": \"\"string\"\",\n        \"\"format\"\": 0,\n        \"\"licensingMode\"\": 0,\n        \"\"licenseFileName\"\": \"\"string\"\",\n        \"\"issueDate\"\": true,\n        \"\"expireDays\"\": 0,\n        \"\"supportDays\"\": 0,\n        \"\"generateKeyInfo\"\": true,\n        \"\"userKey\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"template\"\": \"\"string\"\",\n        \"\"productId\"\": 0,\n        \"\"signatureKeysId\"\": 0,\n        \"\"releaseId\"\": 0,\n        \"\"product\"\": {\n          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"version\"\": \"\"string\"\",\n          \"\"copyright\"\": \"\"string\"\",\n          \"\"url\"\": \"\"string\"\",\n          \"\"description\"\": \"\"string\"\"\n        },\n        \"\"components\"\": [\n          \"\"string\"\"\n        ],\n        \"\"assemblies\"\": [\n          {\n            \"\"id\"\": 0,\n            \"\"name\"\": \"\"string\"\",\n            \"\"version\"\": \"\"string\"\",\n            \"\"culture\"\": \"\"string\"\",\n            \"\"publicKeyToken\"\": \"\"string\"\",\n            \"\"mappingFileId\"\": 0,"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"            \"\"debugSymbolsKey\"\": \"\"string\"\"\n          }\n        ],\n        \"\"fields\"\": [\n          {\n            \"\"name\"\": \"\"string\"\",\n            \"\"value\"\": \"\"string\"\"\n          }\n        ],\n        \"\"features\"\": [\n          {\n            \"\"id\"\": \"\"string\"\",\n            \"\"name\"\": \"\"string\"\",\n            \"\"description\"\": \"\"string\"\",\n            \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n            \"\"key\"\": \"\"string\"\",\n            \"\"data\"\": \"\"string\"\"\n          }\n        ],\n        \"\"restrictions\"\": [\n          {\n            \"\"id\"\": \"\"string\"\",\n            \"\"name\"\": \"\"string\"\",\n            \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n            \"\"properties\"\": {\n              \"\"property1\"\": \"\"string\"\",\n              \"\"property2\"\": \"\"string\"\"\n            },\n            \"\"customXmlContent\"\": \"\"string\"\"\n          }\n        ]\n      },\n      \"\"licensee\"\": {\n        \"\"name\"\": \"\"string\"\",\n        \"\"company\"\": \"\"string\"\",\n        \"\"contactInfo\"\": \"\"string\"\",\n        \"\"url\"\": \"\"string\"\"\n      },\n      \"\"components\"\": [\n        \"\"string\"\"\n      ],\n      \"\"assemblies\"\": [\n        {\n          \"\"id\"\": 0,\n          \"\"name\"\": \"\"string\"\",\n          \"\"version\"\": \"\"string\"\",\n          \"\"culture\"\": \"\"string\"\",\n          \"\"publicKeyToken\"\": \"\"string\"\",\n          \"\"mappingFileId\"\": 0,\n          \"\"debugSymbolsKey\"\": \"\"string\"\"\n        }\n      ],\n      \"\"fields\"\": [\n        {\n          \"\"name\"\": \"\"string\"\",\n          \"\"value\"\": \"\"string\"\"\n        }\n      ],\n      \"\"features\"\": [\n        {"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"description\"\": \"\"string\"\",\n          \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"key\"\": \"\"string\"\",\n          \"\"data\"\": \"\"string\"\"\n        }\n      ],\n      \"\"restrictions\"\": [\n        {\n          \"\"id\"\": \"\"string\"\",\n          \"\"name\"\": \"\"string\"\",\n          \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n          \"\"properties\"\": {\n            \"\"property1\"\": \"\"string\"\",\n            \"\"property2\"\": \"\"string\"\"\n          },\n          \"\"customXmlContent\"\": \"\"string\"\"\n        }\n      ]\n    }\n  }\n}\";\n      Management.InsertLicenseTokenRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertLicenseTokenRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.InsertLicenseTokenRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/licenses/\\{licenseId\\}/tokens\nInserts a new license token based on the provided request parameters.\nBody parameter"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"{\n  \"licenseToken\": {\n    \"id\": 0,\n    \"token\": \"string\",\n    \"address\": \"string\",\n    \"clientId\": \"string\",\n    \"clientName\": \"string\",\n    \"machineId\": \"string\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"lastHeartbeat\": \"2019-08-24T14:15:22Z\",\n    \"hash\": \"string\",\n    \"licenseId\": 0,\n    \"license\": {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\""},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"nodeLockedLicenseId\": 0,\n    \"nodeLockedLicense\": {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"        \"code\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  }\n}\nParameters"},{"page":208,"heading":"POST /v1/licenses/{licenseId}/tokens","anchor":"post-v1licenseslicenseidtokens","text":"Name | In | Type | Required | Description\nlicenseId | path | integer(int32) | true | The license ID.\nbody | body | Management.InsertLicenseTokenRequest | false | The request containing the parameters for inserting a new license token.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"licenseId\":0,\"licenseTokenId\":0,\"token\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseId\": 0,\n  \"licenseTokenId\": 0,\n  \"token\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertLicenseTokenResponse\nAuthentication: API key (x-api-key)."},{"page":208,"heading":"DELETE /v1/licenses/{licenseId}/tokens/{tokenId}","anchor":"delete-v1licenseslicenseidtokenstokenid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/licenses/{licenseId}/tokens/{tokenId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/licenses/{licenseId}/tokens/{tokenId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":208,"heading":"DELETE /v1/licenses/{licenseId}/tokens/{tokenId}","anchor":"delete-v1licenseslicenseidtokenstokenid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/licenses/{licenseId}/tokens/{tokenId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/licenses/\\{licenseId\\}/tokens/\\{tokenId\\}\nDeletes a license token based on the provided request parameters.\nParameters"},{"page":208,"heading":"DELETE /v1/licenses/{licenseId}/tokens/{tokenId}","anchor":"delete-v1licenseslicenseidtokenstokenid","text":"Name | In | Type | Required | Description\nlicenseId | path | integer(int32) | true | The license ID.\ntokenId | path | integer(int32) | true | The token ID.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteLicenseTokenResponse\nAuthentication: API key (x-api-key)."},{"page":209,"heading":"GET /v1/license-traces","anchor":"get-v1license-traces","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/license-traces \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/license-traces',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":209,"heading":"GET /v1/license-traces","anchor":"get-v1license-traces","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/license-traces\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/license-traces\nRetrieves license traces based on the provided request parameters.\nParameters"},{"page":209,"heading":"GET /v1/license-traces","anchor":"get-v1license-traces","text":"Name | In | Type | Required | Description\nlicenseId | query | integer(int32) | false | none\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"licenseTraces\":[{\"id\":0,\"clientIp\":\"string\",\"clientId\":\"string\",\"clientName\":\"string\",\"machineId\":\"string\",\"createdDate\":\"2019-08-24T14:15:22Z\",\"action\":0,\"geoLocation\":\"string\",\"meta\":\"string\",\"licenseId\":0}],\"totalLicenseTracesCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseTraces\": [\n    {\n      \"id\": 0,\n      \"clientIp\": \"string\",\n      \"clientId\": \"string\",\n      \"clientName\": \"string\",\n      \"machineId\": \"string\",\n      \"createdDate\": \"2019-08-24T14:15:22Z\",\n      \"action\": 0,\n      \"geoLocation\": \"string\",\n      \"meta\": \"string\",\n      \"licenseId\": 0\n    }\n  ],\n  \"totalLicenseTracesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetLicenseTracesResponse\nAuthentication: API key (x-api-key)."},{"page":209,"heading":"DELETE /v1/license-traces","anchor":"delete-v1license-traces","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/license-traces \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"traceId\": 0,\n  \"licenseId\": 0,\n  \"filter\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/license-traces',\n{\n  method: 'DELETE',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":209,"heading":"DELETE /v1/license-traces","anchor":"delete-v1license-traces","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/license-traces\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/license-traces\nDeletes a license trace based on the provided request parameters.\nBody parameter\n{\n  \"traceId\": 0,\n  \"licenseId\": 0,\n  \"filter\": \"string\"\n}\nParameters"},{"page":209,"heading":"DELETE /v1/license-traces","anchor":"delete-v1license-traces","text":"Name | In | Type | Required | Description\nbody | body | Management.DeleteLicenseTraceRequest | false | The request containing the parameters for deleting a license trace.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteLicenseTraceResponse\nAuthentication: API key (x-api-key)."},{"page":209,"heading":"POST /v1/license-traces/geolocation","anchor":"post-v1license-tracesgeolocation","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/license-traces/geolocation \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"traceIds\": [\n    0\n  ],\n  \"limit\": 0\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/license-traces/geolocation',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":209,"heading":"POST /v1/license-traces/geolocation","anchor":"post-v1license-tracesgeolocation","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/license-traces/geolocation\";\n      \n      string json = @\"{\n  \"\"traceIds\"\": [\n    0\n  ],\n  \"\"limit\"\": 0\n}\";\n      Management.ResolveLicenseTraceLocationsRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.ResolveLicenseTraceLocationsRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.ResolveLicenseTraceLocationsRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":209,"heading":"POST /v1/license-traces/geolocation","anchor":"post-v1license-tracesgeolocation","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/license-traces/geolocation\nResolves where the named traces' client addresses are and stores the answers.\nThe lookup happens here, with the geolocation service this deployment is configured with\n(GeoLocationService in the application settings): the caller never needs a provider\nof its own, and no credential travels. The route sets GeoLocation and can touch\nnothing else, so a write path opened for a convenience cannot become a way to edit a trace.\nGiven no ids, it takes the oldest traces that still have an address and no location.\nBody parameter\n{\n  \"traceIds\": [\n    0\n  ],\n  \"limit\": 0\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.ResolveLicenseTraceLocationsRequest | false | Which traces to locate, or how many to take.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"resolvedCount\":0,\"unresolvedCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"resolvedCount\": 0,\n  \"unresolvedCount\": 0\n}\nResponses"},{"page":209,"heading":"POST /v1/license-traces/geolocation","anchor":"post-v1license-tracesgeolocation","text":"Status | Meaning | Description | Schema\n200 | OK | OK | Management.ResolveLicenseTraceLocationsResponse\nAuthentication: API key (x-api-key)."},{"page":210,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":210,"heading":"GET /v1/license-templates","anchor":"get-v1license-templates","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/license-templates \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/license-templates',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":210,"heading":"GET /v1/license-templates","anchor":"get-v1license-templates","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/license-templates\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/license-templates\nRetrieves license templates based on the provided request parameters.\nParameters"},{"page":210,"heading":"GET /v1/license-templates","anchor":"get-v1license-templates","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"licenseTemplates\":[{\"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\":\"string\",\"template\":\"string\",\"productId\":0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]}],\"totalLicenseTemplatesCount\":0}"},{"page":210,"heading":"GET /v1/license-templates","anchor":"get-v1license-templates","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseTemplates\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\","},{"page":210,"heading":"GET /v1/license-templates","anchor":"get-v1license-templates","text":"          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicenseTemplatesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetLicenseTemplatesResponse\nAuthentication: API key (x-api-key)."},{"page":210,"heading":"POST /v1/license-templates","anchor":"post-v1license-templates","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/license-templates \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":210,"heading":"POST /v1/license-templates","anchor":"post-v1license-templates","text":"const inputBody = '{\n  \"licenseTemplate\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"code\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"licensingMode\": 0,\n    \"licenseFileName\": \"string\",\n    \"issueDate\": true,\n    \"expireDays\": 0,\n    \"supportDays\": 0,\n    \"generateKeyInfo\": true,\n    \"userKey\": \"string\",\n    \"description\": \"string\",\n    \"template\": \"string\",\n    \"productId\": 0,\n    \"signatureKeysId\": 0,\n    \"releaseId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\",\n        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]"},{"page":210,"heading":"POST /v1/license-templates","anchor":"post-v1license-templates","text":"  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/license-templates',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":210,"heading":"POST /v1/license-templates","anchor":"post-v1license-templates","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/license-templates\";\n      \n      string json = @\"{\n  \"\"licenseTemplate\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"code\"\": \"\"string\"\",\n    \"\"licenseType\"\": \"\"string\"\",\n    \"\"format\"\": 0,\n    \"\"licensingMode\"\": 0,\n    \"\"licenseFileName\"\": \"\"string\"\",\n    \"\"issueDate\"\": true,\n    \"\"expireDays\"\": 0,\n    \"\"supportDays\"\": 0,\n    \"\"generateKeyInfo\"\": true,\n    \"\"userKey\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"template\"\": \"\"string\"\",\n    \"\"productId\"\": 0,\n    \"\"signatureKeysId\"\": 0,\n    \"\"releaseId\"\": 0,\n    \"\"product\"\": {\n      \"\"id\"\": \"\"string\"\",\n      \"\"name\"\": \"\"string\"\",\n      \"\"version\"\": \"\"string\"\",\n      \"\"copyright\"\": \"\"string\"\",\n      \"\"url\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\"\n    },\n    \"\"components\"\": [\n      \"\"string\"\"\n    ],\n    \"\"assemblies\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\",\n        \"\"version\"\": \"\"string\"\",\n        \"\"culture\"\": \"\"string\"\","},{"page":210,"heading":"POST /v1/license-templates","anchor":"post-v1license-templates","text":"        \"\"publicKeyToken\"\": \"\"string\"\",\n        \"\"mappingFileId\"\": 0,\n        \"\"debugSymbolsKey\"\": \"\"string\"\"\n      }\n    ],\n    \"\"fields\"\": [\n      {\n        \"\"name\"\": \"\"string\"\",\n        \"\"value\"\": \"\"string\"\"\n      }\n    ],\n    \"\"features\"\": [\n      {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"key\"\": \"\"string\"\",\n        \"\"data\"\": \"\"string\"\"\n      }\n    ],\n    \"\"restrictions\"\": [\n      {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"properties\"\": {\n          \"\"property1\"\": \"\"string\"\",\n          \"\"property2\"\": \"\"string\"\"\n        },\n        \"\"customXmlContent\"\": \"\"string\"\"\n      }\n    ]\n  }\n}\";\n      Management.InsertLicenseTemplateRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertLicenseTemplateRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.InsertLicenseTemplateRequest content)\n    {\n        //Serialize Object"},{"page":210,"heading":"POST /v1/license-templates","anchor":"post-v1license-templates","text":"        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/license-templates\nInserts a new license template based on the provided request parameters.\nBody parameter"},{"page":210,"heading":"POST /v1/license-templates","anchor":"post-v1license-templates","text":"{\n  \"licenseTemplate\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"code\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"licensingMode\": 0,\n    \"licenseFileName\": \"string\",\n    \"issueDate\": true,\n    \"expireDays\": 0,\n    \"supportDays\": 0,\n    \"generateKeyInfo\": true,\n    \"userKey\": \"string\",\n    \"description\": \"string\",\n    \"template\": \"string\",\n    \"productId\": 0,\n    \"signatureKeysId\": 0,\n    \"releaseId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\",\n        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}\nParameters"},{"page":210,"heading":"POST /v1/license-templates","anchor":"post-v1license-templates","text":"Name | In | Type | Required | Description\nbody | body | Management.InsertLicenseTemplateRequest | false | The request containing the parameters for inserting a new license template.\nExample responses\n200 Response\n{\"templateId\":0,\"success\":true,\"code\":0,\"message\":\"string\",\"template\":\"string\"}\n{\n  \"templateId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"template\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertLicenseTemplateResponse\nAuthentication: API key (x-api-key)."},{"page":210,"heading":"PUT /v1/license-templates","anchor":"put-v1license-templates","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/license-templates \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":210,"heading":"PUT /v1/license-templates","anchor":"put-v1license-templates","text":"const inputBody = '{\n  \"licenseTemplate\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"code\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"licensingMode\": 0,\n    \"licenseFileName\": \"string\",\n    \"issueDate\": true,\n    \"expireDays\": 0,\n    \"supportDays\": 0,\n    \"generateKeyInfo\": true,\n    \"userKey\": \"string\",\n    \"description\": \"string\",\n    \"template\": \"string\",\n    \"productId\": 0,\n    \"signatureKeysId\": 0,\n    \"releaseId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\",\n        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]"},{"page":210,"heading":"PUT /v1/license-templates","anchor":"put-v1license-templates","text":"  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/license-templates',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":210,"heading":"PUT /v1/license-templates","anchor":"put-v1license-templates","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/license-templates\";\n\n      \n      string json = @\"{\n  \"\"licenseTemplate\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"code\"\": \"\"string\"\",\n    \"\"licenseType\"\": \"\"string\"\",\n    \"\"format\"\": 0,\n    \"\"licensingMode\"\": 0,\n    \"\"licenseFileName\"\": \"\"string\"\",\n    \"\"issueDate\"\": true,\n    \"\"expireDays\"\": 0,\n    \"\"supportDays\"\": 0,\n    \"\"generateKeyInfo\"\": true,\n    \"\"userKey\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"template\"\": \"\"string\"\",\n    \"\"productId\"\": 0,\n    \"\"signatureKeysId\"\": 0,\n    \"\"releaseId\"\": 0,\n    \"\"product\"\": {\n      \"\"id\"\": \"\"string\"\",\n      \"\"name\"\": \"\"string\"\",\n      \"\"version\"\": \"\"string\"\",\n      \"\"copyright\"\": \"\"string\"\",\n      \"\"url\"\": \"\"string\"\",\n      \"\"description\"\": \"\"string\"\"\n    },\n    \"\"components\"\": [\n      \"\"string\"\"\n    ],\n    \"\"assemblies\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\",\n        \"\"version\"\": \"\"string\"\",\n        \"\"culture\"\": \"\"string\"\","},{"page":210,"heading":"PUT /v1/license-templates","anchor":"put-v1license-templates","text":"        \"\"publicKeyToken\"\": \"\"string\"\",\n        \"\"mappingFileId\"\": 0,\n        \"\"debugSymbolsKey\"\": \"\"string\"\"\n      }\n    ],\n    \"\"fields\"\": [\n      {\n        \"\"name\"\": \"\"string\"\",\n        \"\"value\"\": \"\"string\"\"\n      }\n    ],\n    \"\"features\"\": [\n      {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"key\"\": \"\"string\"\",\n        \"\"data\"\": \"\"string\"\"\n      }\n    ],\n    \"\"restrictions\"\": [\n      {\n        \"\"id\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"properties\"\": {\n          \"\"property1\"\": \"\"string\"\",\n          \"\"property2\"\": \"\"string\"\"\n        },\n        \"\"customXmlContent\"\": \"\"string\"\"\n      }\n    ]\n  }\n}\";\n      Management.UpdateLicenseTemplateRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateLicenseTemplateRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json"},{"page":210,"heading":"PUT /v1/license-templates","anchor":"put-v1license-templates","text":"    private StringContent SerializeObject(Management.UpdateLicenseTemplateRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/license-templates\nUpdates an existing license template based on the provided request parameters.\nBody parameter"},{"page":210,"heading":"PUT /v1/license-templates","anchor":"put-v1license-templates","text":"{\n  \"licenseTemplate\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"code\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"licensingMode\": 0,\n    \"licenseFileName\": \"string\",\n    \"issueDate\": true,\n    \"expireDays\": 0,\n    \"supportDays\": 0,\n    \"generateKeyInfo\": true,\n    \"userKey\": \"string\",\n    \"description\": \"string\",\n    \"template\": \"string\",\n    \"productId\": 0,\n    \"signatureKeysId\": 0,\n    \"releaseId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\",\n        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}\nParameters"},{"page":210,"heading":"PUT /v1/license-templates","anchor":"put-v1license-templates","text":"Name | In | Type | Required | Description\nbody | body | Management.UpdateLicenseTemplateRequest | false | The request containing the parameters for updating a license template.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"template\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"template\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateLicenseTemplateResponse\nAuthentication: API key (x-api-key)."},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/license-templates/{templateId}/licenses \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/license-templates/{templateId}/licenses',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/license-templates/{templateId}/licenses\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/license-templates/\\{templateId\\}/licenses\nRetrieves licenses for a specific license template based on the provided request parameters.\nParameters"},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"Name | In | Type | Required | Description\ntemplateId | path | integer(int32) | true | The license template ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response"},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"licenses\":[{\"id\":0,\"licenseId\":\"string\",\"licenseType\":\"string\",\"format\":0,\"description\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"issueDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"supportExpireDate\":\"2019-08-24T14:15:22Z\",\"revoked\":true,\"trace\":true,\"licenseKey\":\"string\",\"maxAllowedSites\":0,\"userKey\":\"string\",\"licensingMode\":0,\"licenseeName\":\"string\",\"licenseeCompany\":\"string\",\"licenseeEmail\":\"string\",\"hash\":\"string\",\"meta\":\"string\",\"templateId\":0,\"signatureKeysId\":0,\"customerId\":0,\"orderId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"order\":{\"id\":0,\"orderNumber\":\"string\",\"status\":\"string\",\"processedBy\":\"string\",\"purchaseOrder\":\"string\",\"total\":0.1,\"currency\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"invoiceNumber\":\"string\",\"paymentType\":\"string\",\"paymentNumber\":\"string\",\"paymentStatus\":\"string\",\"paymentDate\":\"2019-08-24T14:15:22Z\",\"description\":\"string\",\"customerId\":0,\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapC"},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"oordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"resellerId\":0},\"customer\":{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"company\":\"string\",\"code\":\"string\",\"vatCode\":\"string\",\"invoiceCode\":\"string\",\"rating\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"address\":\"string\",\"address1\":\"string\",\"address2\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mapCoordinates\":\"string\",\"mapZoomLevel\":0.1,\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"website\":\"string\",\"notes\":\"string\",\"isReseller\":true,\"image\":\"string\",\"meta\":\"string\",\"contacts\":[{\"id\":0,\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"email\":\"string\",\"phone\":\"string\",\"mobile\":\"string\",\"fax\":\"string\",\"details\":\"string\",\"notify\":true,\"customerId\":0,\"meta\":\"string\"}]},\"template\":{\"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\":\"string\",\"template\":\"string\",\"productId\":"},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]},\"licensee\":{\"name\":\"string\",\"company\":\"string\",\"contactInfo\":\"string\",\"url\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]}],\"totalLicensesCount\":0}"},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenses\": [\n    {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\","},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\""},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\","},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":210,"heading":"GET /v1/license-templates/{templateId}/licenses","anchor":"get-v1license-templatestemplateidlicenses","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicensesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetLicenseTemplateLicensesResponse\nAuthentication: API key (x-api-key)."},{"page":210,"heading":"DELETE /v1/license-templates/{templateId}","anchor":"delete-v1license-templatestemplateid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/license-templates/{templateId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/license-templates/{templateId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":210,"heading":"DELETE /v1/license-templates/{templateId}","anchor":"delete-v1license-templatestemplateid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/license-templates/{templateId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/license-templates/\\{templateId\\}\nDeletes an existing license template based on the provided request parameters.\nParameters"},{"page":210,"heading":"DELETE /v1/license-templates/{templateId}","anchor":"delete-v1license-templatestemplateid","text":"Name | In | Type | Required | Description\ntemplateId | path | integer(int32) | true | The license template ID.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteLicenseTemplateResponse\nAuthentication: API key (x-api-key)."},{"page":211,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":211,"heading":"GET /v1/assemblies","anchor":"get-v1assemblies","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/assemblies \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/assemblies',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":211,"heading":"GET /v1/assemblies","anchor":"get-v1assemblies","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/assemblies\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/assemblies\nRetrieves the assemblies based on the provided request parameters.\nParameters"},{"page":211,"heading":"GET /v1/assemblies","anchor":"get-v1assemblies","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"totalAssembliesCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"assemblies\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"culture\": \"string\",\n      \"publicKeyToken\": \"string\",\n      \"mappingFileId\": 0,\n      \"debugSymbolsKey\": \"string\"\n    }\n  ],\n  \"totalAssembliesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetAssembliesResponse\nAuthentication: API key (x-api-key)."},{"page":211,"heading":"POST /v1/assemblies","anchor":"post-v1assemblies","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/assemblies \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/assemblies',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":211,"heading":"POST /v1/assemblies","anchor":"post-v1assemblies","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/assemblies\";\n      \n      string json = @\"{\n  \"\"assembly\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"version\"\": \"\"string\"\",\n    \"\"culture\"\": \"\"string\"\",\n    \"\"publicKeyToken\"\": \"\"string\"\",\n    \"\"mappingFileId\"\": 0,\n    \"\"debugSymbolsKey\"\": \"\"string\"\"\n  }\n}\";\n      Management.InsertAssemblyRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertAssemblyRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.InsertAssemblyRequest content)\n    {\n        //Serialize Object"},{"page":211,"heading":"POST /v1/assemblies","anchor":"post-v1assemblies","text":"        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/assemblies\nInserts a new assembly based on the provided request parameters.\nBody parameter\n{\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.InsertAssemblyRequest | false | The request containing the assembly to insert.\nExample responses\n200 Response\n{\"assemblyId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"assemblyId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertAssemblyResponse\nAuthentication: API key (x-api-key)."},{"page":211,"heading":"PUT /v1/assemblies","anchor":"put-v1assemblies","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/assemblies \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/assemblies',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":211,"heading":"PUT /v1/assemblies","anchor":"put-v1assemblies","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/assemblies\";\n\n      \n      string json = @\"{\n  \"\"assembly\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"version\"\": \"\"string\"\",\n    \"\"culture\"\": \"\"string\"\",\n    \"\"publicKeyToken\"\": \"\"string\"\",\n    \"\"mappingFileId\"\": 0,\n    \"\"debugSymbolsKey\"\": \"\"string\"\"\n  }\n}\";\n      Management.UpdateAssemblyRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateAssemblyRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json"},{"page":211,"heading":"PUT /v1/assemblies","anchor":"put-v1assemblies","text":"    private StringContent SerializeObject(Management.UpdateAssemblyRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/assemblies\nUpdates an existing assembly based on the provided request parameters.\nBody parameter\n{\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.UpdateAssemblyRequest | false | The request containing the assembly to update.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateAssemblyResponse\nAuthentication: API key (x-api-key)."},{"page":211,"heading":"DELETE /v1/assemblies/{assemblyId}","anchor":"delete-v1assembliesassemblyid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/assemblies/{assemblyId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/assemblies/{assemblyId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":211,"heading":"DELETE /v1/assemblies/{assemblyId}","anchor":"delete-v1assembliesassemblyid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/assemblies/{assemblyId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/assemblies/\\{assemblyId\\}\nDeletes an existing assembly based on the provided request parameters.\nParameters"},{"page":211,"heading":"DELETE /v1/assemblies/{assemblyId}","anchor":"delete-v1assembliesassemblyid","text":"Name | In | Type | Required | Description\nassemblyId | path | integer(int32) | true | The ID of the assembly to delete.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteAssemblyResponse\nAuthentication: API key (x-api-key)."},{"page":212,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":212,"heading":"GET /v1/resources","anchor":"get-v1resources","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/resources \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/resources',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":212,"heading":"GET /v1/resources","anchor":"get-v1resources","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/resources\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/resources\nGets a list of resources.\nParameters"},{"page":212,"heading":"GET /v1/resources","anchor":"get-v1resources","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"resources\":[{\"id\":0,\"name\":\"string\",\"type\":\"string\",\"code\":\"string\",\"description\":\"string\",\"source\":\"string\",\"password\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"data\":\"string\",\"dataFormat\":\"string\",\"meta\":\"string\"}],\"totalResourcesCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"resources\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"code\": \"string\",\n      \"description\": \"string\",\n      \"source\": \"string\",\n      \"password\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"data\": \"string\",\n      \"dataFormat\": \"string\",\n      \"meta\": \"string\"\n    }\n  ],\n  \"totalResourcesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetResourcesResponse\nAuthentication: API key (x-api-key)."},{"page":212,"heading":"POST /v1/resources","anchor":"post-v1resources","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/resources \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"resource\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"type\": \"string\",\n    \"code\": \"string\",\n    \"description\": \"string\",\n    \"source\": \"string\",\n    \"password\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"data\": \"string\",\n    \"dataFormat\": \"string\",\n    \"meta\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/resources',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":212,"heading":"POST /v1/resources","anchor":"post-v1resources","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/resources\";\n      \n      string json = @\"{\n  \"\"resource\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"type\"\": \"\"string\"\",\n    \"\"code\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"source\"\": \"\"string\"\",\n    \"\"password\"\": \"\"string\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"data\"\": \"\"string\"\",\n    \"\"dataFormat\"\": \"\"string\"\",\n    \"\"meta\"\": \"\"string\"\"\n  }\n}\";\n      Management.InsertResourceRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertResourceRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json"},{"page":212,"heading":"POST /v1/resources","anchor":"post-v1resources","text":"    private StringContent SerializeObject(Management.InsertResourceRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/resources\nInserts a new resource.\nBody parameter\n{\n  \"resource\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"type\": \"string\",\n    \"code\": \"string\",\n    \"description\": \"string\",\n    \"source\": \"string\",\n    \"password\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"data\": \"string\",\n    \"dataFormat\": \"string\",\n    \"meta\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.InsertResourceRequest | false | The request containing the details of the resource to insert.\nExample responses\n200 Response\n{\"resourceId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"resourceId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertResourceResponse"},{"page":212,"heading":"POST /v1/resources","anchor":"post-v1resources","text":"Authentication: API key (x-api-key)."},{"page":212,"heading":"PUT /v1/resources","anchor":"put-v1resources","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/resources \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"resource\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"type\": \"string\",\n    \"code\": \"string\",\n    \"description\": \"string\",\n    \"source\": \"string\",\n    \"password\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"data\": \"string\",\n    \"dataFormat\": \"string\",\n    \"meta\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/resources',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":212,"heading":"PUT /v1/resources","anchor":"put-v1resources","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/resources\";\n\n      \n      string json = @\"{\n  \"\"resource\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"type\"\": \"\"string\"\",\n    \"\"code\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"source\"\": \"\"string\"\",\n    \"\"password\"\": \"\"string\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"data\"\": \"\"string\"\",\n    \"\"dataFormat\"\": \"\"string\"\",\n    \"\"meta\"\": \"\"string\"\"\n  }\n}\";\n      Management.UpdateResourceRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateResourceRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n"},{"page":212,"heading":"PUT /v1/resources","anchor":"put-v1resources","text":"        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateResourceRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/resources\nUpdates an existing resource.\nBody parameter\n{\n  \"resource\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"type\": \"string\",\n    \"code\": \"string\",\n    \"description\": \"string\",\n    \"source\": \"string\",\n    \"password\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"data\": \"string\",\n    \"dataFormat\": \"string\",\n    \"meta\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.UpdateResourceRequest | false | The request containing the details of the resource to update.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses"},{"page":212,"heading":"PUT /v1/resources","anchor":"put-v1resources","text":"Status | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateResourceResponse\nAuthentication: API key (x-api-key)."},{"page":212,"heading":"DELETE /v1/resources/{resourceId}","anchor":"delete-v1resourcesresourceid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/resources/{resourceId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/resources/{resourceId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":212,"heading":"DELETE /v1/resources/{resourceId}","anchor":"delete-v1resourcesresourceid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/resources/{resourceId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/resources/\\{resourceId\\}\nDeletes a resource.\nParameters\nName | In | Type | Required | Description\nresourceId | path | integer(int32) | true | The resource ID.\nExample responses\n200 Response"},{"page":212,"heading":"DELETE /v1/resources/{resourceId}","anchor":"delete-v1resourcesresourceid","text":"{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteResourceResponse\nAuthentication: API key (x-api-key)."},{"page":213,"heading":"GET /v1/reports","anchor":"get-v1reports","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/reports \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/reports',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":213,"heading":"GET /v1/reports","anchor":"get-v1reports","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/reports\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/reports\nGets reports based on the provided request parameters.\nParameters"},{"page":213,"heading":"GET /v1/reports","anchor":"get-v1reports","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"reports\":[{\"id\":0,\"uid\":\"string\",\"name\":\"string\",\"version\":\"string\",\"date\":\"2019-08-24T14:15:22Z\",\"userKey\":\"string\",\"machineId\":\"string\",\"clientId\":\"string\",\"clientName\":\"string\",\"contentType\":\"string\",\"content\":\"string\",\"address\":\"string\",\"geoLocation\":\"string\",\"properties\":[{\"id\":0,\"name\":\"string\",\"value\":\"string\",\"reportId\":0}]}],\"totalReportsCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"reports\": [\n    {\n      \"id\": 0,\n      \"uid\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"date\": \"2019-08-24T14:15:22Z\",\n      \"userKey\": \"string\",\n      \"machineId\": \"string\",\n      \"clientId\": \"string\",\n      \"clientName\": \"string\",\n      \"contentType\": \"string\",\n      \"content\": \"string\",\n      \"address\": \"string\",\n      \"geoLocation\": \"string\",\n      \"properties\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"value\": \"string\",\n          \"reportId\": 0\n        }\n      ]\n    }\n  ],\n  \"totalReportsCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetReportResponse\nAuthentication: API key (x-api-key)."},{"page":213,"heading":"POST /v1/reports/geolocation","anchor":"post-v1reportsgeolocation","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/reports/geolocation \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"reportIds\": [\n    0\n  ],\n  \"limit\": 0\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/reports/geolocation',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":213,"heading":"POST /v1/reports/geolocation","anchor":"post-v1reportsgeolocation","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/reports/geolocation\";\n      \n      string json = @\"{\n  \"\"reportIds\"\": [\n    0\n  ],\n  \"\"limit\"\": 0\n}\";\n      Management.ResolveReportLocationsRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.ResolveReportLocationsRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.ResolveReportLocationsRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content"},{"page":213,"heading":"POST /v1/reports/geolocation","anchor":"post-v1reportsgeolocation","text":"        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/reports/geolocation\nResolves where the named reports' client addresses are and stores the answers. The\ncounterpart of M:Babel.Licensing.Service.Controllers.V1.ManagementController.ResolveLicenseTraceLocations(Babel.Licensing.Service.Management.ResolveLicenseTraceLocationsRequest), and just as narrow.\nBody parameter\n{\n  \"reportIds\": [\n    0\n  ],\n  \"limit\": 0\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.ResolveReportLocationsRequest | false | Which reports to locate, or how many to take.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"resolvedCount\":0,\"unresolvedCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"resolvedCount\": 0,\n  \"unresolvedCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.ResolveReportLocationsResponse\nAuthentication: API key (x-api-key)."},{"page":213,"heading":"DELETE /v1/reports/{reportId}","anchor":"delete-v1reportsreportid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/reports/{reportId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/reports/{reportId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":213,"heading":"DELETE /v1/reports/{reportId}","anchor":"delete-v1reportsreportid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/reports/{reportId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/reports/\\{reportId\\}\nDeletes a report with the specified ID.\nParameters\nName | In | Type | Required | Description\nreportId | path | integer(int32) | true | The ID of the report to delete.\nExample responses\n200 Response"},{"page":213,"heading":"DELETE /v1/reports/{reportId}","anchor":"delete-v1reportsreportid","text":"{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteReportResponse\nAuthentication: API key (x-api-key)."},{"page":214,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":214,"heading":"GET /v1/users","anchor":"get-v1users","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/users \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":214,"heading":"GET /v1/users","anchor":"get-v1users","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/users\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/users\nGets the users based on the provided request.\nParameters"},{"page":214,"heading":"GET /v1/users","anchor":"get-v1users","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nroles | query | string | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"users\":[{\"id\":\"string\",\"userName\":\"string\",\"email\":\"string\",\"phoneNumber\":\"string\",\"title\":\"string\",\"firstName\":\"string\",\"lastName\":\"string\",\"department\":\"string\",\"birthDate\":\"2019-08-24T14:15:22Z\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"lastDismissMessages\":\"2019-08-24T14:15:22Z\",\"lastLogIn\":\"2019-08-24T14:15:22Z\",\"rank\":0,\"image\":\"string\",\"address\":\"string\",\"postalCode\":\"string\",\"region\":\"string\",\"city\":\"string\",\"country\":\"string\",\"countryCode\":\"string\",\"mobile\":\"string\",\"notes\":\"string\",\"customerId\":0,\"roles\":[\"string\"],\"apiKeys\":[{\"id\":0,\"name\":\"string\",\"key\":\"string\",\"clientSecret\":\"string\",\"createdDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"ownerId\":\"string\",\"revoked\":true,\"permissions\":0,\"description\":\"string\"}],\"settings\":[{\"id\":0,\"category\":\"string\",\"group\":\"string\",\"name\":\"string\",\"value\":\"string\",\"type\":\"string\",\"description\":\"string\",\"readOnly\":true,\"userId\":\"string\"}]}],\"totalUsersCount\":0}"},{"page":214,"heading":"GET /v1/users","anchor":"get-v1users","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"users\": [\n    {\n      \"id\": \"string\",\n      \"userName\": \"string\",\n      \"email\": \"string\",\n      \"phoneNumber\": \"string\",\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"department\": \"string\",\n      \"birthDate\": \"2019-08-24T14:15:22Z\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n      \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n      \"rank\": 0,\n      \"image\": \"string\",\n      \"address\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mobile\": \"string\",\n      \"notes\": \"string\",\n      \"customerId\": 0,\n      \"roles\": [\n        \"string\"\n      ],\n      \"apiKeys\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"key\": \"string\",\n          \"clientSecret\": \"string\",\n          \"createdDate\": \"2019-08-24T14:15:22Z\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"ownerId\": \"string\",\n          \"revoked\": true,\n          \"permissions\": 0,\n          \"description\": \"string\"\n        }\n      ],\n      \"settings\": [\n        {\n          \"id\": 0,\n          \"category\": \"string\",\n          \"group\": \"string\",\n          \"name\": \"string\",\n          \"value\": \"string\",\n          \"type\": \"string\",\n          \"description\": \"string\",\n          \"readOnly\": true,"},{"page":214,"heading":"GET /v1/users","anchor":"get-v1users","text":"          \"userId\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalUsersCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetUsersResponse\nAuthentication: API key (x-api-key)."},{"page":214,"heading":"POST /v1/users","anchor":"post-v1users","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/users \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":214,"heading":"POST /v1/users","anchor":"post-v1users","text":"const inputBody = '{\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  },\n  \"password\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',"},{"page":214,"heading":"POST /v1/users","anchor":"post-v1users","text":"  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":214,"heading":"POST /v1/users","anchor":"post-v1users","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/users\";\n      \n      string json = @\"{\n  \"\"user\"\": {\n    \"\"id\"\": \"\"string\"\",\n    \"\"userName\"\": \"\"string\"\",\n    \"\"email\"\": \"\"string\"\",\n    \"\"phoneNumber\"\": \"\"string\"\",\n    \"\"title\"\": \"\"string\"\",\n    \"\"firstName\"\": \"\"string\"\",\n    \"\"lastName\"\": \"\"string\"\",\n    \"\"department\"\": \"\"string\"\",\n    \"\"birthDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"lastDismissMessages\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"lastLogIn\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"rank\"\": 0,\n    \"\"image\"\": \"\"string\"\",\n    \"\"address\"\": \"\"string\"\",\n    \"\"postalCode\"\": \"\"string\"\",\n    \"\"region\"\": \"\"string\"\",\n    \"\"city\"\": \"\"string\"\",\n    \"\"country\"\": \"\"string\"\",\n    \"\"countryCode\"\": \"\"string\"\",\n    \"\"mobile\"\": \"\"string\"\",\n    \"\"notes\"\": \"\"string\"\",\n    \"\"customerId\"\": 0,\n    \"\"roles\"\": [\n      \"\"string\"\"\n    ],\n    \"\"apiKeys\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"name\"\": \"\"string\"\","},{"page":214,"heading":"POST /v1/users","anchor":"post-v1users","text":"        \"\"key\"\": \"\"string\"\",\n        \"\"clientSecret\"\": \"\"string\"\",\n        \"\"createdDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"ownerId\"\": \"\"string\"\",\n        \"\"revoked\"\": true,\n        \"\"permissions\"\": 0,\n        \"\"description\"\": \"\"string\"\"\n      }\n    ],\n    \"\"settings\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"category\"\": \"\"string\"\",\n        \"\"group\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"value\"\": \"\"string\"\",\n        \"\"type\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"readOnly\"\": true,\n        \"\"userId\"\": \"\"string\"\"\n      }\n    ]\n  },\n  \"\"password\"\": \"\"string\"\"\n}\";\n      Management.InsertUserRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertUserRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.InsertUserRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    "},{"page":214,"heading":"POST /v1/users","anchor":"post-v1users","text":"    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/users\nInserts a new user.\nBody parameter"},{"page":214,"heading":"POST /v1/users","anchor":"post-v1users","text":"{\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  },\n  \"password\": \"string\"\n}\nParameters"},{"page":214,"heading":"POST /v1/users","anchor":"post-v1users","text":"Name | In | Type | Required | Description\nbody | body | Management.InsertUserRequest | false | The request containing the user to insert.\nExample responses\n200 Response\n{\"userId\":\"string\",\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"userId\": \"string\",\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertUserResponse\nAuthentication: API key (x-api-key)."},{"page":214,"heading":"PUT /v1/users","anchor":"put-v1users","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/users \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript"},{"page":214,"heading":"PUT /v1/users","anchor":"put-v1users","text":"const inputBody = '{\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  },\n  \"currentPassword\": \"string\",\n  \"newPassword\": \"string\"\n}';\nconst headers = {"},{"page":214,"heading":"PUT /v1/users","anchor":"put-v1users","text":"  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":214,"heading":"PUT /v1/users","anchor":"put-v1users","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/users\";\n\n      \n      string json = @\"{\n  \"\"user\"\": {\n    \"\"id\"\": \"\"string\"\",\n    \"\"userName\"\": \"\"string\"\",\n    \"\"email\"\": \"\"string\"\",\n    \"\"phoneNumber\"\": \"\"string\"\",\n    \"\"title\"\": \"\"string\"\",\n    \"\"firstName\"\": \"\"string\"\",\n    \"\"lastName\"\": \"\"string\"\",\n    \"\"department\"\": \"\"string\"\",\n    \"\"birthDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"lastDismissMessages\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"lastLogIn\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"rank\"\": 0,\n    \"\"image\"\": \"\"string\"\",\n    \"\"address\"\": \"\"string\"\",\n    \"\"postalCode\"\": \"\"string\"\",\n    \"\"region\"\": \"\"string\"\",\n    \"\"city\"\": \"\"string\"\",\n    \"\"country\"\": \"\"string\"\",\n    \"\"countryCode\"\": \"\"string\"\",\n    \"\"mobile\"\": \"\"string\"\",\n    \"\"notes\"\": \"\"string\"\",\n    \"\"customerId\"\": 0,\n    \"\"roles\"\": [\n      \"\"string\"\"\n    ],\n    \"\"apiKeys\"\": [\n      {\n        \"\"id\"\": 0,"},{"page":214,"heading":"PUT /v1/users","anchor":"put-v1users","text":"        \"\"name\"\": \"\"string\"\",\n        \"\"key\"\": \"\"string\"\",\n        \"\"clientSecret\"\": \"\"string\"\",\n        \"\"createdDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n        \"\"ownerId\"\": \"\"string\"\",\n        \"\"revoked\"\": true,\n        \"\"permissions\"\": 0,\n        \"\"description\"\": \"\"string\"\"\n      }\n    ],\n    \"\"settings\"\": [\n      {\n        \"\"id\"\": 0,\n        \"\"category\"\": \"\"string\"\",\n        \"\"group\"\": \"\"string\"\",\n        \"\"name\"\": \"\"string\"\",\n        \"\"value\"\": \"\"string\"\",\n        \"\"type\"\": \"\"string\"\",\n        \"\"description\"\": \"\"string\"\",\n        \"\"readOnly\"\": true,\n        \"\"userId\"\": \"\"string\"\"\n      }\n    ]\n  },\n  \"\"currentPassword\"\": \"\"string\"\",\n  \"\"newPassword\"\": \"\"string\"\"\n}\";\n      Management.UpdateUserRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateUserRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateUserRequest content)\n    {\n        //Serialize Object"},{"page":214,"heading":"PUT /v1/users","anchor":"put-v1users","text":"        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/users\nUpdates a user.\nBody parameter"},{"page":214,"heading":"PUT /v1/users","anchor":"put-v1users","text":"{\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  },\n  \"currentPassword\": \"string\",\n  \"newPassword\": \"string\"\n}\nParameters"},{"page":214,"heading":"PUT /v1/users","anchor":"put-v1users","text":"Name | In | Type | Required | Description\nbody | body | Management.UpdateUserRequest | false | The request containing the user to update.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateUserResponse\nAuthentication: API key (x-api-key)."},{"page":214,"heading":"DELETE /v1/users/{userId}","anchor":"delete-v1usersuserid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/users/{userId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users/{userId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":214,"heading":"DELETE /v1/users/{userId}","anchor":"delete-v1usersuserid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/users/{userId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/users/\\{userId\\}\nDeletes a user.\nParameters\nName | In | Type | Required | Description\nuserId | path | string | true | The ID of the user to delete.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}"},{"page":214,"heading":"DELETE /v1/users/{userId}","anchor":"delete-v1usersuserid","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteUserResponse\nAuthentication: API key (x-api-key)."},{"page":214,"heading":"GET /v1/users/{userId}/settings","anchor":"get-v1usersuseridsettings","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/users/{userId}/settings \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users/{userId}/settings',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":214,"heading":"GET /v1/users/{userId}/settings","anchor":"get-v1usersuseridsettings","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/users/{userId}/settings\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/users/\\{userId\\}/settings\nRetrieves the user settings based on the provided request.\nParameters"},{"page":214,"heading":"GET /v1/users/{userId}/settings","anchor":"get-v1usersuseridsettings","text":"Name | In | Type | Required | Description\nuserId | path | string | true | The user ID.\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"settings\":[{\"id\":0,\"category\":\"string\",\"group\":\"string\",\"name\":\"string\",\"value\":\"string\",\"type\":\"string\",\"description\":\"string\",\"readOnly\":true,\"userId\":\"string\"}],\"totalSettingsCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"settings\": [\n    {\n      \"id\": 0,\n      \"category\": \"string\",\n      \"group\": \"string\",\n      \"name\": \"string\",\n      \"value\": \"string\",\n      \"type\": \"string\",\n      \"description\": \"string\",\n      \"readOnly\": true,\n      \"userId\": \"string\"\n    }\n  ],\n  \"totalSettingsCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetUserSettingsResponse\nAuthentication: API key (x-api-key)."},{"page":214,"heading":"POST /v1/users/{userId}/settings","anchor":"post-v1usersuseridsettings","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/users/{userId}/settings \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"setting\": {\n    \"id\": 0,\n    \"category\": \"string\",\n    \"group\": \"string\",\n    \"name\": \"string\",\n    \"value\": \"string\",\n    \"type\": \"string\",\n    \"description\": \"string\",\n    \"readOnly\": true,\n    \"userId\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users/{userId}/settings',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":214,"heading":"POST /v1/users/{userId}/settings","anchor":"post-v1usersuseridsettings","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/users/{userId}/settings\";\n      \n      string json = @\"{\n  \"\"setting\"\": {\n    \"\"id\"\": 0,\n    \"\"category\"\": \"\"string\"\",\n    \"\"group\"\": \"\"string\"\",\n    \"\"name\"\": \"\"string\"\",\n    \"\"value\"\": \"\"string\"\",\n    \"\"type\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"readOnly\"\": true,\n    \"\"userId\"\": \"\"string\"\"\n  }\n}\";\n      Management.InsertUserSettingRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertUserSettingRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.InsertUserSettingRequest content)\n    {"},{"page":214,"heading":"POST /v1/users/{userId}/settings","anchor":"post-v1usersuseridsettings","text":"        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/users/\\{userId\\}/settings\nInserts new user settings based on the provided request.\nBody parameter\n{\n  \"setting\": {\n    \"id\": 0,\n    \"category\": \"string\",\n    \"group\": \"string\",\n    \"name\": \"string\",\n    \"value\": \"string\",\n    \"type\": \"string\",\n    \"description\": \"string\",\n    \"readOnly\": true,\n    \"userId\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nuserId | path | string | true | The user ID.\nbody | body | Management.InsertUserSettingRequest | false | The request containing the user settings to insert.\nExample responses\n200 Response\n{\"settingId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"settingId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertUserSettingResponse\nAuthentication: API key (x-api-key)."},{"page":214,"heading":"PUT /v1/users/{userId}/settings","anchor":"put-v1usersuseridsettings","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/users/{userId}/settings \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"setting\": {\n    \"id\": 0,\n    \"category\": \"string\",\n    \"group\": \"string\",\n    \"name\": \"string\",\n    \"value\": \"string\",\n    \"type\": \"string\",\n    \"description\": \"string\",\n    \"readOnly\": true,\n    \"userId\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users/{userId}/settings',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":214,"heading":"PUT /v1/users/{userId}/settings","anchor":"put-v1usersuseridsettings","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/users/{userId}/settings\";\n\n      \n      string json = @\"{\n  \"\"setting\"\": {\n    \"\"id\"\": 0,\n    \"\"category\"\": \"\"string\"\",\n    \"\"group\"\": \"\"string\"\",\n    \"\"name\"\": \"\"string\"\",\n    \"\"value\"\": \"\"string\"\",\n    \"\"type\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"readOnly\"\": true,\n    \"\"userId\"\": \"\"string\"\"\n  }\n}\";\n      Management.UpdateUserSettingRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateUserSettingRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    "},{"page":214,"heading":"PUT /v1/users/{userId}/settings","anchor":"put-v1usersuseridsettings","text":"    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateUserSettingRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/users/\\{userId\\}/settings\nUpdates user settings based on the provided request.\nBody parameter\n{\n  \"setting\": {\n    \"id\": 0,\n    \"category\": \"string\",\n    \"group\": \"string\",\n    \"name\": \"string\",\n    \"value\": \"string\",\n    \"type\": \"string\",\n    \"description\": \"string\",\n    \"readOnly\": true,\n    \"userId\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nuserId | path | string | true | The user ID.\nbody | body | Management.UpdateUserSettingRequest | false | The request containing the user settings to update.\nExample responses\n200 Response\n{\"settingsId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"settingsId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateUserSettingResponse"},{"page":214,"heading":"PUT /v1/users/{userId}/settings","anchor":"put-v1usersuseridsettings","text":"Authentication: API key (x-api-key)."},{"page":214,"heading":"DELETE /v1/users/{userId}/settings/{settingId}","anchor":"delete-v1usersuseridsettingssettingid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/users/{userId}/settings/{settingId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users/{userId}/settings/{settingId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":214,"heading":"DELETE /v1/users/{userId}/settings/{settingId}","anchor":"delete-v1usersuseridsettingssettingid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/users/{userId}/settings/{settingId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/users/\\{userId\\}/settings/\\{settingId\\}\nDeletes user settings based on the provided request.\nParameters"},{"page":214,"heading":"DELETE /v1/users/{userId}/settings/{settingId}","anchor":"delete-v1usersuseridsettingssettingid","text":"Name | In | Type | Required | Description\nuserId | path | string | true | The user ID.\nsettingId | path | integer(int32) | true | The setting ID.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteUserSettingResponse\nAuthentication: API key (x-api-key)."},{"page":215,"heading":"GET /v1/roles","anchor":"get-v1roles","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/roles \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/roles',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":215,"heading":"GET /v1/roles","anchor":"get-v1roles","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/roles\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/roles\nRetrieves roles based on the provided request.\nParameters"},{"page":215,"heading":"GET /v1/roles","anchor":"get-v1roles","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"roles\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\"}],\"totalRolesCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"roles\": [\n    {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\"\n    }\n  ],\n  \"totalRolesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetRolesResponse\nAuthentication: API key (x-api-key)."},{"page":215,"heading":"GET /v1/users/{userId}/roles","anchor":"get-v1usersuseridroles","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/users/{userId}/roles \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users/{userId}/roles',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":215,"heading":"GET /v1/users/{userId}/roles","anchor":"get-v1usersuseridroles","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/users/{userId}/roles\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/users/\\{userId\\}/roles\nRetrieves the roles of a specific user based on the provided request.\nParameters"},{"page":215,"heading":"GET /v1/users/{userId}/roles","anchor":"get-v1usersuseridroles","text":"Name | In | Type | Required | Description\nuserId | path | string | true | The user ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"roles\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\"}],\"totalRolesCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"roles\": [\n    {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\"\n    }\n  ],\n  \"totalRolesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetUserRolesResponse\nAuthentication: API key (x-api-key)."},{"page":215,"heading":"POST /v1/users/{userId}/roles","anchor":"post-v1usersuseridroles","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/users/{userId}/roles \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"roles\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users/{userId}/roles',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":215,"heading":"POST /v1/users/{userId}/roles","anchor":"post-v1usersuseridroles","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/users/{userId}/roles\";\n      \n      string json = @\"{\n  \"\"roles\"\": \"\"string\"\"\n}\";\n      Management.AddUserToRoleRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.AddUserToRoleRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.AddUserToRoleRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    "},{"page":215,"heading":"POST /v1/users/{userId}/roles","anchor":"post-v1usersuseridroles","text":"    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/users/\\{userId\\}/roles\nAdds a user to the specified roles.\nBody parameter\n{\n  \"roles\": \"string\"\n}\nParameters\nName | In | Type | Required | Description\nuserId | path | string | true | The user ID.\nbody | body | Management.AddUserToRoleRequest | false | The request containing the user ID and the roles to add.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.AddUserToRoleResponse\nAuthentication: API key (x-api-key)."},{"page":215,"heading":"DELETE /v1/users/{userId}/roles","anchor":"delete-v1usersuseridroles","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/users/{userId}/roles \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"roles\": \"string\"\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/users/{userId}/roles',\n{\n  method: 'DELETE',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":215,"heading":"DELETE /v1/users/{userId}/roles","anchor":"delete-v1usersuseridroles","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/users/{userId}/roles\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/users/\\{userId\\}/roles\nRemoves a user from the specified roles.\nBody parameter\n{\n  \"roles\": \"string\"\n}\nParameters"},{"page":215,"heading":"DELETE /v1/users/{userId}/roles","anchor":"delete-v1usersuseridroles","text":"Name | In | Type | Required | Description\nuserId | path | string | true | The user ID.\nbody | body | Management.RemoveUserFromRoleRequest | false | The request containing the user ID and the roles to remove.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.RemoveUserFromRoleResponse\nAuthentication: API key (x-api-key)."},{"page":216,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":216,"heading":"GET /v1/api-keys","anchor":"get-v1api-keys","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/api-keys \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/api-keys',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":216,"heading":"GET /v1/api-keys","anchor":"get-v1api-keys","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/api-keys\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/api-keys\nGets the API keys based on the provided request.\nParameters"},{"page":216,"heading":"GET /v1/api-keys","anchor":"get-v1api-keys","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\ninclude | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"apiKeys\":[{\"id\":0,\"name\":\"string\",\"key\":\"string\",\"clientSecret\":\"string\",\"createdDate\":\"2019-08-24T14:15:22Z\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"ownerId\":\"string\",\"revoked\":true,\"permissions\":0,\"description\":\"string\"}],\"totalApiKeysCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"apiKeys\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"key\": \"string\",\n      \"clientSecret\": \"string\",\n      \"createdDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"ownerId\": \"string\",\n      \"revoked\": true,\n      \"permissions\": 0,\n      \"description\": \"string\"\n    }\n  ],\n  \"totalApiKeysCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetApiKeysResponse\nAuthentication: API key (x-api-key)."},{"page":216,"heading":"POST /v1/api-keys","anchor":"post-v1api-keys","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/api-keys \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"apiKey\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"key\": \"string\",\n    \"clientSecret\": \"string\",\n    \"createdDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"ownerId\": \"string\",\n    \"revoked\": true,\n    \"permissions\": 0,\n    \"description\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/api-keys',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":216,"heading":"POST /v1/api-keys","anchor":"post-v1api-keys","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/api-keys\";\n      \n      string json = @\"{\n  \"\"apiKey\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"key\"\": \"\"string\"\",\n    \"\"clientSecret\"\": \"\"string\"\",\n    \"\"createdDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"ownerId\"\": \"\"string\"\",\n    \"\"revoked\"\": true,\n    \"\"permissions\"\": 0,\n    \"\"description\"\": \"\"string\"\"\n  }\n}\";\n      Management.InsertApiKeyRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertApiKeyRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json"},{"page":216,"heading":"POST /v1/api-keys","anchor":"post-v1api-keys","text":"    private StringContent SerializeObject(Management.InsertApiKeyRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/api-keys\nInserts a new API key.\nBody parameter\n{\n  \"apiKey\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"key\": \"string\",\n    \"clientSecret\": \"string\",\n    \"createdDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"ownerId\": \"string\",\n    \"revoked\": true,\n    \"permissions\": 0,\n    \"description\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.InsertApiKeyRequest | false | The request containing the API key to insert.\nExample responses\n200 Response\n{\"apiKeyId\":0,\"success\":true,\"code\":0,\"message\":\"string\",\"apiKey\":\"string\"}\n{\n  \"apiKeyId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"apiKey\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertApiKeyResponse\nAuthentication: API key (x-api-key)."},{"page":216,"heading":"PUT /v1/api-keys","anchor":"put-v1api-keys","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/api-keys \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"apiKey\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"key\": \"string\",\n    \"clientSecret\": \"string\",\n    \"createdDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"ownerId\": \"string\",\n    \"revoked\": true,\n    \"permissions\": 0,\n    \"description\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/api-keys',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":216,"heading":"PUT /v1/api-keys","anchor":"put-v1api-keys","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/api-keys\";\n\n      \n      string json = @\"{\n  \"\"apiKey\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"key\"\": \"\"string\"\",\n    \"\"clientSecret\"\": \"\"string\"\",\n    \"\"createdDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"expireDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"ownerId\"\": \"\"string\"\",\n    \"\"revoked\"\": true,\n    \"\"permissions\"\": 0,\n    \"\"description\"\": \"\"string\"\"\n  }\n}\";\n      Management.UpdateApiKeyRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateApiKeyRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response"},{"page":216,"heading":"PUT /v1/api-keys","anchor":"put-v1api-keys","text":"        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateApiKeyRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/api-keys\nUpdates the API key with the specified ID.\nBody parameter\n{\n  \"apiKey\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"key\": \"string\",\n    \"clientSecret\": \"string\",\n    \"createdDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"ownerId\": \"string\",\n    \"revoked\": true,\n    \"permissions\": 0,\n    \"description\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.UpdateApiKeyRequest | false | The request containing the API key to update.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateApiKeyResponse"},{"page":216,"heading":"PUT /v1/api-keys","anchor":"put-v1api-keys","text":"Authentication: API key (x-api-key)."},{"page":216,"heading":"DELETE /v1/api-keys/{apiKeyId}","anchor":"delete-v1api-keysapikeyid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/api-keys/{apiKeyId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/api-keys/{apiKeyId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":216,"heading":"DELETE /v1/api-keys/{apiKeyId}","anchor":"delete-v1api-keysapikeyid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/api-keys/{apiKeyId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/api-keys/\\{apiKeyId\\}\nDeletes the API key with the specified ID.\nParameters\nName | In | Type | Required | Description\napiKeyId | path | integer(int32) | true | The ID of the API key to delete.\nExample responses\n200 Response"},{"page":216,"heading":"DELETE /v1/api-keys/{apiKeyId}","anchor":"delete-v1api-keysapikeyid","text":"{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteApiKeyResponse\nAuthentication: API key (x-api-key)."},{"page":217,"heading":"GET /v1/log/levels","anchor":"get-v1loglevels","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/log/levels \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/log/levels',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":217,"heading":"GET /v1/log/levels","anchor":"get-v1loglevels","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/log/levels\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/log/levels\nGets the log levels for the specified date range.\nParameters\nName | In | Type | Required | Description\nstartDate | query | string(date-time) | false | none\nendDate | query | string(date-time) | false | none\nintervals | query | integer(int32) | false | none\nExample responses"},{"page":217,"heading":"GET /v1/log/levels","anchor":"get-v1loglevels","text":"200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"logLevels\":[{\"date\":\"2019-08-24T14:15:22Z\",\"level\":\"string\",\"count\":0}],\"groupBy\":\"string\",\"totalLogLevelEntriesCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"logLevels\": [\n    {\n      \"date\": \"2019-08-24T14:15:22Z\",\n      \"level\": \"string\",\n      \"count\": 0\n    }\n  ],\n  \"groupBy\": \"string\",\n  \"totalLogLevelEntriesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetLogLevelsResponse\nAuthentication: API key (x-api-key)."},{"page":217,"heading":"GET /v1/log","anchor":"get-v1log","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/log \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/log',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":217,"heading":"GET /v1/log","anchor":"get-v1log","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/log\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/log\nGets the log entries based on the provided request.\nParameters"},{"page":217,"heading":"GET /v1/log","anchor":"get-v1log","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nstartDate | query | string(date-time) | false | none\nendDate | query | string(date-time) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"logEntries\":[{\"id\":0,\"message\":\"string\",\"messageTemplate\":\"string\",\"level\":\"string\",\"timeStamp\":\"2019-08-24T14:15:22Z\",\"exception\":\"string\",\"properties\":\"string\"}],\"totalLogEntriesCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"logEntries\": [\n    {\n      \"id\": 0,\n      \"message\": \"string\",\n      \"messageTemplate\": \"string\",\n      \"level\": \"string\",\n      \"timeStamp\": \"2019-08-24T14:15:22Z\",\n      \"exception\": \"string\",\n      \"properties\": \"string\"\n    }\n  ],\n  \"totalLogEntriesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetLogResponse\nAuthentication: API key (x-api-key)."},{"page":217,"heading":"DELETE /v1/log","anchor":"delete-v1log","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/log \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/log',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":217,"heading":"DELETE /v1/log","anchor":"delete-v1log","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/log\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/log\nDeletes a log based on the provided request.\nParameters"},{"page":217,"heading":"DELETE /v1/log","anchor":"delete-v1log","text":"Name | In | Type | Required | Description\nid | query | integer(int32) | false | none\nfilter | query | string | false | none\nstartDate | query | string(date-time) | false | none\nendDate | query | string(date-time) | false | none\ndeleteAll | query | boolean | false | none\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | The log has been deleted successfully. Example:\n{\n\"Success\": true,\n\"Message\": \"A total of 10 log entries have been deleted.\",\n\"DeletedLogCount\": 10\n} | None\nAuthentication: API key (x-api-key)."},{"page":218,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":218,"heading":"GET /v1/settings","anchor":"get-v1settings","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/settings \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/settings',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":218,"heading":"GET /v1/settings","anchor":"get-v1settings","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/settings\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/settings\nGets the application settings.\nParameters\nName | In | Type | Required | Description\nrequest | query | Management.GetSettingsRequest | false | The request containing the parameters for the application settings to retrieve.\nExample responses\n200 Response"},{"page":218,"heading":"GET /v1/settings","anchor":"get-v1settings","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"settings\":[{\"group\":\"string\",\"name\":\"string\",\"type\":\"string\",\"value\":null}]}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"settings\": [\n    {\n      \"group\": \"string\",\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"value\": null\n    }\n  ]\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetSettingsResponse\nAuthentication: API key (x-api-key)."},{"page":218,"heading":"PUT /v1/settings","anchor":"put-v1settings","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/settings \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"settings\": [\n    {\n      \"group\": \"string\",\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"value\": null\n    }\n  ]\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/settings',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":218,"heading":"PUT /v1/settings","anchor":"put-v1settings","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/settings\";\n\n      \n      string json = @\"{\n  \"\"settings\"\": [\n    {\n      \"\"group\"\": \"\"string\"\",\n      \"\"name\"\": \"\"string\"\",\n      \"\"type\"\": \"\"string\"\",\n      \"\"value\"\": null\n    }\n  ]\n}\";\n      Management.UpdateSettingsRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateSettingsRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateSettingsRequest content)\n    {"},{"page":218,"heading":"PUT /v1/settings","anchor":"put-v1settings","text":"        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/settings\nUpdates the application settings.\nBody parameter\n{\n  \"settings\": [\n    {\n      \"group\": \"string\",\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"value\": null\n    }\n  ]\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.UpdateSettingsRequest | false | The request containing the updated settings.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateSettingsResponse\nAuthentication: API key (x-api-key)."},{"page":218,"heading":"GET /v1/info","anchor":"get-v1info","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/info \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/info',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":218,"heading":"GET /v1/info","anchor":"get-v1info","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/info\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/info\nGets the server information.\nExample responses\n200 Response"},{"page":218,"heading":"GET /v1/info","anchor":"get-v1info","text":"{\"success\":true,\"code\":0,\"message\":\"string\",\"product\":\"string\",\"edition\":0,\"version\":\"string\",\"license\":\"string\",\"serverHost\":\"string\",\"serverTime\":\"2019-08-24T14:15:22Z\",\"clientAddress\":\"string\",\"activeTokens\":0,\"maxTokens\":0,\"activationTokens\":0,\"floatingTokens\":0,\"expiredTokens\":0,\"totalLicenses\":0,\"revokedLicenses\":0,\"tracedLicenses\":0,\"activationLicenses\":0,\"floatingLicenses\":0,\"fileLicenses\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"product\": \"string\",\n  \"edition\": 0,\n  \"version\": \"string\",\n  \"license\": \"string\",\n  \"serverHost\": \"string\",\n  \"serverTime\": \"2019-08-24T14:15:22Z\",\n  \"clientAddress\": \"string\",\n  \"activeTokens\": 0,\n  \"maxTokens\": 0,\n  \"activationTokens\": 0,\n  \"floatingTokens\": 0,\n  \"expiredTokens\": 0,\n  \"totalLicenses\": 0,\n  \"revokedLicenses\": 0,\n  \"tracedLicenses\": 0,\n  \"activationLicenses\": 0,\n  \"floatingLicenses\": 0,\n  \"fileLicenses\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | The server information has been retrieved successfully. Example:\n{\n\"Product\": \"Babel Licensing Service\",\n\"Version\": \"10.7.0\"\n\"ServerHost\": \"172.34.12.1\"\n\"ServerTime\": \"2022-01-01T00:00:00Z\",\n...\n} | Management.GetServerInfoResponse\nAuthentication: API key (x-api-key)."},{"page":219,"heading":"POST /v1/email/send","anchor":"post-v1emailsend","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/email/send \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"to\": [\n    {\n      \"name\": \"string\",\n      \"email\": \"string\"\n    }\n  ],\n  \"subject\": \"string\",\n  \"body\": \"string\",\n  \"isHtml\": true,\n  \"attachments\": [\n    {\n      \"fileName\": \"string\",\n      \"content\": \"string\",\n      \"contentType\": \"string\"\n    }\n  ]\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/email/send',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":219,"heading":"POST /v1/email/send","anchor":"post-v1emailsend","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/email/send\";\n      \n      string json = @\"{\n  \"\"to\"\": [\n    {\n      \"\"name\"\": \"\"string\"\",\n      \"\"email\"\": \"\"string\"\"\n    }\n  ],\n  \"\"subject\"\": \"\"string\"\",\n  \"\"body\"\": \"\"string\"\",\n  \"\"isHtml\"\": true,\n  \"\"attachments\"\": [\n    {\n      \"\"fileName\"\": \"\"string\"\",\n      \"\"content\"\": \"\"string\"\",\n      \"\"contentType\"\": \"\"string\"\"\n    }\n  ]\n}\";\n      Management.SendEmailRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.SendEmailRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.SendEmailRequest content)\n    {"},{"page":219,"heading":"POST /v1/email/send","anchor":"post-v1emailsend","text":"        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/email/send\nSends an email using the configured email service.\nBody parameter\n{\n  \"to\": [\n    {\n      \"name\": \"string\",\n      \"email\": \"string\"\n    }\n  ],\n  \"subject\": \"string\",\n  \"body\": \"string\",\n  \"isHtml\": true,\n  \"attachments\": [\n    {\n      \"fileName\": \"string\",\n      \"content\": \"string\",\n      \"contentType\": \"string\"\n    }\n  ]\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.SendEmailRequest | false | The request containing the email details to send.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.SendEmailResponse\nAuthentication: API key (x-api-key)."},{"page":219,"heading":"POST /v1/email/license","anchor":"post-v1emaillicense","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/email/license \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"licenseId\": 0,\n  \"resourceId\": 0\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/email/license',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":219,"heading":"POST /v1/email/license","anchor":"post-v1emaillicense","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/email/license\";\n      \n      string json = @\"{\n  \"\"licenseId\"\": 0,\n  \"\"resourceId\"\": 0\n}\";\n      Management.SendLicenseEmailRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.SendLicenseEmailRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.SendLicenseEmailRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    "},{"page":219,"heading":"POST /v1/email/license","anchor":"post-v1emaillicense","text":"    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/email/license\nSends an email to a licensee based on a license and email resource.\nBody parameter\n{\n  \"licenseId\": 0,\n  \"resourceId\": 0\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.SendLicenseEmailRequest | false | The request containing license and email details to send.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.SendLicenseEmailResponse\nAuthentication: API key (x-api-key)."},{"page":220,"heading":"","anchor":"","text":"A product release describes one version of a product: version, releaseDate, channel (stable or insider), public and requiresMaintenance. A release has assemblies that ship with it, license templates created for it, and downloads: the files users install, one per platform and kind. Downloads can be added only to releases of application products (isApplication: true) with a major.minor.patch version.\nThe downloads of a release are what the Updates feed serves. The feed offers a release only when it is public, is on the channel the client asks for and has an artifact for the client's platform. A release that requires maintenance can be installed only by licenses whose maintenance covers the release date. Release routes need an API key of an Administrator, LicenseManager or Sales user; the download routes need Administrator or LicenseManager.\nAdding downloads\nPOST /v1/products/{productId}/releases/{releaseId}/downloads accepts two request formats on the same route.\nA JSON body registers a file that is hosted somewhere else. sourceKind must be url, the url must be an absolute https:// address without credentials, and you supply size, sha256 (lowercase hex) and sha512 (base64), because the service never sees the bytes. Clients downloading the file are redirected to the URL."},{"page":220,"heading":"","anchor":"","text":"A multipart/form-data body uploads the file itself. The service computes size, sha256 and sha512. Use sourceKind=local (the default) to store it on disk under Extensions:DownloadRoot, which must be configured, or sourceKind=resource to store it in the database, up to Extensions:MaxResourceArtifactBytes (64 MiB by default).\nplatform is one of win-x64, win-arm64, darwin-arm64, darwin-x64, linux-x64, linux-arm64, and kind is one of installer, zip, delta, blockmap. A release can hold one artifact for each platform and kind. Both formats answer 201 with the id, size and hashes of the new artifact.\nJSON (hosted file)\ncurl -X POST https://your-licensing-server/v1/products/3/releases/1/downloads \\\n  -H 'x-api-key: <key>' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"releaseDownload\": {\n      \"platform\": \"win-x64\",\n      \"kind\": \"installer\",\n      \"fileName\": \"AcmeApp-Setup-2.1.0.exe\",\n      \"sourceKind\": \"url\",\n      \"url\": \"https://downloads.example.com/acme/AcmeApp-Setup-2.1.0.exe\",\n      \"size\": 84523776,\n      \"sha256\": \"<sha-256, lowercase hex>\",\n      \"sha512\": \"<sha-512, base64>\"\n    }\n  }'\nMultipart (upload)\ncurl -X POST https://your-licensing-server/v1/products/3/releases/1/downloads \\\n  -H 'x-api-key: <key>' \\\n  -F platform=darwin-arm64 \\\n  -F kind=zip \\\n  -F sourceKind=local \\\n  -F file=@AcmeApp-2.1.0-arm64-mac.zip\nfileName is optional and defaults to the name of the uploaded file."},{"page":220,"heading":"","anchor":"","text":"PUT .../downloads changes the platform, kind, file name, signature or URL of an artifact, never its size or hashes: to replace the bytes, delete the artifact and add it again. POST .../downloads/verify hashes every uploaded artifact of the release again and returns the ids of those that are missing or no longer match in drifted. Hosted (url) artifacts are not checked."},{"page":220,"heading":"Pages","anchor":"pages","text":"Releases: Create, update, list and delete the releases of a product.\nRelease Assemblies: Assemblies attached to a release.\nRelease License Templates: License templates of a release.\nDownloads: Register, upload, update, verify and delete release artifacts."},{"page":220,"heading":"Endpoints","anchor":"endpoints","text":"Endpoint | Page\nGET /v1/products/{productId}/releases | Releases\nPOST /v1/products/{productId}/releases | Releases\nPUT /v1/products/{productId}/releases | Releases\nDELETE /v1/products/{productId}/releases/{releaseId} | Releases\nGET /v1/products/{productId}/releases/{releaseId}/assemblies | Release Assemblies\nPOST /v1/products/{productId}/releases/{releaseId}/assemblies | Release Assemblies\nPUT /v1/products/{productId}/releases/{releaseId}/assemblies | Release Assemblies\nDELETE /v1/products/{productId}/releases/{releaseId}/assemblies/{assemblyId} | Release Assemblies\nGET /v1/products/{productId}/releases/{releaseId}/license-templates | Release License Templates\nGET /v1/products/{productId}/releases/{releaseId}/downloads | Downloads\nPOST /v1/products/{productId}/releases/{releaseId}/downloads | Downloads\nPUT /v1/products/{productId}/releases/{releaseId}/downloads | Downloads\nDELETE /v1/products/{productId}/releases/{releaseId}/downloads/{downloadId} | Downloads\nPOST /v1/products/{productId}/releases/{releaseId}/downloads/verify | Downloads"},{"page":221,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":221,"heading":"GET /v1/products/{productId}/releases","anchor":"get-v1productsproductidreleases","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/products/{productId}/releases \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":221,"heading":"GET /v1/products/{productId}/releases","anchor":"get-v1productsproductidreleases","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/products/{productId}/releases\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/products/\\{productId\\}/releases\nGets the product releases based on the provided request.\nParameters"},{"page":221,"heading":"GET /v1/products/{productId}/releases","anchor":"get-v1productsproductidreleases","text":"Name | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"releases\":[{\"id\":0,\"releaseDate\":\"2019-08-24T14:15:22Z\",\"name\":\"string\",\"version\":\"string\",\"description\":\"string\",\"public\":true,\"requiresMaintenance\":true,\"releaseNotes\":\"string\",\"channel\":\"string\"}],\"totalReleasesCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"releases\": [\n    {\n      \"id\": 0,\n      \"releaseDate\": \"2019-08-24T14:15:22Z\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"description\": \"string\",\n      \"public\": true,\n      \"requiresMaintenance\": true,\n      \"releaseNotes\": \"string\",\n      \"channel\": \"stable\"\n    }\n  ],\n  \"totalReleasesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetProductReleasesResponse\nAuthentication: API key (x-api-key)."},{"page":221,"heading":"POST /v1/products/{productId}/releases","anchor":"post-v1productsproductidreleases","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/products/{productId}/releases \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"release\": {\n    \"id\": 0,\n    \"releaseDate\": \"2019-08-24T14:15:22Z\",\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"description\": \"string\",\n    \"public\": true,\n    \"requiresMaintenance\": true,\n    \"releaseNotes\": \"string\",\n    \"channel\": \"stable\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":221,"heading":"POST /v1/products/{productId}/releases","anchor":"post-v1productsproductidreleases","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/products/{productId}/releases\";\n      \n      string json = @\"{\n  \"\"release\"\": {\n    \"\"id\"\": 0,\n    \"\"releaseDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"name\"\": \"\"string\"\",\n    \"\"version\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"public\"\": true,\n    \"\"requiresMaintenance\"\": true,\n    \"\"releaseNotes\"\": \"\"string\"\",\n    \"\"channel\"\": \"\"stable\"\"\n  }\n}\";\n      Management.InsertProductReleaseRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertProductReleaseRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json"},{"page":221,"heading":"POST /v1/products/{productId}/releases","anchor":"post-v1productsproductidreleases","text":"    private StringContent SerializeObject(Management.InsertProductReleaseRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/products/\\{productId\\}/releases\nInserts a new product release.\nWhen requiresMaintenance is omitted, the release requires active maintenance (true). Set it to false explicitly for a release that must be available without maintenance. For an application product, the service rejects requiresMaintenance=false unless Updates:AllowPublicApplicationReleases is enabled in the service configuration.\nBody parameter\n{\n  \"release\": {\n    \"id\": 0,\n    \"releaseDate\": \"2019-08-24T14:15:22Z\",\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"description\": \"string\",\n    \"public\": true,\n    \"requiresMaintenance\": true,\n    \"releaseNotes\": \"string\",\n    \"channel\": \"stable\"\n  }\n}\nParameters"},{"page":221,"heading":"POST /v1/products/{productId}/releases","anchor":"post-v1productsproductidreleases","text":"Name | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nbody | body | Management.InsertProductReleaseRequest | false | The request containing the product release to insert.\nExample responses\n200 Response\n{\"releaseId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"releaseId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertProductReleaseResponse\nAuthentication: API key (x-api-key)."},{"page":221,"heading":"PUT /v1/products/{productId}/releases","anchor":"put-v1productsproductidreleases","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/products/{productId}/releases \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"release\": {\n    \"id\": 0,\n    \"releaseDate\": \"2019-08-24T14:15:22Z\",\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"description\": \"string\",\n    \"public\": true,\n    \"requiresMaintenance\": true,\n    \"releaseNotes\": \"string\",\n    \"channel\": \"stable\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":221,"heading":"PUT /v1/products/{productId}/releases","anchor":"put-v1productsproductidreleases","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/products/{productId}/releases\";\n\n      \n      string json = @\"{\n  \"\"release\"\": {\n    \"\"id\"\": 0,\n    \"\"releaseDate\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"name\"\": \"\"string\"\",\n    \"\"version\"\": \"\"string\"\",\n    \"\"description\"\": \"\"string\"\",\n    \"\"public\"\": true,\n    \"\"requiresMaintenance\"\": true,\n    \"\"releaseNotes\"\": \"\"string\"\",\n    \"\"channel\"\": \"\"stable\"\"\n  }\n}\";\n      Management.UpdateProductReleaseRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateProductReleaseRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response"},{"page":221,"heading":"PUT /v1/products/{productId}/releases","anchor":"put-v1productsproductidreleases","text":"        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateProductReleaseRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/products/\\{productId\\}/releases\nUpdates an existing product release.\nFields omitted from the body keep their stored values; see Updating Resources.\nBody parameter\n{\n  \"release\": {\n    \"id\": 0,\n    \"releaseDate\": \"2019-08-24T14:15:22Z\",\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"description\": \"string\",\n    \"public\": true,\n    \"requiresMaintenance\": true,\n    \"releaseNotes\": \"string\",\n    \"channel\": \"stable\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nbody | body | Management.UpdateProductReleaseRequest | false | The request containing the product release to update.\nExample responses\n200 Response"},{"page":221,"heading":"PUT /v1/products/{productId}/releases","anchor":"put-v1productsproductidreleases","text":"{\"releaseId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"releaseId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateProductReleaseResponse\nAuthentication: API key (x-api-key)."},{"page":221,"heading":"DELETE /v1/products/{productId}/releases/{releaseId}","anchor":"delete-v1productsproductidreleasesreleaseid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/products/{productId}/releases/{releaseId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":221,"heading":"DELETE /v1/products/{productId}/releases/{releaseId}","anchor":"delete-v1productsproductidreleasesreleaseid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/products/{productId}/releases/{releaseId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/products/\\{productId\\}/releases/\\{releaseId\\}\nDeletes an existing product release.\nParameters"},{"page":221,"heading":"DELETE /v1/products/{productId}/releases/{releaseId}","anchor":"delete-v1productsproductidreleasesreleaseid","text":"Name | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteProductReleaseResponse\nAuthentication: API key (x-api-key)."},{"page":222,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":222,"heading":"GET /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"get-v1productsproductidreleasesreleaseidassemblies","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/products/{productId}/releases/{releaseId}/assemblies \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/assemblies',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":222,"heading":"GET /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"get-v1productsproductidreleasesreleaseidassemblies","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/products/{productId}/releases/{releaseId}/assemblies\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/products/\\{productId\\}/releases/\\{releaseId\\}/assemblies\nGets the assemblies of a product release.\nParameters"},{"page":222,"heading":"GET /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"get-v1productsproductidreleasesreleaseidassemblies","text":"Name | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"totalAssembliesCount\":0}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"assemblies\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"culture\": \"string\",\n      \"publicKeyToken\": \"string\",\n      \"mappingFileId\": 0,\n      \"debugSymbolsKey\": \"string\"\n    }\n  ],\n  \"totalAssembliesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetProductReleaseAssembliesResponse\nAuthentication: API key (x-api-key)."},{"page":222,"heading":"POST /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"post-v1productsproductidreleasesreleaseidassemblies","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/products/{productId}/releases/{releaseId}/assemblies \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"productId\": 0,\n  \"releaseId\": 0,\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/assemblies',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":222,"heading":"POST /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"post-v1productsproductidreleasesreleaseidassemblies","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/products/{productId}/releases/{releaseId}/assemblies\";\n      \n      string json = @\"{\n  \"\"productId\"\": 0,\n  \"\"releaseId\"\": 0,\n  \"\"assembly\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"version\"\": \"\"string\"\",\n    \"\"culture\"\": \"\"string\"\",\n    \"\"publicKeyToken\"\": \"\"string\"\",\n    \"\"mappingFileId\"\": 0,\n    \"\"debugSymbolsKey\"\": \"\"string\"\"\n  }\n}\";\n      Management.InsertProductReleaseAssemblyRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.InsertProductReleaseAssemblyRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json"},{"page":222,"heading":"POST /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"post-v1productsproductidreleasesreleaseidassemblies","text":"    private StringContent SerializeObject(Management.InsertProductReleaseAssemblyRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/products/\\{productId\\}/releases/\\{releaseId\\}/assemblies\nInserts a new assembly for a product release.\nBody parameter\n{\n  \"productId\": 0,\n  \"releaseId\": 0,\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nbody | body | Management.InsertProductReleaseAssemblyRequest | false | The request containing the product release assembly to insert.\nExample responses\n200 Response\n{\"assemblyId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"assemblyId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}"},{"page":222,"heading":"POST /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"post-v1productsproductidreleasesreleaseidassemblies","text":"Responses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.InsertProductReleaseAssemblyResponse\nAuthentication: API key (x-api-key)."},{"page":222,"heading":"PUT /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"put-v1productsproductidreleasesreleaseidassemblies","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/products/{productId}/releases/{releaseId}/assemblies \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/assemblies',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":222,"heading":"PUT /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"put-v1productsproductidreleasesreleaseidassemblies","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/products/{productId}/releases/{releaseId}/assemblies\";\n\n      \n      string json = @\"{\n  \"\"assembly\"\": {\n    \"\"id\"\": 0,\n    \"\"name\"\": \"\"string\"\",\n    \"\"version\"\": \"\"string\"\",\n    \"\"culture\"\": \"\"string\"\",\n    \"\"publicKeyToken\"\": \"\"string\"\",\n    \"\"mappingFileId\"\": 0,\n    \"\"debugSymbolsKey\"\": \"\"string\"\"\n  }\n}\";\n      Management.UpdateProductReleaseAssemblyRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateProductReleaseAssemblyRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    "},{"page":222,"heading":"PUT /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"put-v1productsproductidreleasesreleaseidassemblies","text":"    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateProductReleaseAssemblyRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/products/\\{productId\\}/releases/\\{releaseId\\}/assemblies\nUpdates an existing assembly for a product release.\nBody parameter\n{\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nbody | body | Management.UpdateProductReleaseAssemblyRequest | false | The request containing the product release assembly to update.\nExample responses\n200 Response\n{\"assemblyId\":0,\"success\":true,\"code\":0,\"message\":\"string\"}"},{"page":222,"heading":"PUT /v1/products/{productId}/releases/{releaseId}/assemblies","anchor":"put-v1productsproductidreleasesreleaseidassemblies","text":"{\n  \"assemblyId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateProductReleaseAssemblyResponse\nAuthentication: API key (x-api-key)."},{"page":222,"heading":"DELETE /v1/products/{productId}/releases/{releaseId}/assemblies/{assemblyId}","anchor":"delete-v1productsproductidreleasesreleaseidassembliesassemblyid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/products/{productId}/releases/{releaseId}/assemblies/{assemblyId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/assemblies/{assemblyId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":222,"heading":"DELETE /v1/products/{productId}/releases/{releaseId}/assemblies/{assemblyId}","anchor":"delete-v1productsproductidreleasesreleaseidassembliesassemblyid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/products/{productId}/releases/{releaseId}/assemblies/{assemblyId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/products/\\{productId\\}/releases/\\{releaseId\\}/assemblies/\\{assemblyId\\}\nDeletes an existing assembly for a product release.\nParameters"},{"page":222,"heading":"DELETE /v1/products/{productId}/releases/{releaseId}/assemblies/{assemblyId}","anchor":"delete-v1productsproductidreleasesreleaseidassembliesassemblyid","text":"Name | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nassemblyId | path | integer(int32) | true | The assembly ID.\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteProductReleaseAssemblyResponse\nAuthentication: API key (x-api-key)."},{"page":223,"heading":"GET /v1/products/{productId}/releases/{releaseId}/license-templates","anchor":"get-v1productsproductidreleasesreleaseidlicense-templates","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/products/{productId}/releases/{releaseId}/license-templates \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/license-templates',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":223,"heading":"GET /v1/products/{productId}/releases/{releaseId}/license-templates","anchor":"get-v1productsproductidreleasesreleaseidlicense-templates","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/products/{productId}/releases/{releaseId}/license-templates\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/products/\\{productId\\}/releases/\\{releaseId\\}/license-templates\nGets the license templates of a product release.\nParameters"},{"page":223,"heading":"GET /v1/products/{productId}/releases/{releaseId}/license-templates","anchor":"get-v1productsproductidreleasesreleaseidlicense-templates","text":"Name | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"success\":true,\"code\":0,\"message\":\"string\",\"licenseTemplates\":[{\"id\":0,\"name\":\"string\",\"code\":\"string\",\"licenseType\":\"string\",\"format\":0,\"licensingMode\":0,\"licenseFileName\":\"string\",\"issueDate\":true,\"expireDays\":0,\"supportDays\":0,\"generateKeyInfo\":true,\"userKey\":\"string\",\"description\":\"string\",\"template\":\"string\",\"productId\":0,\"signatureKeysId\":0,\"releaseId\":0,\"product\":{\"id\":\"string\",\"name\":\"string\",\"version\":\"string\",\"copyright\":\"string\",\"url\":\"string\",\"description\":\"string\"},\"components\":[\"string\"],\"assemblies\":[{\"id\":0,\"name\":\"string\",\"version\":\"string\",\"culture\":\"string\",\"publicKeyToken\":\"string\",\"mappingFileId\":0,\"debugSymbolsKey\":\"string\"}],\"fields\":[{\"name\":\"string\",\"value\":\"string\"}],\"features\":[{\"id\":\"string\",\"name\":\"string\",\"description\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"key\":\"string\",\"data\":\"string\"}],\"restrictions\":[{\"id\":\"string\",\"name\":\"string\",\"expireDate\":\"2019-08-24T14:15:22Z\",\"properties\":{\"property1\":\"string\",\"property2\":\"string\"},\"customXmlContent\":\"string\"}]}],\"totalLicenseTemplatesCount\":0}"},{"page":223,"heading":"GET /v1/products/{productId}/releases/{releaseId}/license-templates","anchor":"get-v1productsproductidreleasesreleaseidlicense-templates","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseTemplates\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\","},{"page":223,"heading":"GET /v1/products/{productId}/releases/{releaseId}/license-templates","anchor":"get-v1productsproductidreleasesreleaseidlicense-templates","text":"          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicenseTemplatesCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetProductReleaseLicenseTemplatesResponse\nAuthentication: API key (x-api-key)."},{"page":224,"heading":"","anchor":"","text":"Info: All PUT endpoints update only the fields present in the body; see Updating Resources."},{"page":224,"heading":"GET /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"get-v1productsproductidreleasesreleaseiddownloads","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/products/{productId}/releases/{releaseId}/downloads \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/downloads',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":224,"heading":"GET /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"get-v1productsproductidreleasesreleaseiddownloads","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/products/{productId}/releases/{releaseId}/downloads\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/products/\\{productId\\}/releases/\\{releaseId\\}/downloads\nGets the downloadable artifacts registered for a product release.\nParameters"},{"page":224,"heading":"GET /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"get-v1productsproductidreleasesreleaseiddownloads","text":"Name | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nfilter | query | string | false | The filter to apply to the release downloads.\nsort | query | string | false | The sort order of the release downloads.\ntake | query | integer(int32) | false | The number of release downloads to take.\nskip | query | integer(int32) | false | The number of release downloads to skip.\nExample responses\n200 Response\n{\"success\":true,\"releaseDownloads\":[{\"id\":0,\"platform\":\"string\",\"kind\":\"string\",\"fileName\":\"string\",\"sourceKind\":\"string\",\"url\":\"string\",\"size\":0,\"sha256\":\"string\",\"sha512\":\"string\",\"signature\":\"string\",\"signatureKeyId\":\"string\",\"downloads\":0,\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\"}],\"totalReleaseDownloadsCount\":0}\n{\n  \"success\": true,\n  \"releaseDownloads\": [\n    {\n      \"id\": 0,\n      \"platform\": \"string\",\n      \"kind\": \"string\",\n      \"fileName\": \"string\",\n      \"sourceKind\": \"string\",\n      \"url\": \"string\",\n      \"size\": 0,\n      \"sha256\": \"string\",\n      \"sha512\": \"string\",\n      \"signature\": \"string\",\n      \"signatureKeyId\": \"string\",\n      \"downloads\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\"\n    }\n  ],\n  \"totalReleaseDownloadsCount\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.GetReleaseDownloadsResponse\nAuthentication: API key (x-api-key)."},{"page":224,"heading":"POST /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"post-v1productsproductidreleasesreleaseiddownloads","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/products/{productId}/releases/{releaseId}/downloads \\\n  -H 'Content-Type: application/json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"releaseDownload\": {\n    \"id\": 0,\n    \"platform\": \"string\",\n    \"kind\": \"string\",\n    \"fileName\": \"string\",\n    \"sourceKind\": \"string\",\n    \"url\": \"string\",\n    \"size\": 0,\n    \"sha256\": \"string\",\n    \"sha512\": \"string\",\n    \"signature\": \"string\",\n    \"signatureKeyId\": \"string\",\n    \"downloads\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/downloads',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":224,"heading":"POST /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"post-v1productsproductidreleasesreleaseiddownloads","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/products/{productId}/releases/{releaseId}/downloads\";\n      \n      string json = @\"{\n  \"\"releaseDownload\"\": {\n    \"\"id\"\": 0,\n    \"\"platform\"\": \"\"string\"\",\n    \"\"kind\"\": \"\"string\"\",\n    \"\"fileName\"\": \"\"string\"\",\n    \"\"sourceKind\"\": \"\"string\"\",\n    \"\"url\"\": \"\"string\"\",\n    \"\"size\"\": 0,\n    \"\"sha256\"\": \"\"string\"\",\n    \"\"sha512\"\": \"\"string\"\",\n    \"\"signature\"\": \"\"string\"\",\n    \"\"signatureKeyId\"\": \"\"string\"\",\n    \"\"downloads\"\": 0,\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\"\n  }\n}\";\n      Licensing.InsertReleaseDownloadRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Licensing.InsertReleaseDownloadRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request"},{"page":224,"heading":"POST /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"post-v1productsproductidreleasesreleaseiddownloads","text":"        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.InsertReleaseDownloadRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/products/\\{productId\\}/releases/\\{releaseId\\}/downloads\nRegisters a new downloadable artifact for a product release from an\nexternally-hosted https:// URL, using the publisher-supplied size and\nhashes (they cannot be computed server-side since the bytes are never uploaded).\nThe same route also accepts a multipart/form-data upload of the artifact itself, with\nthe form fields platform, kind, sourceKind (local, the default, or\nresource), an optional fileName and the file part: the service then computes\nsize, SHA-256 and SHA-512 server-side.\nBody parameter"},{"page":224,"heading":"POST /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"post-v1productsproductidreleasesreleaseiddownloads","text":"{\n  \"releaseDownload\": {\n    \"id\": 0,\n    \"platform\": \"string\",\n    \"kind\": \"string\",\n    \"fileName\": \"string\",\n    \"sourceKind\": \"string\",\n    \"url\": \"string\",\n    \"size\": 0,\n    \"sha256\": \"string\",\n    \"sha512\": \"string\",\n    \"signature\": \"string\",\n    \"signatureKeyId\": \"string\",\n    \"downloads\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\"\n  }\n}\nreleaseDownload:\n  id: 0\n  platform: string\n  kind: string\n  fileName: string\n  sourceKind: string\n  url: string\n  size: 0\n  sha256: string\n  sha512: string\n  signature: string\n  signatureKeyId: string\n  downloads: 0\n  createdAt: 2019-08-24T14:15:22Z\n  updatedAt: 2019-08-24T14:15:22Z\nParameters\nName | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nbody | body | Licensing.InsertReleaseDownloadRequest | false | The request containing the release download to register.\nExample responses\n201 Response\n{\"success\":true,\"id\":0,\"platform\":\"string\",\"kind\":\"string\",\"size\":0,\"sha256\":\"string\",\"sha512\":\"string\",\"message\":\"string\"}\n{\n  \"success\": true,\n  \"id\": 0,\n  \"platform\": \"string\",\n  \"kind\": \"string\",\n  \"size\": 0,\n  \"sha256\": \"string\",\n  \"sha512\": \"string\",\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n201 | Created | Created | Licensing.InsertReleaseDownloadResponse\nAuthentication: API key (x-api-key)."},{"page":224,"heading":"PUT /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"put-v1productsproductidreleasesreleaseiddownloads","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/products/{productId}/releases/{releaseId}/downloads \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"releaseDownload\": {\n    \"id\": 0,\n    \"platform\": \"string\",\n    \"kind\": \"string\",\n    \"fileName\": \"string\",\n    \"sourceKind\": \"string\",\n    \"url\": \"string\",\n    \"size\": 0,\n    \"sha256\": \"string\",\n    \"sha512\": \"string\",\n    \"signature\": \"string\",\n    \"signatureKeyId\": \"string\",\n    \"downloads\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\"\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/downloads',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":224,"heading":"PUT /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"put-v1productsproductidreleasesreleaseiddownloads","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/products/{productId}/releases/{releaseId}/downloads\";\n\n      \n      string json = @\"{\n  \"\"releaseDownload\"\": {\n    \"\"id\"\": 0,\n    \"\"platform\"\": \"\"string\"\",\n    \"\"kind\"\": \"\"string\"\",\n    \"\"fileName\"\": \"\"string\"\",\n    \"\"sourceKind\"\": \"\"string\"\",\n    \"\"url\"\": \"\"string\"\",\n    \"\"size\"\": 0,\n    \"\"sha256\"\": \"\"string\"\",\n    \"\"sha512\"\": \"\"string\"\",\n    \"\"signature\"\": \"\"string\"\",\n    \"\"signatureKeyId\"\": \"\"string\"\",\n    \"\"downloads\"\": 0,\n    \"\"createdAt\"\": \"\"2019-08-24T14:15:22Z\"\",\n    \"\"updatedAt\"\": \"\"2019-08-24T14:15:22Z\"\"\n  }\n}\";\n      Licensing.UpdateReleaseDownloadRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Licensing.UpdateReleaseDownloadRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n"},{"page":224,"heading":"PUT /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"put-v1productsproductidreleasesreleaseiddownloads","text":"        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response\n        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.UpdateReleaseDownloadRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/products/\\{productId\\}/releases/\\{releaseId\\}/downloads\nUpdates the metadata of an existing release download (platform, kind, file name,\nsignature, or the target URL of a url-sourced artifact). Size and hashes are never\nupdated this way - re-upload or re-register the artifact instead.\nBody parameter"},{"page":224,"heading":"PUT /v1/products/{productId}/releases/{releaseId}/downloads","anchor":"put-v1productsproductidreleasesreleaseiddownloads","text":"{\n  \"releaseDownload\": {\n    \"id\": 0,\n    \"platform\": \"string\",\n    \"kind\": \"string\",\n    \"fileName\": \"string\",\n    \"sourceKind\": \"string\",\n    \"url\": \"string\",\n    \"size\": 0,\n    \"sha256\": \"string\",\n    \"sha512\": \"string\",\n    \"signature\": \"string\",\n    \"signatureKeyId\": \"string\",\n    \"downloads\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\"\n  }\n}\nParameters\nName | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nbody | body | Licensing.UpdateReleaseDownloadRequest | false | The request containing the release download to update.\nExample responses\n200 Response\n{\"success\":true,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.UpdateReleaseDownloadResponse\nAuthentication: API key (x-api-key)."},{"page":224,"heading":"DELETE /v1/products/{productId}/releases/{releaseId}/downloads/{downloadId}","anchor":"delete-v1productsproductidreleasesreleaseiddownloadsdownloadid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/products/{productId}/releases/{releaseId}/downloads/{downloadId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/downloads/{downloadId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":224,"heading":"DELETE /v1/products/{productId}/releases/{releaseId}/downloads/{downloadId}","anchor":"delete-v1productsproductidreleasesreleaseiddownloadsdownloadid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/products/{productId}/releases/{releaseId}/downloads/{downloadId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/products/\\{productId\\}/releases/\\{releaseId\\}/downloads/\\{downloadId\\}"},{"page":224,"heading":"DELETE /v1/products/{productId}/releases/{releaseId}/downloads/{downloadId}","anchor":"delete-v1productsproductidreleasesreleaseiddownloadsdownloadid","text":"Deletes a release download. A resource-sourced artifact's\nResource row is deleted along with it, but a local-sourced artifact's\nfile is deliberately left on disk under the download root - this service never deletes\nfrom the download root, so an admin who deletes the wrong row by mistake (or one whose\nbytes are still referenced by an older feed/cache) does not lose the file. A\nurl-sourced artifact has nothing local to clean up either way.\nParameters\nName | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\ndownloadId | path | integer(int32) | true | The release download ID.\nExample responses\n200 Response\n{\"success\":true,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.DeleteReleaseDownloadResponse\nAuthentication: API key (x-api-key)."},{"page":224,"heading":"POST /v1/products/{productId}/releases/{releaseId}/downloads/verify","anchor":"post-v1productsproductidreleasesreleaseiddownloadsverify","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/products/{productId}/releases/{releaseId}/downloads/verify \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/products/{productId}/releases/{releaseId}/downloads/verify',\n{\n  method: 'POST',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":224,"heading":"POST /v1/products/{productId}/releases/{releaseId}/downloads/verify","anchor":"post-v1productsproductidreleasesreleaseiddownloadsverify","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/products/{productId}/releases/{releaseId}/downloads/verify\";\n      \n      \n      await PostAsync(null, url);\n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(undefined content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(undefined content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body "},{"page":224,"heading":"POST /v1/products/{productId}/releases/{releaseId}/downloads/verify","anchor":"post-v1productsproductidreleasesreleaseiddownloadsverify","text":"        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/products/\\{productId\\}/releases/\\{releaseId\\}/downloads/verify\nRecomputes the hashes of every local or resource-backed artifact of a release and\ncompares them against what is stored, reporting any that no longer match (missing\nfile, missing resource, or a hash mismatch) without touching url-sourced artifacts,\nwhich have no local bytes to re-check.\nParameters\nName | In | Type | Required | Description\nproductId | path | integer(int32) | true | The product ID.\nreleaseId | path | integer(int32) | true | The release ID.\nExample responses\n200 Response\n{\"success\":true,\"verified\":0,\"drifted\":[0]}\n{\n  \"success\": true,\n  \"verified\": 0,\n  \"drifted\": [\n    0\n  ]\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.VerifyReleaseDownloadsResponse\nAuthentication: API key (x-api-key)."},{"page":225,"heading":"POST /v1/report","anchor":"post-v1report","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/report \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain'\nJavaScript\nconst inputBody = '{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\",\n  \"report\": {\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"date\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"encrypted\": true,\n    \"content\": [\n      0\n    ]\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain'\n};\n\nfetch('/v1/report',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":225,"heading":"POST /v1/report","anchor":"post-v1report","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/report\";\n      \n      string json = @\"{\n  \"\"userKey\"\": \"\"string\"\",\n  \"\"machineId\"\": \"\"string\"\",\n  \"\"clientId\"\": \"\"string\"\",\n  \"\"clientName\"\": \"\"string\"\",\n  \"\"report\"\": {\n    \"\"name\"\": \"\"string\"\",\n    \"\"version\"\": \"\"string\"\",\n    \"\"date\"\": {\n      \"\"seconds\"\": 0,\n      \"\"nanos\"\": 0\n    },\n    \"\"encrypted\"\": true,\n    \"\"content\"\": [\n      0\n    ]\n  }\n}\";\n      Licensing.SendReportRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Licensing.SendReportRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Licensing.SendReportRequest content)"},{"page":225,"heading":"POST /v1/report","anchor":"post-v1report","text":"    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/report\nBody parameter\n{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\",\n  \"report\": {\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"date\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"encrypted\": true,\n    \"content\": [\n      0\n    ]\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Licensing.SendReportRequest | false | none\nExample responses\n200 Response\n{\"success\":true,\"reportUid\":\"string\"}\n{\n  \"success\": true,\n  \"reportUid\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Licensing.SendReportResponse\nAuthentication: Bearer token or API key (x-api-key)."},{"page":226,"heading":"","anchor":"","text":"These routes serve the updates of application products to the applications themselves. They are anonymous. An application that has a license identifies it with its user key, preferably in the X-Babel-User-Key header, or in the userKey query parameter; the header keeps the key out of access logs. What a caller is offered depends on that license.\nUpdate check\nGET /v1/updates/{productCode}?platform=win-x64&version=2.0.0&channel=stable returns the latest release for the platform and channel and whether the caller may install it. platform is one of win-x64, win-arm64, darwin-arm64, darwin-x64, linux-x64, linux-arm64; version is the caller's current major.minor.patch version; channel is stable (default) or insider.\n{\n  \"success\": true,\n  \"data\": {\n    \"format\": 2,\n    \"product\": { \"code\": \"acme-app\", \"name\": \"Acme App\" },\n    \"channel\": \"stable\",\n    \"platform\": \"win-x64\",\n    \"current\": \"2.0.0\",\n    \"latest\": \"2.1.0\",\n    \"release\": { \"version\": \"2.1.0\", \"publishedAt\": \"2026-09-01T00:00:00Z\", \"name\": \"Acme App 2.1.0\" },\n    \"updateAvailable\": true,\n    \"installable\": false,\n    \"withheldReason\": \"licenseRequired\",\n    \"purchaseUrl\": \"https://www.babelfor.net/shop\"\n  },\n  \"signature\": \"<base64>\",\n  \"keyId\": \"ext-2026-09\"\n}\ndata is signed with ECDSA P-256 (ES256). Get the public key for keyId from GET /v1/extensions/keys and verify signature against the canonical JSON of data before trusting it."},{"page":226,"heading":"","anchor":"","text":"When the latest release is installable and newer than version, data.download holds the file name, kind, size, hashes and url of the primary artifact. Otherwise withheldReason says why:\nwithheldReason | Meaning\nlicenseRequired | The release requires maintenance and the caller sent no user key, or one that matches no license. purchaseUrl is included\nmaintenanceExpired | The license's maintenance ended before the release date. latestInstallable names the newest release the license can still install, if one is newer than version\nplatformRequiresLicense | The platform is limited to some editions and the caller sent no user key, or one that matches no license\nplatformRequiresEdition | The license edition is not entitled to the platform. requiredEdition names one that is\nWith a valid user key the answer also has a maintenance object with until, expired, expiresInDays, noticeDays, renewalUrl, supportEmail, licenseId and licensee, when the service knows them.\nMaintenance and platform rules"},{"page":226,"heading":"","anchor":"","text":"A license's maintenance ends on its support expiration date or, when it has none, one year after its issue date. A release that requires maintenance is installable when its release date is on or before that day. A release with requiresMaintenance: false is installable by anyone.\nUpdates:PlatformEditions limits a platform family to some license editions. By default Windows is open to every edition, and macOS and Linux require Ultimate. Updates:EnforcePlatformEditions turns the rule off.\nDemo licenses are exempt from both rules.\nOn the update check and the feed files, a revoked or expired license gets 403 with the message License revoked or expired. The download route refuses it with the same message as a bad token, and applies the platform rule as well.\nFeed files and downloads\nApplications built with electron-updater use the generic provider with the feed directory /v1/updates/{productCode}/feed/{channel}/{platform}/. electron-updater appends latest.yml (Windows), latest-mac.yml (macOS) or latest-linux.yml (Linux). /v1/updates/{productCode}/latest.yml, latest-mac.yml and latest-linux.yml are shortcuts that default to win-x64, darwin-arm64 and linux-x64. A feed lists the highest release the caller may install and answers 204 when there is none."},{"page":226,"heading":"","anchor":"","text":"Download URLs have the form /v1/updates/{productCode}/download/{platform}/{version}/{fileName}. For a release that requires maintenance, the URL returned to a caller with a user key carries a token query parameter. The token is valid for one artifact, expires after Extensions:TokenLifetimeMinutes (10 minutes by default) and is used up by the first download; the same token can resume that download with range requests until it expires. A missing, expired or used token gets 403 with Download token invalid, expired or already used. Uploaded artifacts are served with X-Babel-Sha256 and X-Babel-Sha512 headers; hosted ones redirect with 302 to their URL."},{"page":226,"heading":"Pages","anchor":"pages","text":"Update Check: The signed JSON update check.\nFeeds and Downloads: electron-updater feed files and artifact downloads.\nExtension Keys: The public keys that sign the feed."},{"page":226,"heading":"Endpoints","anchor":"endpoints","text":"Endpoint | Page\nGET /v1/updates/{productCode} | Update Check\nGET /v1/updates/{productCode}/feed/{channel}/{platform}/{file} | Feeds and Downloads\nGET /v1/updates/{productCode}/latest.yml | Feeds and Downloads\nGET /v1/updates/{productCode}/latest-mac.yml | Feeds and Downloads\nGET /v1/updates/{productCode}/latest-linux.yml | Feeds and Downloads\nGET /v1/updates/{productCode}/download/{platform}/{version}/{fileName} | Feeds and Downloads\nHEAD /v1/updates/{productCode}/download/{platform}/{version}/{fileName} | Feeds and Downloads\nGET /v1/extensions/keys | Extension Keys"},{"page":227,"heading":"GET /v1/updates/{productCode}","anchor":"get-v1updatesproductcode","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/updates/{productCode}\nJavaScript\nfetch('/v1/updates/{productCode}',\n{\n  method: 'GET'\n\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#\nusing System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/updates/{productCode}\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/updates/\\{productCode\\}"},{"page":227,"heading":"GET /v1/updates/{productCode}","anchor":"get-v1updatesproductcode","text":"Answers the update check for one application product: what the latest release is,\nwhether this caller may install it, why not when it may not, and where to download\nit from. The data object is signed with the feed key so the desktop can\nverify it was not tampered with in transit.\nParameters\nName | In | Type | Required | Description\nproductCode | path | string | true | The application product's code (e.g. babel-desktop).\nplatform | query | string | false | The caller's platform, one of the recognised platform ids.\nversion | query | string | false | The caller's current version (strict semver).\nchannel | query | string | false | The release channel: stable (default) or insider.\nuserKey | query | string | false | The license user key, when the header is not used.\nmachineId | query | string | false | An optional machine id, echoed into any issued token.\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | None\n403 | Forbidden | Forbidden | None\n404 | Not Found | Not Found | None\nAuthentication: none, the endpoint is anonymous."},{"page":228,"heading":"GET /v1/updates/{productCode}/feed/{channel}/{platform}/{file}","anchor":"get-v1updatesproductcodefeedchannelplatformfile","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/updates/{productCode}/feed/{channel}/{platform}/{file}\nJavaScript\nfetch('/v1/updates/{productCode}/feed/{channel}/{platform}/{file}',\n{\n  method: 'GET'\n\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":228,"heading":"GET /v1/updates/{productCode}/feed/{channel}/{platform}/{file}","anchor":"get-v1updatesproductcodefeedchannelplatformfile","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/updates/{productCode}/feed/{channel}/{platform}/{file}\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/updates/\\{productCode\\}/feed/\\{channel\\}/\\{platform\\}/\\{file\\}"},{"page":228,"heading":"GET /v1/updates/{productCode}/feed/{channel}/{platform}/{file}","anchor":"get-v1updatesproductcodefeedchannelplatformfile","text":"Serves the electron-updater manifest for a product, channel and platform. This is\nthe canonical route: the desktop points the generic provider at the directory and\nelectron-updater appends the file name itself.\nParameters\nName | In | Type | Required | Description\nproductCode | path | string | true | The application product's code.\nchannel | path | string | true | The release channel.\nplatform | path | string | true | The platform the feed is served for.\nfile | path | string | true | latest.yml, latest-mac.yml or latest-linux.yml - it must be the\nuserKey | query | string | false | The license user key, when the header is not used.\nDetailed descriptions\nfile: latest.yml, latest-mac.yml or latest-linux.yml - it must be the\none this platform's family is served from.\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | None\n204 | No Content | No Content | None\n403 | Forbidden | Forbidden | None\n404 | Not Found | Not Found | None\nAuthentication: none, the endpoint is anonymous."},{"page":228,"heading":"GET /v1/updates/{productCode}/latest.yml","anchor":"get-v1updatesproductcodelatestyml","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/updates/{productCode}/latest.yml\nJavaScript\nfetch('/v1/updates/{productCode}/latest.yml',\n{\n  method: 'GET'\n\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#\nusing System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/updates/{productCode}/latest.yml\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}"},{"page":228,"heading":"GET /v1/updates/{productCode}/latest.yml","anchor":"get-v1updatesproductcodelatestyml","text":"GET /v1/updates/\\{productCode\\}/latest.yml\nConvenience alias for the Windows manifest; defaults to win-x64.\nParameters\nName | In | Type | Required | Description\nproductCode | path | string | true | The application product's code.\nchannel | query | string | false | The release channel; stable by default.\nplatform | query | string | false | The platform; win-x64 by default.\nuserKey | query | string | false | The license user key, when the header is not used.\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | None\n204 | No Content | No Content | None\n403 | Forbidden | Forbidden | None\n404 | Not Found | Not Found | None\nAuthentication: none, the endpoint is anonymous."},{"page":228,"heading":"GET /v1/updates/{productCode}/latest-mac.yml","anchor":"get-v1updatesproductcodelatest-macyml","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/updates/{productCode}/latest-mac.yml\nJavaScript\nfetch('/v1/updates/{productCode}/latest-mac.yml',\n{\n  method: 'GET'\n\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":228,"heading":"GET /v1/updates/{productCode}/latest-mac.yml","anchor":"get-v1updatesproductcodelatest-macyml","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/updates/{productCode}/latest-mac.yml\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/updates/\\{productCode\\}/latest-mac.yml\nConvenience alias for the macOS manifest; defaults to darwin-arm64.\nParameters"},{"page":228,"heading":"GET /v1/updates/{productCode}/latest-mac.yml","anchor":"get-v1updatesproductcodelatest-macyml","text":"Name | In | Type | Required | Description\nproductCode | path | string | true | The application product's code.\nchannel | query | string | false | The release channel; stable by default.\nplatform | query | string | false | The platform; darwin-arm64 by default.\nuserKey | query | string | false | The license user key, when the header is not used.\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | None\n204 | No Content | No Content | None\n403 | Forbidden | Forbidden | None\n404 | Not Found | Not Found | None\nAuthentication: none, the endpoint is anonymous."},{"page":228,"heading":"GET /v1/updates/{productCode}/latest-linux.yml","anchor":"get-v1updatesproductcodelatest-linuxyml","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/updates/{productCode}/latest-linux.yml\nJavaScript\nfetch('/v1/updates/{productCode}/latest-linux.yml',\n{\n  method: 'GET'\n\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":228,"heading":"GET /v1/updates/{productCode}/latest-linux.yml","anchor":"get-v1updatesproductcodelatest-linuxyml","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/updates/{productCode}/latest-linux.yml\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/updates/\\{productCode\\}/latest-linux.yml\nConvenience alias for the Linux manifest; defaults to linux-x64.\nParameters"},{"page":228,"heading":"GET /v1/updates/{productCode}/latest-linux.yml","anchor":"get-v1updatesproductcodelatest-linuxyml","text":"Name | In | Type | Required | Description\nproductCode | path | string | true | The application product's code.\nchannel | query | string | false | The release channel; stable by default.\nplatform | query | string | false | The platform; linux-x64 by default.\nuserKey | query | string | false | The license user key, when the header is not used.\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | None\n204 | No Content | No Content | None\n403 | Forbidden | Forbidden | None\n404 | Not Found | Not Found | None\nAuthentication: none, the endpoint is anonymous."},{"page":228,"heading":"GET /v1/updates/{productCode}/download/{platform}/{version}/{fileName}","anchor":"get-v1updatesproductcodedownloadplatformversionfilename","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/updates/{productCode}/download/{platform}/{version}/{fileName}\nJavaScript\nfetch('/v1/updates/{productCode}/download/{platform}/{version}/{fileName}',\n{\n  method: 'GET'\n\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":228,"heading":"GET /v1/updates/{productCode}/download/{platform}/{version}/{fileName}","anchor":"get-v1updatesproductcodedownloadplatformversionfilename","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/updates/{productCode}/download/{platform}/{version}/{fileName}\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/updates/\\{productCode\\}/download/\\{platform\\}/\\{version\\}/\\{fileName\\}"},{"page":228,"heading":"GET /v1/updates/{productCode}/download/{platform}/{version}/{fileName}","anchor":"get-v1updatesproductcodedownloadplatformversionfilename","text":"Serves one artifact of one release. The platform rule is applied first and is never\nbypassed by an ungated release; a release that requires maintenance additionally\nrequires a single-use download token (the same token may re-serve byte ranges of\nthe same artifact until it expires, so a resumed download does not need a new one).\nUngated releases are public and need no token.\nParameters\nName | In | Type | Required | Description\nproductCode | path | string | true | The application product's code.\nplatform | path | string | true | The artifact's platform.\nversion | path | string | true | The release version.\nfileName | path | string | true | The artifact's file name - the last path segment, because\ntoken | query | string | false | The single-use download token, for a gated release.\nkind | query | string | false | An optional artifact kind, when one file name is ambiguous.\nuserKey | query | string | false | The license user key, when the header is not used.\nchannel | query | string | false | The release channel the version is expected in; when omitted,\nDetailed descriptions\nfileName: The artifact's file name - the last path segment, because\nelectron-updater picks artifacts by the extension of the URL path.\nchannel: The release channel the version is expected in; when omitted,\na release of any channel of the product matches.\nResponses"},{"page":228,"heading":"GET /v1/updates/{productCode}/download/{platform}/{version}/{fileName}","anchor":"get-v1updatesproductcodedownloadplatformversionfilename","text":"Status | Meaning | Description | Schema\n200 | OK | OK | None\n206 | Partial Content | Partial Content | None\n302 | Found | Found | None\n403 | Forbidden | Forbidden | None\n404 | Not Found | Not Found | None\nAuthentication: none, the endpoint is anonymous."},{"page":228,"heading":"HEAD /v1/updates/{productCode}/download/{platform}/{version}/{fileName}","anchor":"head-v1updatesproductcodedownloadplatformversionfilename","text":"Code samples\ncURL\n# You can also use wget\ncurl -X HEAD /v1/updates/{productCode}/download/{platform}/{version}/{fileName}\nJavaScript\nfetch('/v1/updates/{productCode}/download/{platform}/{version}/{fileName}',\n{\n  method: 'HEAD'\n\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#\nusing System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nHEAD /v1/updates/\\{productCode\\}/download/\\{platform\\}/\\{version\\}/\\{fileName\\}"},{"page":228,"heading":"HEAD /v1/updates/{productCode}/download/{platform}/{version}/{fileName}","anchor":"head-v1updatesproductcodedownloadplatformversionfilename","text":"Serves one artifact of one release. The platform rule is applied first and is never\nbypassed by an ungated release; a release that requires maintenance additionally\nrequires a single-use download token (the same token may re-serve byte ranges of\nthe same artifact until it expires, so a resumed download does not need a new one).\nUngated releases are public and need no token.\nParameters\nName | In | Type | Required | Description\nproductCode | path | string | true | The application product's code.\nplatform | path | string | true | The artifact's platform.\nversion | path | string | true | The release version.\nfileName | path | string | true | The artifact's file name - the last path segment, because\ntoken | query | string | false | The single-use download token, for a gated release.\nkind | query | string | false | An optional artifact kind, when one file name is ambiguous.\nuserKey | query | string | false | The license user key, when the header is not used.\nchannel | query | string | false | The release channel the version is expected in; when omitted,\nDetailed descriptions\nfileName: The artifact's file name - the last path segment, because\nelectron-updater picks artifacts by the extension of the URL path.\nchannel: The release channel the version is expected in; when omitted,\na release of any channel of the product matches.\nResponses"},{"page":228,"heading":"HEAD /v1/updates/{productCode}/download/{platform}/{version}/{fileName}","anchor":"head-v1updatesproductcodedownloadplatformversionfilename","text":"Status | Meaning | Description | Schema\n200 | OK | OK | None\n206 | Partial Content | Partial Content | None\n302 | Found | Found | None\n403 | Forbidden | Forbidden | None\n404 | Not Found | Not Found | None\nAuthentication: none, the endpoint is anonymous."},{"page":229,"heading":"GET /v1/extensions/keys","anchor":"get-v1extensionskeys","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/extensions/keys\nJavaScript\nfetch('/v1/extensions/keys',\n{\n  method: 'GET'\n\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#\nusing System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/extensions/keys\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/extensions/keys"},{"page":229,"heading":"GET /v1/extensions/keys","anchor":"get-v1extensionskeys","text":"Gets the keys feed payloads are signed with. The service holds exactly one active\nkey; the list shape is what lets a future rotation publish the retiring key\nalongside the new one without a client change.\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | None\nAuthentication: none, the endpoint is anonymous."},{"page":230,"heading":"","anchor":"","text":"Webhook subscriptions, their delivery events, the available event types and the dispatcher status."},{"page":230,"heading":"Pages","anchor":"pages","text":"Subscriptions: Create, update, test and delete webhook subscriptions.\nEvents: Delivery events of a subscription.\nStatus and Event Types: Dispatcher status and the event types you can subscribe to."},{"page":230,"heading":"Endpoints","anchor":"endpoints","text":"Endpoint | Page\nGET /v1/webhooks/subscriptions | Subscriptions\nPOST /v1/webhooks/subscriptions | Subscriptions\nGET /v1/webhooks/subscriptions/{id} | Subscriptions\nPUT /v1/webhooks/subscriptions/{id} | Subscriptions\nDELETE /v1/webhooks/subscriptions/{id} | Subscriptions\nPOST /v1/webhooks/subscriptions/{id}/test | Subscriptions\nGET /v1/webhooks/subscriptions/{id}/events | Events\nDELETE /v1/webhooks/subscriptions/{id}/events/{eventId} | Events\nGET /v1/webhooks/status | Status and Event Types\nGET /v1/webhooks/event-types | Status and Event Types"},{"page":231,"heading":"GET /v1/webhooks/subscriptions","anchor":"get-v1webhookssubscriptions","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/webhooks/subscriptions \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/subscriptions',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":231,"heading":"GET /v1/webhooks/subscriptions","anchor":"get-v1webhookssubscriptions","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/webhooks/subscriptions\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/webhooks/subscriptions\nGets all webhook subscriptions.\nParameters"},{"page":231,"heading":"GET /v1/webhooks/subscriptions","anchor":"get-v1webhookssubscriptions","text":"Name | In | Type | Required | Description\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ninclude | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"subscriptions\":[{\"id\":0,\"name\":\"string\",\"eventType\":\"string\",\"url\":\"string\",\"secret\":\"string\",\"maxRetryCount\":0,\"isActive\":true,\"userId\":\"string\",\"headers\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"webhookEvents\":[{\"id\":0,\"webhookSubscriptionId\":0,\"eventType\":\"string\",\"payload\":\"string\",\"statusCode\":0,\"response\":\"string\",\"errorMessage\":\"string\",\"isSuccess\":true,\"retryCount\":0,\"sentAt\":\"2019-08-24T14:15:22Z\",\"nextRetryAt\":\"2019-08-24T14:15:22Z\",\"createdAt\":\"2019-08-24T14:15:22Z\"}]}],\"totalSubscriptionsCount\":0,\"success\":true,\"message\":\"string\"}"},{"page":231,"heading":"GET /v1/webhooks/subscriptions","anchor":"get-v1webhookssubscriptions","text":"{\n  \"subscriptions\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"eventType\": \"string\",\n      \"url\": \"string\",\n      \"secret\": \"string\",\n      \"maxRetryCount\": 0,\n      \"isActive\": true,\n      \"userId\": \"string\",\n      \"headers\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"webhookEvents\": [\n        {\n          \"id\": 0,\n          \"webhookSubscriptionId\": 0,\n          \"eventType\": \"string\",\n          \"payload\": \"string\",\n          \"statusCode\": 0,\n          \"response\": \"string\",\n          \"errorMessage\": \"string\",\n          \"isSuccess\": true,\n          \"retryCount\": 0,\n          \"sentAt\": \"2019-08-24T14:15:22Z\",\n          \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\"\n        }\n      ]\n    }\n  ],\n  \"totalSubscriptionsCount\": 0,\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetWebhookSubscriptionsResponse\nAuthentication: API key (x-api-key)."},{"page":231,"heading":"POST /v1/webhooks/subscriptions","anchor":"post-v1webhookssubscriptions","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/webhooks/subscriptions \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"subscription\": {\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"headers\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"maxRetryCount\": 0,\n    \"isActive\": true\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/subscriptions',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":231,"heading":"POST /v1/webhooks/subscriptions","anchor":"post-v1webhookssubscriptions","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/webhooks/subscriptions\";\n      \n      string json = @\"{\n  \"\"subscription\"\": {\n    \"\"name\"\": \"\"string\"\",\n    \"\"eventType\"\": \"\"string\"\",\n    \"\"url\"\": \"\"string\"\",\n    \"\"secret\"\": \"\"string\"\",\n    \"\"headers\"\": {\n      \"\"property1\"\": \"\"string\"\",\n      \"\"property2\"\": \"\"string\"\"\n    },\n    \"\"maxRetryCount\"\": 0,\n    \"\"isActive\"\": true\n  }\n}\";\n      Management.CreateWebhookSubscriptionRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.CreateWebhookSubscriptionRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json"},{"page":231,"heading":"POST /v1/webhooks/subscriptions","anchor":"post-v1webhookssubscriptions","text":"    private StringContent SerializeObject(Management.CreateWebhookSubscriptionRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/webhooks/subscriptions\nCreates a new webhook subscription.\nBody parameter\n{\n  \"subscription\": {\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"headers\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"maxRetryCount\": 0,\n    \"isActive\": true\n  }\n}\nParameters\nName | In | Type | Required | Description\nbody | body | Management.CreateWebhookSubscriptionRequest | false | The subscription details.\nExample responses\n200 Response"},{"page":231,"heading":"POST /v1/webhooks/subscriptions","anchor":"post-v1webhookssubscriptions","text":"{\"subscription\":{\"id\":0,\"name\":\"string\",\"eventType\":\"string\",\"url\":\"string\",\"secret\":\"string\",\"maxRetryCount\":0,\"isActive\":true,\"userId\":\"string\",\"headers\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"webhookEvents\":[{\"id\":0,\"webhookSubscriptionId\":0,\"eventType\":\"string\",\"payload\":\"string\",\"statusCode\":0,\"response\":\"string\",\"errorMessage\":\"string\",\"isSuccess\":true,\"retryCount\":0,\"sentAt\":\"2019-08-24T14:15:22Z\",\"nextRetryAt\":\"2019-08-24T14:15:22Z\",\"createdAt\":\"2019-08-24T14:15:22Z\"}]},\"success\":true,\"message\":\"string\"}\n{\n  \"subscription\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"maxRetryCount\": 0,\n    \"isActive\": true,\n    \"userId\": \"string\",\n    \"headers\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"webhookEvents\": [\n      {\n        \"id\": 0,\n        \"webhookSubscriptionId\": 0,\n        \"eventType\": \"string\",\n        \"payload\": \"string\",\n        \"statusCode\": 0,\n        \"response\": \"string\",\n        \"errorMessage\": \"string\",\n        \"isSuccess\": true,\n        \"retryCount\": 0,\n        \"sentAt\": \"2019-08-24T14:15:22Z\",\n        \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\"\n      }\n    ]\n  },\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.CreateWebhookSubscriptionResponse\nAuthentication: API key (x-api-key)."},{"page":231,"heading":"GET /v1/webhooks/subscriptions/{id}","anchor":"get-v1webhookssubscriptionsid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/webhooks/subscriptions/{id} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/subscriptions/{id}',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":231,"heading":"GET /v1/webhooks/subscriptions/{id}","anchor":"get-v1webhookssubscriptionsid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/webhooks/subscriptions/{id}\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/webhooks/subscriptions/\\{id\\}\nGets a webhook subscription by ID.\nParameters\nName | In | Type | Required | Description\nid | path | integer(int32) | true | The subscription ID.\nExample responses\n200 Response"},{"page":231,"heading":"GET /v1/webhooks/subscriptions/{id}","anchor":"get-v1webhookssubscriptionsid","text":"{\"subscription\":{\"id\":0,\"name\":\"string\",\"eventType\":\"string\",\"url\":\"string\",\"secret\":\"string\",\"maxRetryCount\":0,\"isActive\":true,\"userId\":\"string\",\"headers\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"webhookEvents\":[{\"id\":0,\"webhookSubscriptionId\":0,\"eventType\":\"string\",\"payload\":\"string\",\"statusCode\":0,\"response\":\"string\",\"errorMessage\":\"string\",\"isSuccess\":true,\"retryCount\":0,\"sentAt\":\"2019-08-24T14:15:22Z\",\"nextRetryAt\":\"2019-08-24T14:15:22Z\",\"createdAt\":\"2019-08-24T14:15:22Z\"}]},\"success\":true,\"message\":\"string\"}\n{\n  \"subscription\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"maxRetryCount\": 0,\n    \"isActive\": true,\n    \"userId\": \"string\",\n    \"headers\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"webhookEvents\": [\n      {\n        \"id\": 0,\n        \"webhookSubscriptionId\": 0,\n        \"eventType\": \"string\",\n        \"payload\": \"string\",\n        \"statusCode\": 0,\n        \"response\": \"string\",\n        \"errorMessage\": \"string\",\n        \"isSuccess\": true,\n        \"retryCount\": 0,\n        \"sentAt\": \"2019-08-24T14:15:22Z\",\n        \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\"\n      }\n    ]\n  },\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetWebhookSubscriptionResponse\nAuthentication: API key (x-api-key)."},{"page":231,"heading":"PUT /v1/webhooks/subscriptions/{id}","anchor":"put-v1webhookssubscriptionsid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X PUT /v1/webhooks/subscriptions/{id} \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"subscription\": {\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"headers\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"maxRetryCount\": 0,\n    \"isActive\": true\n  }\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/subscriptions/{id}',\n{\n  method: 'PUT',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":231,"heading":"PUT /v1/webhooks/subscriptions/{id}","anchor":"put-v1webhookssubscriptionsid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    /// Make a dummy request\n    public async Task MakePutRequest()\n    {\n      int id = 1;\n      string url = \"/v1/webhooks/subscriptions/{id}\";\n\n      \n      string json = @\"{\n  \"\"subscription\"\": {\n    \"\"name\"\": \"\"string\"\",\n    \"\"eventType\"\": \"\"string\"\",\n    \"\"url\"\": \"\"string\"\",\n    \"\"secret\"\": \"\"string\"\",\n    \"\"headers\"\": {\n      \"\"property1\"\": \"\"string\"\",\n      \"\"property2\"\": \"\"string\"\"\n    },\n    \"\"maxRetryCount\"\": 0,\n    \"\"isActive\"\": true\n  }\n}\";\n      Management.UpdateWebhookSubscriptionRequest content = JsonConvert.DeserializeObject(json);\n      var result = await PutAsync(id, content, url);\n      \n          \n    }\n\n    /// Performs a PUT Request\n    public async Task PutAsync(int id, Management.UpdateWebhookSubscriptionRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute PUT request\n        HttpResponseMessage response = await Client.PutAsync(url + $\"/{id}\", jsonContent);\n\n        //Return response"},{"page":231,"heading":"PUT /v1/webhooks/subscriptions/{id}","anchor":"put-v1webhookssubscriptionsid","text":"        return await DeserializeObject(response);\n    }\n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.UpdateWebhookSubscriptionRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPUT /v1/webhooks/subscriptions/\\{id\\}\nUpdates an existing webhook subscription.\nBody parameter\n{\n  \"subscription\": {\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"headers\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"maxRetryCount\": 0,\n    \"isActive\": true\n  }\n}\nParameters\nName | In | Type | Required | Description\nid | path | integer(int32) | true | The subscription ID.\nbody | body | Management.UpdateWebhookSubscriptionRequest | false | The updated subscription details.\nExample responses\n200 Response"},{"page":231,"heading":"PUT /v1/webhooks/subscriptions/{id}","anchor":"put-v1webhookssubscriptionsid","text":"{\"subscription\":{\"id\":0,\"name\":\"string\",\"eventType\":\"string\",\"url\":\"string\",\"secret\":\"string\",\"maxRetryCount\":0,\"isActive\":true,\"userId\":\"string\",\"headers\":\"string\",\"createdAt\":\"2019-08-24T14:15:22Z\",\"updatedAt\":\"2019-08-24T14:15:22Z\",\"webhookEvents\":[{\"id\":0,\"webhookSubscriptionId\":0,\"eventType\":\"string\",\"payload\":\"string\",\"statusCode\":0,\"response\":\"string\",\"errorMessage\":\"string\",\"isSuccess\":true,\"retryCount\":0,\"sentAt\":\"2019-08-24T14:15:22Z\",\"nextRetryAt\":\"2019-08-24T14:15:22Z\",\"createdAt\":\"2019-08-24T14:15:22Z\"}]},\"success\":true,\"message\":\"string\"}\n{\n  \"subscription\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"maxRetryCount\": 0,\n    \"isActive\": true,\n    \"userId\": \"string\",\n    \"headers\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"webhookEvents\": [\n      {\n        \"id\": 0,\n        \"webhookSubscriptionId\": 0,\n        \"eventType\": \"string\",\n        \"payload\": \"string\",\n        \"statusCode\": 0,\n        \"response\": \"string\",\n        \"errorMessage\": \"string\",\n        \"isSuccess\": true,\n        \"retryCount\": 0,\n        \"sentAt\": \"2019-08-24T14:15:22Z\",\n        \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\"\n      }\n    ]\n  },\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.UpdateWebhookSubscriptionResponse\nAuthentication: API key (x-api-key)."},{"page":231,"heading":"DELETE /v1/webhooks/subscriptions/{id}","anchor":"delete-v1webhookssubscriptionsid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/webhooks/subscriptions/{id} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/subscriptions/{id}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":231,"heading":"DELETE /v1/webhooks/subscriptions/{id}","anchor":"delete-v1webhookssubscriptionsid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/webhooks/subscriptions/{id}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/webhooks/subscriptions/\\{id\\}\nDeletes a webhook subscription.\nParameters\nName | In | Type | Required | Description\nid | path | integer(int32) | true | The subscription ID.\nExample responses\n200 Response"},{"page":231,"heading":"DELETE /v1/webhooks/subscriptions/{id}","anchor":"delete-v1webhookssubscriptionsid","text":"{\"success\":true,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteWebhookSubscriptionResponse\nAuthentication: API key (x-api-key)."},{"page":231,"heading":"POST /v1/webhooks/subscriptions/{id}/test","anchor":"post-v1webhookssubscriptionsidtest","text":"Code samples\ncURL\n# You can also use wget\ncurl -X POST /v1/webhooks/subscriptions/{id}/test \\\n  -H 'Content-Type: application/json-patch+json' \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst inputBody = '{\n  \"payload\": null\n}';\nconst headers = {\n  'Content-Type':'application/json-patch+json',\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/subscriptions/{id}/test',\n{\n  method: 'POST',\n  body: inputBody,\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":231,"heading":"POST /v1/webhooks/subscriptions/{id}/test","anchor":"post-v1webhookssubscriptionsidtest","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    /// Make a dummy request\n    public async Task MakePostRequest()\n    {\n      string url = \"/v1/webhooks/subscriptions/{id}/test\";\n      \n      string json = @\"{\n  \"\"payload\"\": null\n}\";\n      Management.SendWebhookTestEventRequest content = JsonConvert.DeserializeObject(json);\n      await PostAsync(content, url);\n      \n      \n    }\n\n    /// Performs a POST Request\n    public async Task PostAsync(Management.SendWebhookTestEventRequest content, string url)\n    {\n        //Serialize Object\n        StringContent jsonContent = SerializeObject(content);\n\n        //Execute POST request\n        HttpResponseMessage response = await Client.PostAsync(url, jsonContent);\n    }\n    \n    \n    \n    /// Serialize an object to Json\n    private StringContent SerializeObject(Management.SendWebhookTestEventRequest content)\n    {\n        //Serialize Object\n        string jsonObject = JsonConvert.SerializeObject(content);\n\n        //Create Json UTF8 String Content\n        return new StringContent(jsonObject, Encoding.UTF8, \"application/json\");\n    }\n    "},{"page":231,"heading":"POST /v1/webhooks/subscriptions/{id}/test","anchor":"post-v1webhookssubscriptionsidtest","text":"    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nPOST /v1/webhooks/subscriptions/\\{id\\}/test\nSends a test event for a specific webhook subscription.\nBody parameter\n{\n  \"payload\": null\n}\nParameters\nName | In | Type | Required | Description\nid | path | integer(int32) | true | The subscription ID.\nbody | body | Management.SendWebhookTestEventRequest | false | The request containing a custom payload to send (optional).\nExample responses\n200 Response\n{\"success\":true,\"message\":\"string\",\"eventId\":0}\n{\n  \"success\": true,\n  \"message\": \"string\",\n  \"eventId\": 0\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.SendWebhookTestEventResponse\nAuthentication: API key (x-api-key)."},{"page":232,"heading":"GET /v1/webhooks/subscriptions/{id}/events","anchor":"get-v1webhookssubscriptionsidevents","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/webhooks/subscriptions/{id}/events \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/subscriptions/{id}/events',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":232,"heading":"GET /v1/webhooks/subscriptions/{id}/events","anchor":"get-v1webhookssubscriptionsidevents","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/webhooks/subscriptions/{id}/events\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/webhooks/subscriptions/\\{id\\}/events\nGets all events for a specific webhook subscription.\nParameters"},{"page":232,"heading":"GET /v1/webhooks/subscriptions/{id}/events","anchor":"get-v1webhookssubscriptionsidevents","text":"Name | In | Type | Required | Description\nid | path | integer(int32) | true | The subscription ID.\nselect | query | string | false | none\nfilter | query | string | false | none\nsort | query | string | false | none\ninclude | query | string | false | none\ntake | query | integer(int32) | false | none\nskip | query | integer(int32) | false | none\nExample responses\n200 Response\n{\"events\":[{\"id\":0,\"webhookSubscriptionId\":0,\"eventType\":\"string\",\"payload\":\"string\",\"statusCode\":0,\"response\":\"string\",\"errorMessage\":\"string\",\"isSuccess\":true,\"retryCount\":0,\"sentAt\":\"2019-08-24T14:15:22Z\",\"nextRetryAt\":\"2019-08-24T14:15:22Z\",\"createdAt\":\"2019-08-24T14:15:22Z\"}],\"totalEventsCount\":0,\"success\":true,\"message\":\"string\"}\n{\n  \"events\": [\n    {\n      \"id\": 0,\n      \"webhookSubscriptionId\": 0,\n      \"eventType\": \"string\",\n      \"payload\": \"string\",\n      \"statusCode\": 0,\n      \"response\": \"string\",\n      \"errorMessage\": \"string\",\n      \"isSuccess\": true,\n      \"retryCount\": 0,\n      \"sentAt\": \"2019-08-24T14:15:22Z\",\n      \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\"\n    }\n  ],\n  \"totalEventsCount\": 0,\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetWebhookEventsResponse\nAuthentication: API key (x-api-key)."},{"page":232,"heading":"DELETE /v1/webhooks/subscriptions/{id}/events/{eventId}","anchor":"delete-v1webhookssubscriptionsideventseventid","text":"Code samples\ncURL\n# You can also use wget\ncurl -X DELETE /v1/webhooks/subscriptions/{id}/events/{eventId} \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/subscriptions/{id}/events/{eventId}',\n{\n  method: 'DELETE',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":232,"heading":"DELETE /v1/webhooks/subscriptions/{id}/events/{eventId}","anchor":"delete-v1webhookssubscriptionsideventseventid","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    \n    \n    \n    /// Make a dummy request\n    public async Task MakeDeleteRequest()\n    {\n      int id = 1;\n      string url = \"/v1/webhooks/subscriptions/{id}/events/{eventId}\";\n\n      await DeleteAsync(id, url);\n    }\n\n    /// Performs a DELETE Request\n    public async Task DeleteAsync(int id, string url)\n    {\n        //Execute DELETE request\n        HttpResponseMessage response = await Client.DeleteAsync(url + $\"/{id}\");\n\n        //Return response\n        await DeserializeObject(response);\n    }\n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nDELETE /v1/webhooks/subscriptions/\\{id\\}/events/\\{eventId\\}\nDeletes a webhook event.\nParameters"},{"page":232,"heading":"DELETE /v1/webhooks/subscriptions/{id}/events/{eventId}","anchor":"delete-v1webhookssubscriptionsideventseventid","text":"Name | In | Type | Required | Description\nid | path | integer(int32) | true | The subscription ID.\neventId | path | integer(int32) | true | The event ID.\nExample responses\n200 Response\n{\"success\":true,\"message\":\"string\"}\n{\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.DeleteWebhookEventResponse\nAuthentication: API key (x-api-key)."},{"page":233,"heading":"GET /v1/webhooks/status","anchor":"get-v1webhooksstatus","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/webhooks/status \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/status',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":233,"heading":"GET /v1/webhooks/status","anchor":"get-v1webhooksstatus","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/webhooks/status\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/webhooks/status\nGets the webhook system status.\nExample responses\n200 Response\n{\"isEnabled\":true,\"success\":true,\"message\":\"string\"}\n{\n  \"isEnabled\": true,\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses"},{"page":233,"heading":"GET /v1/webhooks/status","anchor":"get-v1webhooksstatus","text":"Status | Meaning | Description | Schema\n200 | OK | OK | Management.GetWebhookStatusResponse\nAuthentication: API key (x-api-key)."},{"page":233,"heading":"GET /v1/webhooks/event-types","anchor":"get-v1webhooksevent-types","text":"Code samples\ncURL\n# You can also use wget\ncurl -X GET /v1/webhooks/event-types \\\n  -H 'Accept: text/plain' \\\n  -H 'x-api-key: API_KEY'\nJavaScript\nconst headers = {\n  'Accept':'text/plain',\n  'x-api-key':'API_KEY'\n};\n\nfetch('/v1/webhooks/event-types',\n{\n  method: 'GET',\n\n  headers: headers\n})\n.then(function(res) {\n    return res.json();\n}).then(function(body) {\n    console.log(body);\n});\nC#"},{"page":233,"heading":"GET /v1/webhooks/event-types","anchor":"get-v1webhooksevent-types","text":"using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\n/// <summary>\n/// Example of Http Client\n/// </summary>\npublic class HttpExample\n{\n    private HttpClient Client { get; set; }\n\n    /// <summary>\n    /// Setup http client\n    /// </summary>\n    public HttpExample()\n    {\n      Client = new HttpClient();\n    }\n    \n    /// Make a dummy request\n    public async Task MakeGetRequest()\n    {\n      string url = \"/v1/webhooks/event-types\";\n      var result = await GetAsync(url);\n    }\n\n    /// Performs a GET Request\n    public async Task GetAsync(string url)\n    {\n        //Start the request\n        HttpResponseMessage response = await Client.GetAsync(url);\n\n        //Validate result\n        response.EnsureSuccessStatusCode();\n\n    }\n    \n    \n    \n    \n    /// Deserialize object from request response\n    private async Task DeserializeObject(HttpResponseMessage response)\n    {\n        //Read body \n        string responseBody = await response.Content.ReadAsStringAsync();\n\n        //Deserialize Body to object\n        var result = JsonConvert.DeserializeObject(responseBody);\n    }\n}\nGET /v1/webhooks/event-types\nGets all available webhook event types.\nExample responses\n200 Response\n{\"eventTypes\":[{\"name\":\"string\",\"description\":\"string\"}],\"success\":true,\"message\":\"string\"}"},{"page":233,"heading":"GET /v1/webhooks/event-types","anchor":"get-v1webhooksevent-types","text":"{\n  \"eventTypes\": [\n    {\n      \"name\": \"string\",\n      \"description\": \"string\"\n    }\n  ],\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponses\nStatus | Meaning | Description | Schema\n200 | OK | OK | Management.GetWebhookEventTypesResponse\nAuthentication: API key (x-api-key)."},{"page":234,"heading":"","anchor":"","text":"The request and response models of the API, grouped by area. Endpoint pages link to the model they use."},{"page":234,"heading":"Pages","anchor":"pages","text":"Product Releases: Releases, release assemblies and release downloads.\nLicensing: Licensing operations and reports sent by applications.\nWebhooks: Webhook subscriptions, events and event types.\nAuthentication: Login, logout, session and the signed-in user.\nReports, Log and Server: Received reports, log, email, settings and server information.\nUsers, Roles and API Keys: Users, user settings, roles and API keys.\nLicense Tokens: License tokens.\nLicenses: Licenses, license templates and license traces.\nCustomers, Orders and Products: Customers, contacts, orders, products, assemblies and resources."},{"page":234,"heading":"All Schemas","anchor":"all-schemas","text":"Schema | Page\nLicensing.ActivateLicenseRequest | Licensing\nLicensing.ActivateLicenseResponse | Licensing\nLicensing.DeactivateLicenseRequest | Licensing\nLicensing.DeactivateLicenseResponse | Licensing\nLicensing.DeleteReleaseDownloadResponse | Product Releases\nLicensing.Duration | Licensing\nLicensing.GetReleaseDownloadsResponse | Product Releases\nLicensing.HeartbeatRequest | Licensing\nLicensing.HeartbeatResponse | Licensing\nLicensing.InsertReleaseDownloadRequest | Product Releases\nLicensing.InsertReleaseDownloadResponse | Product Releases\nLicensing.License | Licensing\nLicensing.LicenseFormat | Licensing\nLicensing.LicenseInfoRequest | Licensing\nLicensing.LicenseInfoResponse | Licensing\nLicensing.LicenseToken | Licensing\nLicensing.LicensingMode | Licensing\nLicensing.ReleaseDownloadDto | Product Releases\nLicensing.ReleaseLicenseRequest | Licensing\nLicensing.ReleaseLicenseResponse | Licensing\nLicensing.Report | Licensing\nLicensing.RequestLicenseRequest | Licensing\nLicensing.RequestLicenseResponse | Licensing\nLicensing.SendReportRequest | Licensing\nLicensing.SendReportResponse | Licensing\nLicensing.Timestamp | Licensing\nLicensing.UpdateReleaseDownloadRequest | Product Releases\nLicensing.UpdateReleaseDownloadResponse | Product Releases\nLicensing.ValidateLicenseRequest | Licensing\nLicensing.ValidateLicenseResponse | Licensing\nLicensing.VerifyReleaseDownloadsResponse | Product Releases\nManagement.AddUserToRoleRequest | Users, Roles and API Keys"},{"page":234,"heading":"All Schemas","anchor":"all-schemas","text":"Management.AddUserToRoleResponse | Users, Roles and API Keys\nManagement.ApiKey | Users, Roles and API Keys\nManagement.ApplicationSetting | Reports, Log and Server\nManagement.Assembly | Customers, Orders and Products\nManagement.Contact | Customers, Orders and Products\nManagement.CreateWebhookSubscriptionDto | Webhooks\nManagement.CreateWebhookSubscriptionRequest | Webhooks\nManagement.CreateWebhookSubscriptionResponse | Webhooks\nManagement.Customer | Customers, Orders and Products\nManagement.DeleteApiKeyResponse | Users, Roles and API Keys\nManagement.DeleteAssemblyResponse | Customers, Orders and Products\nManagement.DeleteContactResponse | Customers, Orders and Products\nManagement.DeleteCustomerResponse | Customers, Orders and Products\nManagement.DeleteLicenseResponse | Licenses\nManagement.DeleteLicenseTemplateResponse | Licenses\nManagement.DeleteLicenseTokenResponse | License Tokens\nManagement.DeleteLicenseTraceRequest | Licenses\nManagement.DeleteLicenseTraceResponse | Licenses\nManagement.DeleteOrderResponse | Customers, Orders and Products\nManagement.DeleteProductOrderResponse | Customers, Orders and Products\nManagement.DeleteProductReleaseAssemblyResponse | Product Releases\nManagement.DeleteProductReleaseResponse | Product Releases\nManagement.DeleteProductResponse | Customers, Orders and Products\nManagement.DeleteReportResponse | Reports, Log and Server\nManagement.DeleteResourceResponse | Customers, Orders and Products\nManagement.DeleteUserResponse | Users, Roles and API Keys"},{"page":234,"heading":"All Schemas","anchor":"all-schemas","text":"Management.DeleteUserSettingResponse | Users, Roles and API Keys\nManagement.DeleteWebhookEventResponse | Webhooks\nManagement.DeleteWebhookSubscriptionResponse | Webhooks\nManagement.EmailAttachment | Reports, Log and Server\nManagement.EmailRecipient | Reports, Log and Server\nManagement.GetApiKeysResponse | Users, Roles and API Keys\nManagement.GetAssembliesResponse | Customers, Orders and Products\nManagement.GetContactsResponse | Customers, Orders and Products\nManagement.GetCustomerContactsResponse | Customers, Orders and Products\nManagement.GetCustomerLicensesResponse | Licenses\nManagement.GetCustomerOrdersResponse | Customers, Orders and Products\nManagement.GetCustomersResponse | Customers, Orders and Products\nManagement.GetLicensesResponse | Licenses\nManagement.GetLicenseTemplateLicensesResponse | Licenses\nManagement.GetLicenseTemplatesResponse | Licenses\nManagement.GetLicenseTokensResponse | License Tokens\nManagement.GetLicenseTracesResponse | Licenses\nManagement.GetLoggedInUserRequest | Authentication\nManagement.GetLoggedInUserResponse | Authentication\nManagement.GetLogLevelsResponse | Reports, Log and Server\nManagement.GetLogResponse | Reports, Log and Server\nManagement.GetOrderLicensesResponse | Licenses\nManagement.GetOrderProductsResponse | Customers, Orders and Products\nManagement.GetOrdersResponse | Customers, Orders and Products\nManagement.GetProductOrdersResponse | Customers, Orders and Products\nManagement.GetProductReleaseAssembliesResponse | Product Releases"},{"page":234,"heading":"All Schemas","anchor":"all-schemas","text":"Management.GetProductReleaseLicenseTemplatesResponse | Product Releases\nManagement.GetProductReleasesResponse | Product Releases\nManagement.GetProductsResponse | Customers, Orders and Products\nManagement.GetReportResponse | Reports, Log and Server\nManagement.GetResourcesResponse | Customers, Orders and Products\nManagement.GetRolesResponse | Users, Roles and API Keys\nManagement.GetServerInfoResponse | Reports, Log and Server\nManagement.GetSessionResponse | Authentication\nManagement.GetSettingsRequest | Reports, Log and Server\nManagement.GetSettingsResponse | Reports, Log and Server\nManagement.GetUserRolesResponse | Users, Roles and API Keys\nManagement.GetUserSettingsResponse | Users, Roles and API Keys\nManagement.GetUsersResponse | Users, Roles and API Keys\nManagement.GetWebhookEventsResponse | Webhooks\nManagement.GetWebhookEventTypesResponse | Webhooks\nManagement.GetWebhookStatusResponse | Webhooks\nManagement.GetWebhookSubscriptionResponse | Webhooks\nManagement.GetWebhookSubscriptionsResponse | Webhooks\nManagement.InsertApiKeyRequest | Users, Roles and API Keys\nManagement.InsertApiKeyResponse | Users, Roles and API Keys\nManagement.InsertAssemblyRequest | Customers, Orders and Products\nManagement.InsertAssemblyResponse | Customers, Orders and Products\nManagement.InsertContactRequest | Customers, Orders and Products\nManagement.InsertContactResponse | Customers, Orders and Products\nManagement.InsertCustomerRequest | Customers, Orders and Products"},{"page":234,"heading":"All Schemas","anchor":"all-schemas","text":"Management.InsertCustomerResponse | Customers, Orders and Products\nManagement.InsertLicenseRequest | Licenses\nManagement.InsertLicenseResponse | Licenses\nManagement.InsertLicenseTemplateRequest | Licenses\nManagement.InsertLicenseTemplateResponse | Licenses\nManagement.InsertLicenseTokenRequest | License Tokens\nManagement.InsertLicenseTokenResponse | License Tokens\nManagement.InsertOrderRequest | Customers, Orders and Products\nManagement.InsertOrderResponse | Customers, Orders and Products\nManagement.InsertProductOrderRequest | Customers, Orders and Products\nManagement.InsertProductOrderResponse | Customers, Orders and Products\nManagement.InsertProductReleaseAssemblyRequest | Product Releases\nManagement.InsertProductReleaseAssemblyResponse | Product Releases\nManagement.InsertProductReleaseRequest | Product Releases\nManagement.InsertProductReleaseResponse | Product Releases\nManagement.InsertProductRequest | Customers, Orders and Products\nManagement.InsertProductResponse | Customers, Orders and Products\nManagement.InsertResourceRequest | Customers, Orders and Products\nManagement.InsertResourceResponse | Customers, Orders and Products\nManagement.InsertUserRequest | Users, Roles and API Keys\nManagement.InsertUserResponse | Users, Roles and API Keys\nManagement.InsertUserSettingRequest | Users, Roles and API Keys\nManagement.InsertUserSettingResponse | Users, Roles and API Keys\nManagement.License | Licenses\nManagement.Licensee | Licenses\nManagement.LicenseFeature | Licenses"},{"page":234,"heading":"All Schemas","anchor":"all-schemas","text":"Management.LicenseField | Licenses\nManagement.LicenseProduct | Licenses\nManagement.LicenseRestriction | Licenses\nManagement.LicenseTemplate | Licenses\nManagement.LicenseToken | License Tokens\nManagement.LicenseTrace | Licenses\nManagement.LicensingMode | Licenses\nManagement.LogEntry | Reports, Log and Server\nManagement.LoginRequest | Authentication\nManagement.LoginResponse | Authentication\nManagement.LogLevelInfo | Reports, Log and Server\nManagement.LogoutRequest | Authentication\nManagement.LogoutResponse | Authentication\nManagement.Order | Customers, Orders and Products\nManagement.Product | Customers, Orders and Products\nManagement.ProductOrder | Customers, Orders and Products\nManagement.Release | Product Releases\nManagement.RemoveUserFromRoleRequest | Users, Roles and API Keys\nManagement.RemoveUserFromRoleResponse | Users, Roles and API Keys\nManagement.Report | Reports, Log and Server\nManagement.ReportProperty | Reports, Log and Server\nManagement.ResolveLicenseTraceLocationsRequest | Licenses\nManagement.ResolveLicenseTraceLocationsResponse | Licenses\nManagement.ResolveReportLocationsRequest | Reports, Log and Server\nManagement.ResolveReportLocationsResponse | Reports, Log and Server\nManagement.Resource | Customers, Orders and Products\nManagement.Role | Users, Roles and API Keys\nManagement.SendEmailRequest | Reports, Log and Server\nManagement.SendEmailResponse | Reports, Log and Server\nManagement.SendLicenseEmailRequest | Reports, Log and Server"},{"page":234,"heading":"All Schemas","anchor":"all-schemas","text":"Management.SendLicenseEmailResponse | Reports, Log and Server\nManagement.SendWebhookTestEventRequest | Webhooks\nManagement.SendWebhookTestEventResponse | Webhooks\nManagement.UpdateApiKeyRequest | Users, Roles and API Keys\nManagement.UpdateApiKeyResponse | Users, Roles and API Keys\nManagement.UpdateAssemblyRequest | Customers, Orders and Products\nManagement.UpdateAssemblyResponse | Customers, Orders and Products\nManagement.UpdateContactRequest | Customers, Orders and Products\nManagement.UpdateContactResponse | Customers, Orders and Products\nManagement.UpdateCustomerRequest | Customers, Orders and Products\nManagement.UpdateCustomerResponse | Customers, Orders and Products\nManagement.UpdateLicenseRequest | Licenses\nManagement.UpdateLicenseResponse | Licenses\nManagement.UpdateLicenseTemplateRequest | Licenses\nManagement.UpdateLicenseTemplateResponse | Licenses\nManagement.UpdateOrderRequest | Customers, Orders and Products\nManagement.UpdateOrderResponse | Customers, Orders and Products\nManagement.UpdateProductOrderRequest | Customers, Orders and Products\nManagement.UpdateProductOrderResponse | Customers, Orders and Products\nManagement.UpdateProductReleaseAssemblyRequest | Product Releases\nManagement.UpdateProductReleaseAssemblyResponse | Product Releases\nManagement.UpdateProductReleaseRequest | Product Releases\nManagement.UpdateProductReleaseResponse | Product Releases\nManagement.UpdateProductRequest | Customers, Orders and Products"},{"page":234,"heading":"All Schemas","anchor":"all-schemas","text":"Management.UpdateProductResponse | Customers, Orders and Products\nManagement.UpdateResourceRequest | Customers, Orders and Products\nManagement.UpdateResourceResponse | Customers, Orders and Products\nManagement.UpdateSettingsRequest | Reports, Log and Server\nManagement.UpdateSettingsResponse | Reports, Log and Server\nManagement.UpdateUserRequest | Users, Roles and API Keys\nManagement.UpdateUserResponse | Users, Roles and API Keys\nManagement.UpdateUserSettingRequest | Users, Roles and API Keys\nManagement.UpdateUserSettingResponse | Users, Roles and API Keys\nManagement.UpdateUserSettingsRequest | Authentication\nManagement.UpdateUserSettingsResponse | Authentication\nManagement.UpdateWebhookSubscriptionDto | Webhooks\nManagement.UpdateWebhookSubscriptionRequest | Webhooks\nManagement.UpdateWebhookSubscriptionResponse | Webhooks\nManagement.User | Users, Roles and API Keys\nManagement.UserSetting | Users, Roles and API Keys\nManagement.WebhookEvent | Webhooks\nManagement.WebhookEventType | Webhooks\nManagement.WebhookSubscription | Webhooks"},{"page":235,"heading":"Licensing.DeleteReleaseDownloadResponse","anchor":"licensingdeletereleasedownloadresponse","text":"{\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponse for DeleteReleaseDownload.\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | Indicates whether the operation was successful.\nmessage | string¦null | false | none | A human-readable message indicating the result of the operation."},{"page":235,"heading":"Licensing.GetReleaseDownloadsResponse","anchor":"licensinggetreleasedownloadsresponse","text":"{\n  \"success\": true,\n  \"releaseDownloads\": [\n    {\n      \"id\": 0,\n      \"platform\": \"string\",\n      \"kind\": \"string\",\n      \"fileName\": \"string\",\n      \"sourceKind\": \"string\",\n      \"url\": \"string\",\n      \"size\": 0,\n      \"sha256\": \"string\",\n      \"sha512\": \"string\",\n      \"signature\": \"string\",\n      \"signatureKeyId\": \"string\",\n      \"downloads\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\"\n    }\n  ],\n  \"totalReleaseDownloadsCount\": 0\n}\nResponse for the GetReleaseDownloadsRequest.\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | Indicates whether the operation was successful.\nreleaseDownloads | [Licensing.ReleaseDownloadDto]¦null | false | none | The list of release downloads.\ntotalReleaseDownloadsCount | integer(int32) | false | none | The total number of release downloads."},{"page":235,"heading":"Licensing.InsertReleaseDownloadRequest","anchor":"licensinginsertreleasedownloadrequest","text":"{\n  \"releaseDownload\": {\n    \"id\": 0,\n    \"platform\": \"string\",\n    \"kind\": \"string\",\n    \"fileName\": \"string\",\n    \"sourceKind\": \"string\",\n    \"url\": \"string\",\n    \"size\": 0,\n    \"sha256\": \"string\",\n    \"sha512\": \"string\",\n    \"signature\": \"string\",\n    \"signatureKeyId\": \"string\",\n    \"downloads\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\"\n  }\n}\nRequest to register a url-sourced release download.\nProperties\nName | Type | Required | Restrictions | Description\nreleaseDownload | Licensing.ReleaseDownloadDto | false | none | A downloadable artifact of a product release, as exposed by the admin API."},{"page":235,"heading":"Licensing.InsertReleaseDownloadResponse","anchor":"licensinginsertreleasedownloadresponse","text":"{\n  \"success\": true,\n  \"id\": 0,\n  \"platform\": \"string\",\n  \"kind\": \"string\",\n  \"size\": 0,\n  \"sha256\": \"string\",\n  \"sha512\": \"string\",\n  \"message\": \"string\"\n}\nResponse for InsertReleaseDownloadRequest / an artifact upload.\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | Indicates whether the operation was successful.\nid | integer(int32) | false | none | The id of the created release download.\nplatform | string¦null | false | none | The artifact's platform.\nkind | string¦null | false | none | The artifact's kind.\nsize | integer(int64) | false | none | The artifact size in bytes.\nsha256 | string¦null | false | none | The SHA-256 hash, lowercase hex.\nsha512 | string¦null | false | none | The SHA-512 hash, base64.\nmessage | string¦null | false | none | A human-readable message indicating the result of the operation."},{"page":235,"heading":"Licensing.ReleaseDownloadDto","anchor":"licensingreleasedownloaddto","text":"{\n  \"id\": 0,\n  \"platform\": \"string\",\n  \"kind\": \"string\",\n  \"fileName\": \"string\",\n  \"sourceKind\": \"string\",\n  \"url\": \"string\",\n  \"size\": 0,\n  \"sha256\": \"string\",\n  \"sha512\": \"string\",\n  \"signature\": \"string\",\n  \"signatureKeyId\": \"string\",\n  \"downloads\": 0,\n  \"createdAt\": \"2019-08-24T14:15:22Z\",\n  \"updatedAt\": \"2019-08-24T14:15:22Z\"\n}\nA downloadable artifact of a product release, as exposed by the admin API.\nProperties"},{"page":235,"heading":"Licensing.ReleaseDownloadDto","anchor":"licensingreleasedownloaddto","text":"Name | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | The unique identifier of the release download.\nplatform | string¦null | false | none | One of the recognised platform identifiers (e.g. darwin-arm64, win-x64).\nkind | string¦null | false | none | installer | zip | delta | blockmap.\nfileName | string¦null | false | none | The artifact's file name.\nsourceKind | string¦null | false | none | url | local | resource.\nurl | string¦null | false | none | The externally-hosted URL, when SourceKind is url.\nsize | integer(int64)¦null | false | none | The artifact size in bytes.\nsha256 | string¦null | false | none | The SHA-256 hash, lowercase hex.\nsha512 | string¦null | false | none | The SHA-512 hash, base64.\nsignature | string¦null | false | none | An optional detached signature over the artifact.\nsignatureKeyId | string¦null | false | none | The id of the key used to produce Signature.\ndownloads | integer(int64)¦null | false | none | The number of times this artifact has been downloaded.\ncreatedAt | string(date-time)¦null | false | none | When the release download was created.\nupdatedAt | string(date-time)¦null | false | none | When the release download was last updated."},{"page":235,"heading":"Licensing.UpdateReleaseDownloadRequest","anchor":"licensingupdatereleasedownloadrequest","text":"{\n  \"releaseDownload\": {\n    \"id\": 0,\n    \"platform\": \"string\",\n    \"kind\": \"string\",\n    \"fileName\": \"string\",\n    \"sourceKind\": \"string\",\n    \"url\": \"string\",\n    \"size\": 0,\n    \"sha256\": \"string\",\n    \"sha512\": \"string\",\n    \"signature\": \"string\",\n    \"signatureKeyId\": \"string\",\n    \"downloads\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\"\n  }\n}\nRequest to update an existing release download.\nProperties\nName | Type | Required | Restrictions | Description\nreleaseDownload | Licensing.ReleaseDownloadDto | false | none | A downloadable artifact of a product release, as exposed by the admin API."},{"page":235,"heading":"Licensing.UpdateReleaseDownloadResponse","anchor":"licensingupdatereleasedownloadresponse","text":"{\n  \"success\": true,\n  \"message\": \"string\"\n}\nResponse for UpdateReleaseDownloadRequest.\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | Indicates whether the operation was successful.\nmessage | string¦null | false | none | A human-readable message indicating the result of the operation."},{"page":235,"heading":"Licensing.VerifyReleaseDownloadsResponse","anchor":"licensingverifyreleasedownloadsresponse","text":"{\n  \"success\": true,\n  \"verified\": 0,\n  \"drifted\": [\n    0\n  ]\n}\nResponse for VerifyReleaseDownloads.\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | Indicates whether the operation was successful.\nverified | integer(int32) | false | none | The number of local/resource artifacts checked.\ndrifted | [integer]¦null | false | none | The ids of the artifacts whose recomputed hashes no longer match, or whose bytes are missing."},{"page":235,"heading":"Management.DeleteProductReleaseAssemblyResponse","anchor":"managementdeleteproductreleaseassemblyresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":235,"heading":"Management.DeleteProductReleaseResponse","anchor":"managementdeleteproductreleaseresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":235,"heading":"Management.GetProductReleaseAssembliesResponse","anchor":"managementgetproductreleaseassembliesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"assemblies\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"culture\": \"string\",\n      \"publicKeyToken\": \"string\",\n      \"mappingFileId\": 0,\n      \"debugSymbolsKey\": \"string\"\n    }\n  ],\n  \"totalAssembliesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nassemblies | [Management.Assembly]¦null | false | none | none\ntotalAssembliesCount | integer(int32) | false | none | none"},{"page":235,"heading":"Management.GetProductReleaseLicenseTemplatesResponse","anchor":"managementgetproductreleaselicensetemplatesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseTemplates\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\","},{"page":235,"heading":"Management.GetProductReleaseLicenseTemplatesResponse","anchor":"managementgetproductreleaselicensetemplatesresponse","text":"          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicenseTemplatesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenseTemplates | [Management.LicenseTemplate]¦null | false | none | none\ntotalLicenseTemplatesCount | integer(int32)¦null | false | none | none"},{"page":235,"heading":"Management.GetProductReleasesResponse","anchor":"managementgetproductreleasesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"releases\": [\n    {\n      \"id\": 0,\n      \"releaseDate\": \"2019-08-24T14:15:22Z\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"description\": \"string\",\n      \"public\": true,\n      \"requiresMaintenance\": true,\n      \"releaseNotes\": \"string\",\n      \"channel\": \"stable\"\n    }\n  ],\n  \"totalReleasesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nreleases | [Management.Release]¦null | false | none | none\ntotalReleasesCount | integer(int32)¦null | false | none | none"},{"page":235,"heading":"Management.InsertProductReleaseAssemblyRequest","anchor":"managementinsertproductreleaseassemblyrequest","text":"{\n  \"productId\": 0,\n  \"releaseId\": 0,\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nproductId | integer(int32) | false | none | none\nreleaseId | integer(int32) | false | none | none\nassembly | Management.Assembly | false | none | none"},{"page":235,"heading":"Management.InsertProductReleaseAssemblyResponse","anchor":"managementinsertproductreleaseassemblyresponse","text":"{\n  \"assemblyId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nassemblyId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":235,"heading":"Management.InsertProductReleaseRequest","anchor":"managementinsertproductreleaserequest","text":"{\n  \"release\": {\n    \"id\": 0,\n    \"releaseDate\": \"2019-08-24T14:15:22Z\",\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"description\": \"string\",\n    \"public\": true,\n    \"requiresMaintenance\": true,\n    \"releaseNotes\": \"string\",\n    \"channel\": \"stable\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nrelease | Management.Release | false | none | none"},{"page":235,"heading":"Management.InsertProductReleaseResponse","anchor":"managementinsertproductreleaseresponse","text":"{\n  \"releaseId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nreleaseId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":235,"heading":"Management.Release","anchor":"managementrelease","text":"{\n  \"id\": 0,\n  \"releaseDate\": \"2019-08-24T14:15:22Z\",\n  \"name\": \"string\",\n  \"version\": \"string\",\n  \"description\": \"string\",\n  \"public\": true,\n  \"requiresMaintenance\": true,\n  \"releaseNotes\": \"string\",\n  \"channel\": \"stable\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\nreleaseDate | string(date-time) | false | none | none\nname | string¦null | false | none | none\nversion | string¦null | false | none | none\ndescription | string¦null | false | none | none\npublic | boolean¦null | false | none | Whether the release is published. A release is not returned by v1/updates until this is true.\nrequiresMaintenance | boolean¦null | false | none | Whether the maintenance check applies to this release. When omitted on insert, it defaults to true.\nreleaseNotes | string¦null | false | none | Release notes in Markdown.\nchannel | string¦null | false | none | Release channel: stable or insider."},{"page":235,"heading":"Management.UpdateProductReleaseAssemblyRequest","anchor":"managementupdateproductreleaseassemblyrequest","text":"{\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nassembly | Management.Assembly | false | none | none"},{"page":235,"heading":"Management.UpdateProductReleaseAssemblyResponse","anchor":"managementupdateproductreleaseassemblyresponse","text":"{\n  \"assemblyId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nassemblyId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":235,"heading":"Management.UpdateProductReleaseRequest","anchor":"managementupdateproductreleaserequest","text":"{\n  \"release\": {\n    \"id\": 0,\n    \"releaseDate\": \"2019-08-24T14:15:22Z\",\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"description\": \"string\",\n    \"public\": true,\n    \"requiresMaintenance\": true,\n    \"releaseNotes\": \"string\",\n    \"channel\": \"stable\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nrelease | Management.Release | false | none | none"},{"page":235,"heading":"Management.UpdateProductReleaseResponse","anchor":"managementupdateproductreleaseresponse","text":"{\n  \"releaseId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nreleaseId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":236,"heading":"Licensing.ActivateLicenseRequest","anchor":"licensingactivatelicenserequest","text":"{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nuserKey | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none"},{"page":236,"heading":"Licensing.ActivateLicenseResponse","anchor":"licensingactivatelicenseresponse","text":"{\n  \"success\": true,\n  \"licenseToken\": \"string\",\n  \"tokenExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0,\n  \"license\": {\n    \"licenseId\": \"string\",\n    \"licensingMode\": 0,\n    \"expireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"supportExpireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"licenseKey\": [\n      0\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\nlicenseToken | string¦null | false | none | none\ntokenExpireAt | Licensing.Timestamp | false | none | none\nactiveClientCount | integer(int32) | false | none | none\nmaxClientCount | integer(int32) | false | none | none\nlicense | Licensing.License | false | none | none"},{"page":236,"heading":"Licensing.DeactivateLicenseRequest","anchor":"licensingdeactivatelicenserequest","text":"{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nuserKey | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none"},{"page":236,"heading":"Licensing.DeactivateLicenseResponse","anchor":"licensingdeactivatelicenseresponse","text":"{\n  \"licenseId\": \"string\",\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicenseId | string¦null | false | none | none\nactiveClientCount | integer(int32) | false | none | none\nmaxClientCount | integer(int32) | false | none | none"},{"page":236,"heading":"Licensing.Duration","anchor":"licensingduration","text":"{\n  \"seconds\": 0,\n  \"nanos\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nseconds | integer(int64) | false | none | none\nnanos | integer(int32) | false | none | none"},{"page":236,"heading":"Licensing.HeartbeatRequest","anchor":"licensingheartbeatrequest","text":"{\n  \"licenseToken\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicenseToken | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none"},{"page":236,"heading":"Licensing.HeartbeatResponse","anchor":"licensingheartbeatresponse","text":"{\n  \"active\": true,\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0,\n  \"tokenExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"heartbeatInterval\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nactive | boolean | false | none | none\nactiveClientCount | integer(int32) | false | none | none\nmaxClientCount | integer(int32) | false | none | none\ntokenExpireAt | Licensing.Timestamp | false | none | none\nheartbeatInterval | Licensing.Duration | false | none | none"},{"page":236,"heading":"Licensing.License","anchor":"licensinglicense","text":"{\n  \"licenseId\": \"string\",\n  \"licensingMode\": 0,\n  \"expireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"supportExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"licenseKey\": [\n    0\n  ]\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicenseId | string¦null | false | none | none\nlicensingMode | Licensing.LicensingMode | false | none | none\nexpireAt | Licensing.Timestamp | false | none | none\nsupportExpireAt | Licensing.Timestamp | false | none | none\nlicenseKey | [integer]¦null | false | none | none"},{"page":236,"heading":"Licensing.LicenseFormat","anchor":"licensinglicenseformat","text":"0\nProperties\nName | Type | Required | Restrictions | Description\nanonymous | integer(int32) | false | none | none\nEnumerated Values\nProperty | Value\nanonymous | 0\nanonymous | 1\nanonymous | 2\nanonymous | 3"},{"page":236,"heading":"Licensing.LicenseInfoRequest","anchor":"licensinglicenseinforequest","text":"{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nuserKey | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none"},{"page":236,"heading":"Licensing.LicenseInfoResponse","anchor":"licensinglicenseinforesponse","text":"{\n  \"licenseTokens\": [\n    {\n      \"token\": \"string\",\n      \"licenseId\": \"string\",\n      \"revoked\": true,\n      \"clientId\": \"string\",\n      \"clientAddr\": \"string\",\n      \"clientName\": \"string\",\n      \"machineId\": \"string\",\n      \"issuedAt\": {\n        \"seconds\": 0,\n        \"nanos\": 0\n      },\n      \"expireAt\": {\n        \"seconds\": 0,\n        \"nanos\": 0\n      },\n      \"lastHearbeat\": {\n        \"seconds\": 0,\n        \"nanos\": 0\n      }\n    }\n  ],\n  \"licenseId\": \"string\",\n  \"maxClientCount\": 0,\n  \"activeClientCount\": 0,\n  \"licensingMode\": 0,\n  \"revoked\": true,\n  \"issuedAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"expireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"supportExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicenseTokens | [Licensing.LicenseToken]¦null | false | read-only | none\nlicenseId | string¦null | false | none | none\nmaxClientCount | integer(int32) | false | none | none\nactiveClientCount | integer(int32) | false | none | none\nlicensingMode | Licensing.LicensingMode | false | none | none\nrevoked | boolean | false | none | none\nissuedAt | Licensing.Timestamp | false | none | none\nexpireAt | Licensing.Timestamp | false | none | none\nsupportExpireAt | Licensing.Timestamp | false | none | none"},{"page":236,"heading":"Licensing.LicenseToken","anchor":"licensinglicensetoken","text":"{\n  \"token\": \"string\",\n  \"licenseId\": \"string\",\n  \"revoked\": true,\n  \"clientId\": \"string\",\n  \"clientAddr\": \"string\",\n  \"clientName\": \"string\",\n  \"machineId\": \"string\",\n  \"issuedAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"expireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"lastHearbeat\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\ntoken | string¦null | false | none | none\nlicenseId | string¦null | false | none | none\nrevoked | boolean | false | none | none\nclientId | string¦null | false | none | none\nclientAddr | string¦null | false | none | none\nclientName | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nissuedAt | Licensing.Timestamp | false | none | none\nexpireAt | Licensing.Timestamp | false | none | none\nlastHearbeat | Licensing.Timestamp | false | none | none"},{"page":236,"heading":"Licensing.LicensingMode","anchor":"licensinglicensingmode","text":"0\nProperties\nName | Type | Required | Restrictions | Description\nanonymous | integer(int32) | false | none | none\nEnumerated Values\nProperty | Value\nanonymous | 0\nanonymous | 1\nanonymous | 2"},{"page":236,"heading":"Licensing.ReleaseLicenseRequest","anchor":"licensingreleaselicenserequest","text":"{\n  \"licenseToken\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicenseToken | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none"},{"page":236,"heading":"Licensing.ReleaseLicenseResponse","anchor":"licensingreleaselicenseresponse","text":"{\n  \"licenseId\": \"string\",\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicenseId | string¦null | false | none | none\nactiveClientCount | integer(int32) | false | none | none\nmaxClientCount | integer(int32) | false | none | none"},{"page":236,"heading":"Licensing.Report","anchor":"licensingreport","text":"{\n  \"name\": \"string\",\n  \"version\": \"string\",\n  \"date\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"encrypted\": true,\n  \"content\": [\n    0\n  ]\n}\nProperties\nName | Type | Required | Restrictions | Description\nname | string¦null | false | none | none\nversion | string¦null | false | none | none\ndate | Licensing.Timestamp | false | none | none\nencrypted | boolean | false | none | none\ncontent | [integer]¦null | false | none | none"},{"page":236,"heading":"Licensing.RequestLicenseRequest","anchor":"licensingrequestlicenserequest","text":"{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nuserKey | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none"},{"page":236,"heading":"Licensing.RequestLicenseResponse","anchor":"licensingrequestlicenseresponse","text":"{\n  \"granted\": true,\n  \"licenseToken\": \"string\",\n  \"tokenExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"heartbeatInterval\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0,\n  \"license\": {\n    \"licenseId\": \"string\",\n    \"licensingMode\": 0,\n    \"expireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"supportExpireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"licenseKey\": [\n      0\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\ngranted | boolean | false | none | none\nlicenseToken | string¦null | false | none | none\ntokenExpireAt | Licensing.Timestamp | false | none | none\nheartbeatInterval | Licensing.Duration | false | none | none\nactiveClientCount | integer(int32) | false | none | none\nmaxClientCount | integer(int32) | false | none | none\nlicense | Licensing.License | false | none | none"},{"page":236,"heading":"Licensing.SendReportRequest","anchor":"licensingsendreportrequest","text":"{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\",\n  \"report\": {\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"date\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"encrypted\": true,\n    \"content\": [\n      0\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nuserKey | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none\nreport | Licensing.Report | false | none | none"},{"page":236,"heading":"Licensing.SendReportResponse","anchor":"licensingsendreportresponse","text":"{\n  \"success\": true,\n  \"reportUid\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\nreportUid | string¦null | false | none | none"},{"page":236,"heading":"Licensing.Timestamp","anchor":"licensingtimestamp","text":"{\n  \"seconds\": 0,\n  \"nanos\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nseconds | integer(int64) | false | none | none\nnanos | integer(int32) | false | none | none"},{"page":236,"heading":"Licensing.ValidateLicenseRequest","anchor":"licensingvalidatelicenserequest","text":"{\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nuserKey | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none"},{"page":236,"heading":"Licensing.ValidateLicenseResponse","anchor":"licensingvalidatelicenseresponse","text":"{\n  \"success\": true,\n  \"licenseToken\": \"string\",\n  \"tokenExpireAt\": {\n    \"seconds\": 0,\n    \"nanos\": 0\n  },\n  \"activeClientCount\": 0,\n  \"maxClientCount\": 0,\n  \"license\": {\n    \"licenseId\": \"string\",\n    \"licensingMode\": 0,\n    \"expireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"supportExpireAt\": {\n      \"seconds\": 0,\n      \"nanos\": 0\n    },\n    \"licenseKey\": [\n      0\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\nlicenseToken | string¦null | false | none | none\ntokenExpireAt | Licensing.Timestamp | false | none | none\nactiveClientCount | integer(int32) | false | none | none\nmaxClientCount | integer(int32) | false | none | none\nlicense | Licensing.License | false | none | none"},{"page":237,"heading":"Management.CreateWebhookSubscriptionDto","anchor":"managementcreatewebhooksubscriptiondto","text":"{\n  \"name\": \"string\",\n  \"eventType\": \"string\",\n  \"url\": \"string\",\n  \"secret\": \"string\",\n  \"headers\": {\n    \"property1\": \"string\",\n    \"property2\": \"string\"\n  },\n  \"maxRetryCount\": 0,\n  \"isActive\": true\n}\nProperties\nName | Type | Required | Restrictions | Description\nname | string¦null | false | none | none\neventType | string¦null | false | none | none\nurl | string¦null | false | none | none\nsecret | string¦null | false | none | none\nheaders | object¦null | false | none | none\n» additionalProperties | string¦null | false | none | none\nmaxRetryCount | integer(int32)¦null | false | none | none\nisActive | boolean¦null | false | none | none"},{"page":237,"heading":"Management.CreateWebhookSubscriptionRequest","anchor":"managementcreatewebhooksubscriptionrequest","text":"{\n  \"subscription\": {\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"headers\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"maxRetryCount\": 0,\n    \"isActive\": true\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nsubscription | Management.CreateWebhookSubscriptionDto | false | none | none"},{"page":237,"heading":"Management.CreateWebhookSubscriptionResponse","anchor":"managementcreatewebhooksubscriptionresponse","text":"{\n  \"subscription\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"maxRetryCount\": 0,\n    \"isActive\": true,\n    \"userId\": \"string\",\n    \"headers\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"webhookEvents\": [\n      {\n        \"id\": 0,\n        \"webhookSubscriptionId\": 0,\n        \"eventType\": \"string\",\n        \"payload\": \"string\",\n        \"statusCode\": 0,\n        \"response\": \"string\",\n        \"errorMessage\": \"string\",\n        \"isSuccess\": true,\n        \"retryCount\": 0,\n        \"sentAt\": \"2019-08-24T14:15:22Z\",\n        \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\"\n      }\n    ]\n  },\n  \"success\": true,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsubscription | Management.WebhookSubscription | false | none | none\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none"},{"page":237,"heading":"Management.DeleteWebhookEventResponse","anchor":"managementdeletewebhookeventresponse","text":"{\n  \"success\": true,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none"},{"page":237,"heading":"Management.DeleteWebhookSubscriptionResponse","anchor":"managementdeletewebhooksubscriptionresponse","text":"{\n  \"success\": true,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none"},{"page":237,"heading":"Management.GetWebhookEventTypesResponse","anchor":"managementgetwebhookeventtypesresponse","text":"{\n  \"eventTypes\": [\n    {\n      \"name\": \"string\",\n      \"description\": \"string\"\n    }\n  ],\n  \"success\": true,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\neventTypes | [Management.WebhookEventType]¦null | false | none | none\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none"},{"page":237,"heading":"Management.GetWebhookEventsResponse","anchor":"managementgetwebhookeventsresponse","text":"{\n  \"events\": [\n    {\n      \"id\": 0,\n      \"webhookSubscriptionId\": 0,\n      \"eventType\": \"string\",\n      \"payload\": \"string\",\n      \"statusCode\": 0,\n      \"response\": \"string\",\n      \"errorMessage\": \"string\",\n      \"isSuccess\": true,\n      \"retryCount\": 0,\n      \"sentAt\": \"2019-08-24T14:15:22Z\",\n      \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\"\n    }\n  ],\n  \"totalEventsCount\": 0,\n  \"success\": true,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nevents | [Management.WebhookEvent]¦null | false | none | none\ntotalEventsCount | integer(int32) | false | none | none\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none"},{"page":237,"heading":"Management.GetWebhookStatusResponse","anchor":"managementgetwebhookstatusresponse","text":"{\n  \"isEnabled\": true,\n  \"success\": true,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nisEnabled | boolean | false | none | none\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none"},{"page":237,"heading":"Management.GetWebhookSubscriptionResponse","anchor":"managementgetwebhooksubscriptionresponse","text":"{\n  \"subscription\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"maxRetryCount\": 0,\n    \"isActive\": true,\n    \"userId\": \"string\",\n    \"headers\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"webhookEvents\": [\n      {\n        \"id\": 0,\n        \"webhookSubscriptionId\": 0,\n        \"eventType\": \"string\",\n        \"payload\": \"string\",\n        \"statusCode\": 0,\n        \"response\": \"string\",\n        \"errorMessage\": \"string\",\n        \"isSuccess\": true,\n        \"retryCount\": 0,\n        \"sentAt\": \"2019-08-24T14:15:22Z\",\n        \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\"\n      }\n    ]\n  },\n  \"success\": true,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsubscription | Management.WebhookSubscription | false | none | none\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none"},{"page":237,"heading":"Management.GetWebhookSubscriptionsResponse","anchor":"managementgetwebhooksubscriptionsresponse","text":"{\n  \"subscriptions\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"eventType\": \"string\",\n      \"url\": \"string\",\n      \"secret\": \"string\",\n      \"maxRetryCount\": 0,\n      \"isActive\": true,\n      \"userId\": \"string\",\n      \"headers\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"webhookEvents\": [\n        {\n          \"id\": 0,\n          \"webhookSubscriptionId\": 0,\n          \"eventType\": \"string\",\n          \"payload\": \"string\",\n          \"statusCode\": 0,\n          \"response\": \"string\",\n          \"errorMessage\": \"string\",\n          \"isSuccess\": true,\n          \"retryCount\": 0,\n          \"sentAt\": \"2019-08-24T14:15:22Z\",\n          \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\"\n        }\n      ]\n    }\n  ],\n  \"totalSubscriptionsCount\": 0,\n  \"success\": true,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsubscriptions | [Management.WebhookSubscription]¦null | false | none | none\ntotalSubscriptionsCount | integer(int32) | false | none | none\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none"},{"page":237,"heading":"Management.SendWebhookTestEventRequest","anchor":"managementsendwebhooktesteventrequest","text":"{\n  \"payload\": null\n}\nProperties\nName | Type | Required | Restrictions | Description\npayload | any | false | none | none"},{"page":237,"heading":"Management.SendWebhookTestEventResponse","anchor":"managementsendwebhooktesteventresponse","text":"{\n  \"success\": true,\n  \"message\": \"string\",\n  \"eventId\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none\neventId | integer(int32)¦null | false | none | none"},{"page":237,"heading":"Management.UpdateWebhookSubscriptionDto","anchor":"managementupdatewebhooksubscriptiondto","text":"{\n  \"name\": \"string\",\n  \"eventType\": \"string\",\n  \"url\": \"string\",\n  \"secret\": \"string\",\n  \"headers\": {\n    \"property1\": \"string\",\n    \"property2\": \"string\"\n  },\n  \"maxRetryCount\": 0,\n  \"isActive\": true\n}\nProperties\nName | Type | Required | Restrictions | Description\nname | string¦null | false | none | none\neventType | string¦null | false | none | none\nurl | string¦null | false | none | none\nsecret | string¦null | false | none | none\nheaders | object¦null | false | none | none\n» additionalProperties | string¦null | false | none | none\nmaxRetryCount | integer(int32)¦null | false | none | none\nisActive | boolean¦null | false | none | none"},{"page":237,"heading":"Management.UpdateWebhookSubscriptionRequest","anchor":"managementupdatewebhooksubscriptionrequest","text":"{\n  \"subscription\": {\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"headers\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"maxRetryCount\": 0,\n    \"isActive\": true\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nsubscription | Management.UpdateWebhookSubscriptionDto | false | none | none"},{"page":237,"heading":"Management.UpdateWebhookSubscriptionResponse","anchor":"managementupdatewebhooksubscriptionresponse","text":"{\n  \"subscription\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"eventType\": \"string\",\n    \"url\": \"string\",\n    \"secret\": \"string\",\n    \"maxRetryCount\": 0,\n    \"isActive\": true,\n    \"userId\": \"string\",\n    \"headers\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"webhookEvents\": [\n      {\n        \"id\": 0,\n        \"webhookSubscriptionId\": 0,\n        \"eventType\": \"string\",\n        \"payload\": \"string\",\n        \"statusCode\": 0,\n        \"response\": \"string\",\n        \"errorMessage\": \"string\",\n        \"isSuccess\": true,\n        \"retryCount\": 0,\n        \"sentAt\": \"2019-08-24T14:15:22Z\",\n        \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\"\n      }\n    ]\n  },\n  \"success\": true,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsubscription | Management.WebhookSubscription | false | none | none\nsuccess | boolean | false | none | none\nmessage | string¦null | false | none | none"},{"page":237,"heading":"Management.WebhookEvent","anchor":"managementwebhookevent","text":"{\n  \"id\": 0,\n  \"webhookSubscriptionId\": 0,\n  \"eventType\": \"string\",\n  \"payload\": \"string\",\n  \"statusCode\": 0,\n  \"response\": \"string\",\n  \"errorMessage\": \"string\",\n  \"isSuccess\": true,\n  \"retryCount\": 0,\n  \"sentAt\": \"2019-08-24T14:15:22Z\",\n  \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n  \"createdAt\": \"2019-08-24T14:15:22Z\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32) | false | none | none\nwebhookSubscriptionId | integer(int32) | false | none | none\neventType | string¦null | false | none | none\npayload | string¦null | false | none | none\nstatusCode | integer(int32)¦null | false | none | none\nresponse | string¦null | false | none | none\nerrorMessage | string¦null | false | none | none\nisSuccess | boolean¦null | false | none | none\nretryCount | integer(int32) | false | none | none\nsentAt | string(date-time)¦null | false | none | none\nnextRetryAt | string(date-time)¦null | false | none | none\ncreatedAt | string(date-time) | false | none | none"},{"page":237,"heading":"Management.WebhookEventType","anchor":"managementwebhookeventtype","text":"{\n  \"name\": \"string\",\n  \"description\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nname | string¦null | false | none | none\ndescription | string¦null | false | none | none"},{"page":237,"heading":"Management.WebhookSubscription","anchor":"managementwebhooksubscription","text":"{\n  \"id\": 0,\n  \"name\": \"string\",\n  \"eventType\": \"string\",\n  \"url\": \"string\",\n  \"secret\": \"string\",\n  \"maxRetryCount\": 0,\n  \"isActive\": true,\n  \"userId\": \"string\",\n  \"headers\": \"string\",\n  \"createdAt\": \"2019-08-24T14:15:22Z\",\n  \"updatedAt\": \"2019-08-24T14:15:22Z\",\n  \"webhookEvents\": [\n    {\n      \"id\": 0,\n      \"webhookSubscriptionId\": 0,\n      \"eventType\": \"string\",\n      \"payload\": \"string\",\n      \"statusCode\": 0,\n      \"response\": \"string\",\n      \"errorMessage\": \"string\",\n      \"isSuccess\": true,\n      \"retryCount\": 0,\n      \"sentAt\": \"2019-08-24T14:15:22Z\",\n      \"nextRetryAt\": \"2019-08-24T14:15:22Z\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\"\n    }\n  ]\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32) | false | none | none\nname | string¦null | false | none | none\neventType | string¦null | false | none | none\nurl | string¦null | false | none | none\nsecret | string¦null | false | none | none\nmaxRetryCount | integer(int32) | false | none | none\nisActive | boolean | false | none | none\nuserId | string¦null | false | none | none\nheaders | string¦null | false | none | none\ncreatedAt | string(date-time)¦null | false | none | none\nupdatedAt | string(date-time)¦null | false | none | none\nwebhookEvents | [Management.WebhookEvent]¦null | false | none | none"},{"page":238,"heading":"Management.GetLoggedInUserRequest","anchor":"managementgetloggedinuserrequest","text":"{}\nProperties\nNone"},{"page":238,"heading":"Management.GetLoggedInUserResponse","anchor":"managementgetloggedinuserresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  }\n}\nProperties"},{"page":238,"heading":"Management.GetLoggedInUserResponse","anchor":"managementgetloggedinuserresponse","text":"Name | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nuser | Management.User | false | none | none"},{"page":238,"heading":"Management.GetSessionResponse","anchor":"managementgetsessionresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"user\": \"string\",\n  \"roles\": [\n    \"string\"\n  ],\n  \"permissions\": 0,\n  \"keyName\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nuser | string¦null | false | none | none\nroles | [string]¦null | false | none | none\npermissions | integer(int32)¦null | false | none | none\nkeyName | string¦null | false | none | none"},{"page":238,"heading":"Management.LoginRequest","anchor":"managementloginrequest","text":"{\n  \"username\": \"string\",\n  \"password\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nusername | string¦null | false | none | none\npassword | string¦null | false | none | none"},{"page":238,"heading":"Management.LoginResponse","anchor":"managementloginresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"token\": \"string\",\n  \"expiresIn\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\ntoken | string¦null | false | none | none\nexpiresIn | integer(int32) | false | none | none"},{"page":238,"heading":"Management.LogoutRequest","anchor":"managementlogoutrequest","text":"{}\nProperties\nNone"},{"page":238,"heading":"Management.LogoutResponse","anchor":"managementlogoutresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":238,"heading":"Management.UpdateUserSettingsRequest","anchor":"managementupdateusersettingsrequest","text":"{\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nuser | Management.User | false | none | none"},{"page":238,"heading":"Management.UpdateUserSettingsResponse","anchor":"managementupdateusersettingsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  }\n}\nProperties"},{"page":238,"heading":"Management.UpdateUserSettingsResponse","anchor":"managementupdateusersettingsresponse","text":"Name | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nuser | Management.User | false | none | none"},{"page":239,"heading":"Management.ApplicationSetting","anchor":"managementapplicationsetting","text":"{\n  \"group\": \"string\",\n  \"name\": \"string\",\n  \"type\": \"string\",\n  \"value\": null\n}\nProperties\nName | Type | Required | Restrictions | Description\ngroup | string¦null | false | none | none\nname | string¦null | false | none | none\ntype | string¦null | false | none | none\nvalue | any | false | none | none"},{"page":239,"heading":"Management.DeleteReportResponse","anchor":"managementdeletereportresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":239,"heading":"Management.EmailAttachment","anchor":"managementemailattachment","text":"{\n  \"fileName\": \"string\",\n  \"content\": \"string\",\n  \"contentType\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nfileName | string¦null | false | none | none\ncontent | string(byte)¦null | false | none | none\ncontentType | string¦null | false | none | none"},{"page":239,"heading":"Management.EmailRecipient","anchor":"managementemailrecipient","text":"{\n  \"name\": \"string\",\n  \"email\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nname | string¦null | false | none | none\nemail | string¦null | false | none | none"},{"page":239,"heading":"Management.GetLogLevelsResponse","anchor":"managementgetloglevelsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"logLevels\": [\n    {\n      \"date\": \"2019-08-24T14:15:22Z\",\n      \"level\": \"string\",\n      \"count\": 0\n    }\n  ],\n  \"groupBy\": \"string\",\n  \"totalLogLevelEntriesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlogLevels | [Management.LogLevelInfo]¦null | false | none | none\ngroupBy | string¦null | false | none | none\ntotalLogLevelEntriesCount | integer(int32)¦null | false | none | none"},{"page":239,"heading":"Management.GetLogResponse","anchor":"managementgetlogresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"logEntries\": [\n    {\n      \"id\": 0,\n      \"message\": \"string\",\n      \"messageTemplate\": \"string\",\n      \"level\": \"string\",\n      \"timeStamp\": \"2019-08-24T14:15:22Z\",\n      \"exception\": \"string\",\n      \"properties\": \"string\"\n    }\n  ],\n  \"totalLogEntriesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlogEntries | [Management.LogEntry]¦null | false | none | none\ntotalLogEntriesCount | integer(int32)¦null | false | none | none"},{"page":239,"heading":"Management.GetReportResponse","anchor":"managementgetreportresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"reports\": [\n    {\n      \"id\": 0,\n      \"uid\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"date\": \"2019-08-24T14:15:22Z\",\n      \"userKey\": \"string\",\n      \"machineId\": \"string\",\n      \"clientId\": \"string\",\n      \"clientName\": \"string\",\n      \"contentType\": \"string\",\n      \"content\": \"string\",\n      \"address\": \"string\",\n      \"geoLocation\": \"string\",\n      \"properties\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"value\": \"string\",\n          \"reportId\": 0\n        }\n      ]\n    }\n  ],\n  \"totalReportsCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nreports | [Management.Report]¦null | false | none | none\ntotalReportsCount | integer(int32)¦null | false | none | none"},{"page":239,"heading":"Management.GetServerInfoResponse","anchor":"managementgetserverinforesponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"product\": \"string\",\n  \"edition\": 0,\n  \"version\": \"string\",\n  \"license\": \"string\",\n  \"serverHost\": \"string\",\n  \"serverTime\": \"2019-08-24T14:15:22Z\",\n  \"clientAddress\": \"string\",\n  \"activeTokens\": 0,\n  \"maxTokens\": 0,\n  \"activationTokens\": 0,\n  \"floatingTokens\": 0,\n  \"expiredTokens\": 0,\n  \"totalLicenses\": 0,\n  \"revokedLicenses\": 0,\n  \"tracedLicenses\": 0,\n  \"activationLicenses\": 0,\n  \"floatingLicenses\": 0,\n  \"fileLicenses\": 0\n}\nProperties"},{"page":239,"heading":"Management.GetServerInfoResponse","anchor":"managementgetserverinforesponse","text":"Name | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nproduct | string¦null | false | none | none\nedition | integer(int32)¦null | false | none | none\nversion | string¦null | false | none | none\nlicense | string¦null | false | none | none\nserverHost | string¦null | false | none | none\nserverTime | string(date-time)¦null | false | none | none\nclientAddress | string¦null | false | none | none\nactiveTokens | integer(int32)¦null | false | none | none\nmaxTokens | integer(int32)¦null | false | none | none\nactivationTokens | integer(int32)¦null | false | none | none\nfloatingTokens | integer(int32)¦null | false | none | none\nexpiredTokens | integer(int32)¦null | false | none | none\ntotalLicenses | integer(int32)¦null | false | none | none\nrevokedLicenses | integer(int32)¦null | false | none | none\ntracedLicenses | integer(int32)¦null | false | none | none\nactivationLicenses | integer(int32)¦null | false | none | none\nfloatingLicenses | integer(int32)¦null | false | none | none\nfileLicenses | integer(int32)¦null | false | none | none"},{"page":239,"heading":"Management.GetSettingsRequest","anchor":"managementgetsettingsrequest","text":"{}\nProperties\nNone"},{"page":239,"heading":"Management.GetSettingsResponse","anchor":"managementgetsettingsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"settings\": [\n    {\n      \"group\": \"string\",\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"value\": null\n    }\n  ]\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nsettings | [Management.ApplicationSetting]¦null | false | none | none"},{"page":239,"heading":"Management.LogEntry","anchor":"managementlogentry","text":"{\n  \"id\": 0,\n  \"message\": \"string\",\n  \"messageTemplate\": \"string\",\n  \"level\": \"string\",\n  \"timeStamp\": \"2019-08-24T14:15:22Z\",\n  \"exception\": \"string\",\n  \"properties\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nmessageTemplate | string¦null | false | none | none\nlevel | string¦null | false | none | none\ntimeStamp | string(date-time)¦null | false | none | none\nexception | string¦null | false | none | none\nproperties | string¦null | false | none | none"},{"page":239,"heading":"Management.LogLevelInfo","anchor":"managementloglevelinfo","text":"{\n  \"date\": \"2019-08-24T14:15:22Z\",\n  \"level\": \"string\",\n  \"count\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\ndate | string(date-time) | false | none | none\nlevel | string¦null | false | none | none\ncount | integer(int32) | false | none | none"},{"page":239,"heading":"Management.Report","anchor":"managementreport","text":"{\n  \"id\": 0,\n  \"uid\": \"string\",\n  \"name\": \"string\",\n  \"version\": \"string\",\n  \"date\": \"2019-08-24T14:15:22Z\",\n  \"userKey\": \"string\",\n  \"machineId\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\",\n  \"contentType\": \"string\",\n  \"content\": \"string\",\n  \"address\": \"string\",\n  \"geoLocation\": \"string\",\n  \"properties\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"value\": \"string\",\n      \"reportId\": 0\n    }\n  ]\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32) | false | none | none\nuid | string¦null | false | none | none\nname | string¦null | false | none | none\nversion | string¦null | false | none | none\ndate | string(date-time)¦null | false | none | none\nuserKey | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none\ncontentType | string¦null | false | none | none\ncontent | string¦null | false | none | none\naddress | string¦null | false | none | none\ngeoLocation | string¦null | false | none | none\nproperties | [Management.ReportProperty]¦null | false | none | none"},{"page":239,"heading":"Management.ReportProperty","anchor":"managementreportproperty","text":"{\n  \"id\": 0,\n  \"name\": \"string\",\n  \"value\": \"string\",\n  \"reportId\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32) | false | none | none\nname | string¦null | false | none | none\nvalue | string¦null | false | none | none\nreportId | integer(int32) | false | none | none"},{"page":239,"heading":"Management.ResolveReportLocationsRequest","anchor":"managementresolvereportlocationsrequest","text":"{\n  \"reportIds\": [\n    0\n  ],\n  \"limit\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nreportIds | [integer]¦null | false | none | none\nlimit | integer(int32)¦null | false | none | none"},{"page":239,"heading":"Management.ResolveReportLocationsResponse","anchor":"managementresolvereportlocationsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"resolvedCount\": 0,\n  \"unresolvedCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nresolvedCount | integer(int32)¦null | false | none | none\nunresolvedCount | integer(int32)¦null | false | none | none"},{"page":239,"heading":"Management.SendEmailRequest","anchor":"managementsendemailrequest","text":"{\n  \"to\": [\n    {\n      \"name\": \"string\",\n      \"email\": \"string\"\n    }\n  ],\n  \"subject\": \"string\",\n  \"body\": \"string\",\n  \"isHtml\": true,\n  \"attachments\": [\n    {\n      \"fileName\": \"string\",\n      \"content\": \"string\",\n      \"contentType\": \"string\"\n    }\n  ]\n}\nProperties\nName | Type | Required | Restrictions | Description\nto | [Management.EmailRecipient]¦null | false | none | none\nsubject | string¦null | false | none | none\nbody | string¦null | false | none | none\nisHtml | boolean | false | none | none\nattachments | [Management.EmailAttachment]¦null | false | none | none"},{"page":239,"heading":"Management.SendEmailResponse","anchor":"managementsendemailresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":239,"heading":"Management.SendLicenseEmailRequest","anchor":"managementsendlicenseemailrequest","text":"{\n  \"licenseId\": 0,\n  \"resourceId\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicenseId | integer(int32) | false | none | none\nresourceId | integer(int32) | false | none | none"},{"page":239,"heading":"Management.SendLicenseEmailResponse","anchor":"managementsendlicenseemailresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":239,"heading":"Management.UpdateSettingsRequest","anchor":"managementupdatesettingsrequest","text":"{\n  \"settings\": [\n    {\n      \"group\": \"string\",\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"value\": null\n    }\n  ]\n}\nProperties\nName | Type | Required | Restrictions | Description\nsettings | [Management.ApplicationSetting]¦null | false | none | none"},{"page":239,"heading":"Management.UpdateSettingsResponse","anchor":"managementupdatesettingsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.AddUserToRoleRequest","anchor":"managementaddusertorolerequest","text":"{\n  \"roles\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nroles | string¦null | false | none | none"},{"page":240,"heading":"Management.AddUserToRoleResponse","anchor":"managementaddusertoroleresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.ApiKey","anchor":"managementapikey","text":"{\n  \"id\": 0,\n  \"name\": \"string\",\n  \"key\": \"string\",\n  \"clientSecret\": \"string\",\n  \"createdDate\": \"2019-08-24T14:15:22Z\",\n  \"expireDate\": \"2019-08-24T14:15:22Z\",\n  \"ownerId\": \"string\",\n  \"revoked\": true,\n  \"permissions\": 0,\n  \"description\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\nname | string¦null | false | none | none\nkey | string¦null | false | none | none\nclientSecret | string¦null | false | none | none\ncreatedDate | string(date-time)¦null | false | none | none\nexpireDate | string(date-time)¦null | false | none | none\nownerId | string¦null | false | none | none\nrevoked | boolean¦null | false | none | none\npermissions | integer(int32)¦null | false | none | none\ndescription | string¦null | false | none | none"},{"page":240,"heading":"Management.DeleteApiKeyResponse","anchor":"managementdeleteapikeyresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.DeleteUserResponse","anchor":"managementdeleteuserresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.DeleteUserSettingResponse","anchor":"managementdeleteusersettingresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.GetApiKeysResponse","anchor":"managementgetapikeysresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"apiKeys\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"key\": \"string\",\n      \"clientSecret\": \"string\",\n      \"createdDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"ownerId\": \"string\",\n      \"revoked\": true,\n      \"permissions\": 0,\n      \"description\": \"string\"\n    }\n  ],\n  \"totalApiKeysCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\napiKeys | [Management.ApiKey]¦null | false | none | none\ntotalApiKeysCount | integer(int32)¦null | false | none | none"},{"page":240,"heading":"Management.GetRolesResponse","anchor":"managementgetrolesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"roles\": [\n    {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\"\n    }\n  ],\n  \"totalRolesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nroles | [Management.Role]¦null | false | none | none\ntotalRolesCount | integer(int32)¦null | false | none | none"},{"page":240,"heading":"Management.GetUserRolesResponse","anchor":"managementgetuserrolesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"roles\": [\n    {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\"\n    }\n  ],\n  \"totalRolesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nroles | [Management.Role]¦null | false | none | none\ntotalRolesCount | integer(int32)¦null | false | none | none"},{"page":240,"heading":"Management.GetUserSettingsResponse","anchor":"managementgetusersettingsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"settings\": [\n    {\n      \"id\": 0,\n      \"category\": \"string\",\n      \"group\": \"string\",\n      \"name\": \"string\",\n      \"value\": \"string\",\n      \"type\": \"string\",\n      \"description\": \"string\",\n      \"readOnly\": true,\n      \"userId\": \"string\"\n    }\n  ],\n  \"totalSettingsCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nsettings | [Management.UserSetting]¦null | false | none | none\ntotalSettingsCount | integer(int32)¦null | false | none | none"},{"page":240,"heading":"Management.GetUsersResponse","anchor":"managementgetusersresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"users\": [\n    {\n      \"id\": \"string\",\n      \"userName\": \"string\",\n      \"email\": \"string\",\n      \"phoneNumber\": \"string\",\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"department\": \"string\",\n      \"birthDate\": \"2019-08-24T14:15:22Z\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n      \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n      \"rank\": 0,\n      \"image\": \"string\",\n      \"address\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mobile\": \"string\",\n      \"notes\": \"string\",\n      \"customerId\": 0,\n      \"roles\": [\n        \"string\"\n      ],\n      \"apiKeys\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"key\": \"string\",\n          \"clientSecret\": \"string\",\n          \"createdDate\": \"2019-08-24T14:15:22Z\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"ownerId\": \"string\",\n          \"revoked\": true,\n          \"permissions\": 0,\n          \"description\": \"string\"\n        }\n      ],\n      \"settings\": [\n        {\n          \"id\": 0,\n          \"category\": \"string\",\n          \"group\": \"string\",\n          \"name\": \"string\",\n          \"value\": \"string\",\n          \"type\": \"string\",\n          \"description\": \"string\",\n          \"readOnly\": true,"},{"page":240,"heading":"Management.GetUsersResponse","anchor":"managementgetusersresponse","text":"          \"userId\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalUsersCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nusers | [Management.User]¦null | false | none | none\ntotalUsersCount | integer(int32)¦null | false | none | none"},{"page":240,"heading":"Management.InsertApiKeyRequest","anchor":"managementinsertapikeyrequest","text":"{\n  \"apiKey\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"key\": \"string\",\n    \"clientSecret\": \"string\",\n    \"createdDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"ownerId\": \"string\",\n    \"revoked\": true,\n    \"permissions\": 0,\n    \"description\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\napiKey | Management.ApiKey | false | none | none"},{"page":240,"heading":"Management.InsertApiKeyResponse","anchor":"managementinsertapikeyresponse","text":"{\n  \"apiKeyId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"apiKey\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\napiKeyId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\napiKey | string¦null | false | none | none"},{"page":240,"heading":"Management.InsertUserRequest","anchor":"managementinsertuserrequest","text":"{\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  },\n  \"password\": \"string\"\n}\nProperties"},{"page":240,"heading":"Management.InsertUserRequest","anchor":"managementinsertuserrequest","text":"Name | Type | Required | Restrictions | Description\nuser | Management.User | false | none | none\npassword | string¦null | false | none | none"},{"page":240,"heading":"Management.InsertUserResponse","anchor":"managementinsertuserresponse","text":"{\n  \"userId\": \"string\",\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nuserId | string¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.InsertUserSettingRequest","anchor":"managementinsertusersettingrequest","text":"{\n  \"setting\": {\n    \"id\": 0,\n    \"category\": \"string\",\n    \"group\": \"string\",\n    \"name\": \"string\",\n    \"value\": \"string\",\n    \"type\": \"string\",\n    \"description\": \"string\",\n    \"readOnly\": true,\n    \"userId\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nsetting | Management.UserSetting | false | none | none"},{"page":240,"heading":"Management.InsertUserSettingResponse","anchor":"managementinsertusersettingresponse","text":"{\n  \"settingId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsettingId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.RemoveUserFromRoleRequest","anchor":"managementremoveuserfromrolerequest","text":"{\n  \"roles\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nroles | string¦null | false | none | none"},{"page":240,"heading":"Management.RemoveUserFromRoleResponse","anchor":"managementremoveuserfromroleresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.Role","anchor":"managementrole","text":"{\n  \"id\": \"string\",\n  \"name\": \"string\",\n  \"description\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | string¦null | false | none | none\nname | string¦null | false | none | none\ndescription | string¦null | false | none | none"},{"page":240,"heading":"Management.UpdateApiKeyRequest","anchor":"managementupdateapikeyrequest","text":"{\n  \"apiKey\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"key\": \"string\",\n    \"clientSecret\": \"string\",\n    \"createdDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"ownerId\": \"string\",\n    \"revoked\": true,\n    \"permissions\": 0,\n    \"description\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\napiKey | Management.ApiKey | false | none | none"},{"page":240,"heading":"Management.UpdateApiKeyResponse","anchor":"managementupdateapikeyresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.UpdateUserRequest","anchor":"managementupdateuserrequest","text":"{\n  \"user\": {\n    \"id\": \"string\",\n    \"userName\": \"string\",\n    \"email\": \"string\",\n    \"phoneNumber\": \"string\",\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"department\": \"string\",\n    \"birthDate\": \"2019-08-24T14:15:22Z\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n    \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n    \"rank\": 0,\n    \"image\": \"string\",\n    \"address\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mobile\": \"string\",\n    \"notes\": \"string\",\n    \"customerId\": 0,\n    \"roles\": [\n      \"string\"\n    ],\n    \"apiKeys\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"key\": \"string\",\n        \"clientSecret\": \"string\",\n        \"createdDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"ownerId\": \"string\",\n        \"revoked\": true,\n        \"permissions\": 0,\n        \"description\": \"string\"\n      }\n    ],\n    \"settings\": [\n      {\n        \"id\": 0,\n        \"category\": \"string\",\n        \"group\": \"string\",\n        \"name\": \"string\",\n        \"value\": \"string\",\n        \"type\": \"string\",\n        \"description\": \"string\",\n        \"readOnly\": true,\n        \"userId\": \"string\"\n      }\n    ]\n  },\n  \"currentPassword\": \"string\",\n  \"newPassword\": \"string\"\n}\nProperties"},{"page":240,"heading":"Management.UpdateUserRequest","anchor":"managementupdateuserrequest","text":"Name | Type | Required | Restrictions | Description\nuser | Management.User | false | none | none\ncurrentPassword | string¦null | false | none | none\nnewPassword | string¦null | false | none | none"},{"page":240,"heading":"Management.UpdateUserResponse","anchor":"managementupdateuserresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.UpdateUserSettingRequest","anchor":"managementupdateusersettingrequest","text":"{\n  \"setting\": {\n    \"id\": 0,\n    \"category\": \"string\",\n    \"group\": \"string\",\n    \"name\": \"string\",\n    \"value\": \"string\",\n    \"type\": \"string\",\n    \"description\": \"string\",\n    \"readOnly\": true,\n    \"userId\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nsetting | Management.UserSetting | false | none | none"},{"page":240,"heading":"Management.UpdateUserSettingResponse","anchor":"managementupdateusersettingresponse","text":"{\n  \"settingsId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsettingsId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":240,"heading":"Management.User","anchor":"managementuser","text":"{\n  \"id\": \"string\",\n  \"userName\": \"string\",\n  \"email\": \"string\",\n  \"phoneNumber\": \"string\",\n  \"title\": \"string\",\n  \"firstName\": \"string\",\n  \"lastName\": \"string\",\n  \"department\": \"string\",\n  \"birthDate\": \"2019-08-24T14:15:22Z\",\n  \"createdAt\": \"2019-08-24T14:15:22Z\",\n  \"updatedAt\": \"2019-08-24T14:15:22Z\",\n  \"lastDismissMessages\": \"2019-08-24T14:15:22Z\",\n  \"lastLogIn\": \"2019-08-24T14:15:22Z\",\n  \"rank\": 0,\n  \"image\": \"string\",\n  \"address\": \"string\",\n  \"postalCode\": \"string\",\n  \"region\": \"string\",\n  \"city\": \"string\",\n  \"country\": \"string\",\n  \"countryCode\": \"string\",\n  \"mobile\": \"string\",\n  \"notes\": \"string\",\n  \"customerId\": 0,\n  \"roles\": [\n    \"string\"\n  ],\n  \"apiKeys\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"key\": \"string\",\n      \"clientSecret\": \"string\",\n      \"createdDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"ownerId\": \"string\",\n      \"revoked\": true,\n      \"permissions\": 0,\n      \"description\": \"string\"\n    }\n  ],\n  \"settings\": [\n    {\n      \"id\": 0,\n      \"category\": \"string\",\n      \"group\": \"string\",\n      \"name\": \"string\",\n      \"value\": \"string\",\n      \"type\": \"string\",\n      \"description\": \"string\",\n      \"readOnly\": true,\n      \"userId\": \"string\"\n    }\n  ]\n}\nProperties"},{"page":240,"heading":"Management.User","anchor":"managementuser","text":"Name | Type | Required | Restrictions | Description\nid | string¦null | false | none | none\nuserName | string¦null | false | none | none\nemail | string¦null | false | none | none\nphoneNumber | string¦null | false | none | none\ntitle | string¦null | false | none | none\nfirstName | string¦null | false | none | none\nlastName | string¦null | false | none | none\ndepartment | string¦null | false | none | none\nbirthDate | string(date-time)¦null | false | none | none\ncreatedAt | string(date-time)¦null | false | none | none\nupdatedAt | string(date-time)¦null | false | none | none\nlastDismissMessages | string(date-time)¦null | false | none | none\nlastLogIn | string(date-time)¦null | false | none | none\nrank | integer(int32)¦null | false | none | none\nimage | string(byte)¦null | false | none | none\naddress | string¦null | false | none | none\npostalCode | string¦null | false | none | none\nregion | string¦null | false | none | none\ncity | string¦null | false | none | none\ncountry | string¦null | false | none | none\ncountryCode | string¦null | false | none | none\nmobile | string¦null | false | none | none\nnotes | string¦null | false | none | none\ncustomerId | integer(int32)¦null | false | none | none\nroles | [string]¦null | false | none | none\napiKeys | [Management.ApiKey]¦null | false | none | none\nsettings | [Management.UserSetting]¦null | false | none | none"},{"page":240,"heading":"Management.UserSetting","anchor":"managementusersetting","text":"{\n  \"id\": 0,\n  \"category\": \"string\",\n  \"group\": \"string\",\n  \"name\": \"string\",\n  \"value\": \"string\",\n  \"type\": \"string\",\n  \"description\": \"string\",\n  \"readOnly\": true,\n  \"userId\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32) | false | none | none\ncategory | string¦null | false | none | none\ngroup | string¦null | false | none | none\nname | string¦null | false | none | none\nvalue | string¦null | false | none | none\ntype | string¦null | false | none | none\ndescription | string¦null | false | none | none\nreadOnly | boolean | false | none | none\nuserId | string¦null | false | none | none"},{"page":241,"heading":"Management.DeleteLicenseTokenResponse","anchor":"managementdeletelicensetokenresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseTokens\": [\n    {\n      \"id\": 0,\n      \"token\": \"string\",\n      \"address\": \"string\",\n      \"clientId\": \"string\",\n      \"clientName\": \"string\",\n      \"machineId\": \"string\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"lastHeartbeat\": \"2019-08-24T14:15:22Z\",\n      \"hash\": \"string\",\n      \"licenseId\": 0,\n      \"license\": {\n        \"id\": 0,\n        \"licenseId\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"description\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"issueDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n        \"revoked\": true,\n        \"trace\": true,\n        \"licenseKey\": \"string\",\n        \"maxAllowedSites\": 0,\n        \"userKey\": \"string\",\n        \"licensingMode\": 0,\n        \"licenseeName\": \"string\",\n        \"licenseeCompany\": \"string\",\n        \"licenseeEmail\": \"string\",\n        \"hash\": \"string\",\n        \"meta\": \"string\",\n        \"templateId\": 0,\n        \"signatureKeysId\": 0,\n        \"customerId\": 0,\n        \"orderId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"order\": {\n          \"id\": 0,"},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\",\n          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\","},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\",\n                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        },\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\","},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"template\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"code\": \"string\",\n          \"licenseType\": \"string\",\n          \"format\": 0,\n          \"licensingMode\": 0,\n          \"licenseFileName\": \"string\",\n          \"issueDate\": true,\n          \"expireDays\": 0,\n          \"supportDays\": 0,\n          \"generateKeyInfo\": true,\n          \"userKey\": \"string\",\n          \"description\": \"string\",\n          \"template\": \"string\",\n          \"productId\": 0,\n          \"signatureKeysId\": 0,\n          \"releaseId\": 0,\n          \"product\": {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"copyright\": \"string\",\n            \"url\": \"string\",\n            \"description\": \"string\"\n          },\n          \"components\": [\n            \"string\"\n          ],\n          \"assemblies\": [\n            {\n              \"id\": 0,\n              \"name\": \"string\",\n              \"version\": \"string\","},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"              \"culture\": \"string\",\n              \"publicKeyToken\": \"string\",\n              \"mappingFileId\": 0,\n              \"debugSymbolsKey\": \"string\"\n            }\n          ],\n          \"fields\": [\n            {\n              \"name\": \"string\",\n              \"value\": \"string\"\n            }\n          ],\n          \"features\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"description\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"key\": \"string\",\n              \"data\": \"string\"\n            }\n          ],\n          \"restrictions\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"properties\": {\n                \"property1\": \"string\",\n                \"property2\": \"string\"\n              },\n              \"customXmlContent\": \"string\"\n            }\n          ]\n        },\n        \"licensee\": {\n          \"name\": \"string\",\n          \"company\": \"string\",\n          \"contactInfo\": \"string\",\n          \"url\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {"},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"nodeLockedLicenseId\": 0,\n      \"nodeLockedLicense\": {\n        \"id\": 0,\n        \"licenseId\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"description\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"issueDate\": \"2019-08-24T14:15:22Z\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n        \"revoked\": true,\n        \"trace\": true,\n        \"licenseKey\": \"string\",\n        \"maxAllowedSites\": 0,\n        \"userKey\": \"string\",\n        \"licensingMode\": 0,\n        \"licenseeName\": \"string\",\n        \"licenseeCompany\": \"string\",\n        \"licenseeEmail\": \"string\",\n        \"hash\": \"string\",\n        \"meta\": \"string\",\n        \"templateId\": 0,\n        \"signatureKeysId\": 0,"},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"        \"customerId\": 0,\n        \"orderId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\",\n          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\","},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\",\n                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        },\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\","},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"template\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"code\": \"string\",\n          \"licenseType\": \"string\",\n          \"format\": 0,\n          \"licensingMode\": 0,\n          \"licenseFileName\": \"string\",\n          \"issueDate\": true,\n          \"expireDays\": 0,\n          \"supportDays\": 0,\n          \"generateKeyInfo\": true,\n          \"userKey\": \"string\",\n          \"description\": \"string\",\n          \"template\": \"string\",\n          \"productId\": 0,\n          \"signatureKeysId\": 0,\n          \"releaseId\": 0,\n          \"product\": {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"version\": \"string\","},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"            \"copyright\": \"string\",\n            \"url\": \"string\",\n            \"description\": \"string\"\n          },\n          \"components\": [\n            \"string\"\n          ],\n          \"assemblies\": [\n            {\n              \"id\": 0,\n              \"name\": \"string\",\n              \"version\": \"string\",\n              \"culture\": \"string\",\n              \"publicKeyToken\": \"string\",\n              \"mappingFileId\": 0,\n              \"debugSymbolsKey\": \"string\"\n            }\n          ],\n          \"fields\": [\n            {\n              \"name\": \"string\",\n              \"value\": \"string\"\n            }\n          ],\n          \"features\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"description\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"key\": \"string\",\n              \"data\": \"string\"\n            }\n          ],\n          \"restrictions\": [\n            {\n              \"id\": \"string\",\n              \"name\": \"string\",\n              \"expireDate\": \"2019-08-24T14:15:22Z\",\n              \"properties\": {\n                \"property1\": \"string\",\n                \"property2\": \"string\"\n              },\n              \"customXmlContent\": \"string\"\n            }\n          ]\n        },\n        \"licensee\": {\n          \"name\": \"string\",\n          \"company\": \"string\",\n          \"contactInfo\": \"string\",\n          \"url\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {"},{"page":241,"heading":"Management.GetLicenseTokensResponse","anchor":"managementgetlicensetokensresponse","text":"            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      }\n    }\n  ],\n  \"licenseTokensCount\": 0,\n  \"totalLicenseTokensCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenseTokens | [Management.LicenseToken]¦null | false | none | none\nlicenseTokensCount | integer(int32)¦null | false | none | none\ntotalLicenseTokensCount | integer(int32)¦null | false | none | none"},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"{\n  \"licenseToken\": {\n    \"id\": 0,\n    \"token\": \"string\",\n    \"address\": \"string\",\n    \"clientId\": \"string\",\n    \"clientName\": \"string\",\n    \"machineId\": \"string\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"lastHeartbeat\": \"2019-08-24T14:15:22Z\",\n    \"hash\": \"string\",\n    \"licenseId\": 0,\n    \"license\": {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,"},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\","},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\","},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\","},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\""},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"nodeLockedLicenseId\": 0,\n    \"nodeLockedLicense\": {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\","},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,"},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\","},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"        \"code\": \"string\",\n        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":241,"heading":"Management.InsertLicenseTokenRequest","anchor":"managementinsertlicensetokenrequest","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicenseToken | Management.LicenseToken | false | none | none"},{"page":241,"heading":"Management.InsertLicenseTokenResponse","anchor":"managementinsertlicensetokenresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseId\": 0,\n  \"licenseTokenId\": 0,\n  \"token\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenseId | integer(int32)¦null | false | none | none\nlicenseTokenId | integer(int32)¦null | false | none | none\ntoken | string¦null | false | none | none"},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"{\n  \"id\": 0,\n  \"token\": \"string\",\n  \"address\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\",\n  \"machineId\": \"string\",\n  \"issueDate\": \"2019-08-24T14:15:22Z\",\n  \"expireDate\": \"2019-08-24T14:15:22Z\",\n  \"lastHeartbeat\": \"2019-08-24T14:15:22Z\",\n  \"hash\": \"string\",\n  \"licenseId\": 0,\n  \"license\": {\n    \"id\": 0,\n    \"licenseId\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"description\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n    \"revoked\": true,\n    \"trace\": true,\n    \"licenseKey\": \"string\",\n    \"maxAllowedSites\": 0,\n    \"userKey\": \"string\",\n    \"licensingMode\": 0,\n    \"licenseeName\": \"string\",\n    \"licenseeCompany\": \"string\",\n    \"licenseeEmail\": \"string\",\n    \"hash\": \"string\",\n    \"meta\": \"string\",\n    \"templateId\": 0,\n    \"signatureKeysId\": 0,\n    \"customerId\": 0,\n    \"orderId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\","},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\""},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"          }\n        ]\n      },\n      \"resellerId\": 0\n    },\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"template\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\","},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"licensee\": {\n      \"name\": \"string\",\n      \"company\": \"string\","},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"      \"contactInfo\": \"string\",\n      \"url\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\",\n        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  },\n  \"nodeLockedLicenseId\": 0,\n  \"nodeLockedLicense\": {\n    \"id\": 0,\n    \"licenseId\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"description\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n    \"revoked\": true,\n    \"trace\": true,\n    \"licenseKey\": \"string\",\n    \"maxAllowedSites\": 0,\n    \"userKey\": \"string\",\n    \"licensingMode\": 0,\n    \"licenseeName\": \"string\","},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"    \"licenseeCompany\": \"string\",\n    \"licenseeEmail\": \"string\",\n    \"hash\": \"string\",\n    \"meta\": \"string\",\n    \"templateId\": 0,\n    \"signatureKeysId\": 0,\n    \"customerId\": 0,\n    \"orderId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\","},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    },\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\","},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"template\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": ["},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"licensee\": {\n      \"name\": \"string\",\n      \"company\": \"string\",\n      \"contactInfo\": \"string\",\n      \"url\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\",\n        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":241,"heading":"Management.LicenseToken","anchor":"managementlicensetoken","text":"        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\ntoken | string¦null | false | none | none\naddress | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none\nmachineId | string¦null | false | none | none\nissueDate | string(date-time)¦null | false | none | none\nexpireDate | string(date-time)¦null | false | none | none\nlastHeartbeat | string(date-time)¦null | false | none | none\nhash | string¦null | false | none | none\nlicenseId | integer(int32)¦null | false | none | none\nlicense | Management.License | false | none | none\nnodeLockedLicenseId | integer(int32)¦null | false | none | none\nnodeLockedLicense | Management.License | false | none | none"},{"page":242,"heading":"Management.DeleteLicenseResponse","anchor":"managementdeletelicenseresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":242,"heading":"Management.DeleteLicenseTemplateResponse","anchor":"managementdeletelicensetemplateresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":242,"heading":"Management.DeleteLicenseTraceRequest","anchor":"managementdeletelicensetracerequest","text":"{\n  \"traceId\": 0,\n  \"licenseId\": 0,\n  \"filter\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\ntraceId | integer(int32)¦null | false | none | none\nlicenseId | integer(int32)¦null | false | none | none\nfilter | string¦null | false | none | none"},{"page":242,"heading":"Management.DeleteLicenseTraceResponse","anchor":"managementdeletelicensetraceresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":242,"heading":"Management.GetCustomerLicensesResponse","anchor":"managementgetcustomerlicensesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenses\": [\n    {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\","},{"page":242,"heading":"Management.GetCustomerLicensesResponse","anchor":"managementgetcustomerlicensesresponse","text":"        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\""},{"page":242,"heading":"Management.GetCustomerLicensesResponse","anchor":"managementgetcustomerlicensesresponse","text":"            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\","},{"page":242,"heading":"Management.GetCustomerLicensesResponse","anchor":"managementgetcustomerlicensesresponse","text":"        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":242,"heading":"Management.GetCustomerLicensesResponse","anchor":"managementgetcustomerlicensesresponse","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicensesCount\": 0\n}\nProperties"},{"page":242,"heading":"Management.GetCustomerLicensesResponse","anchor":"managementgetcustomerlicensesresponse","text":"Name | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenses | [Management.License]¦null | false | none | none\ntotalLicensesCount | integer(int32)¦null | false | none | none"},{"page":242,"heading":"Management.GetLicenseTemplateLicensesResponse","anchor":"managementgetlicensetemplatelicensesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenses\": [\n    {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\","},{"page":242,"heading":"Management.GetLicenseTemplateLicensesResponse","anchor":"managementgetlicensetemplatelicensesresponse","text":"        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\""},{"page":242,"heading":"Management.GetLicenseTemplateLicensesResponse","anchor":"managementgetlicensetemplatelicensesresponse","text":"            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\","},{"page":242,"heading":"Management.GetLicenseTemplateLicensesResponse","anchor":"managementgetlicensetemplatelicensesresponse","text":"        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":242,"heading":"Management.GetLicenseTemplateLicensesResponse","anchor":"managementgetlicensetemplatelicensesresponse","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicensesCount\": 0\n}\nProperties"},{"page":242,"heading":"Management.GetLicenseTemplateLicensesResponse","anchor":"managementgetlicensetemplatelicensesresponse","text":"Name | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenses | [Management.License]¦null | false | none | none\ntotalLicensesCount | integer(int32)¦null | false | none | none"},{"page":242,"heading":"Management.GetLicenseTemplatesResponse","anchor":"managementgetlicensetemplatesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseTemplates\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\","},{"page":242,"heading":"Management.GetLicenseTemplatesResponse","anchor":"managementgetlicensetemplatesresponse","text":"          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicenseTemplatesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenseTemplates | [Management.LicenseTemplate]¦null | false | none | none\ntotalLicenseTemplatesCount | integer(int32)¦null | false | none | none"},{"page":242,"heading":"Management.GetLicenseTracesResponse","anchor":"managementgetlicensetracesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseTraces\": [\n    {\n      \"id\": 0,\n      \"clientIp\": \"string\",\n      \"clientId\": \"string\",\n      \"clientName\": \"string\",\n      \"machineId\": \"string\",\n      \"createdDate\": \"2019-08-24T14:15:22Z\",\n      \"action\": 0,\n      \"geoLocation\": \"string\",\n      \"meta\": \"string\",\n      \"licenseId\": 0\n    }\n  ],\n  \"totalLicenseTracesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenseTraces | [Management.LicenseTrace]¦null | false | none | none\ntotalLicenseTracesCount | integer(int32)¦null | false | none | none"},{"page":242,"heading":"Management.GetLicensesResponse","anchor":"managementgetlicensesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenses\": [\n    {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\","},{"page":242,"heading":"Management.GetLicensesResponse","anchor":"managementgetlicensesresponse","text":"        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\""},{"page":242,"heading":"Management.GetLicensesResponse","anchor":"managementgetlicensesresponse","text":"            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\","},{"page":242,"heading":"Management.GetLicensesResponse","anchor":"managementgetlicensesresponse","text":"        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":242,"heading":"Management.GetLicensesResponse","anchor":"managementgetlicensesresponse","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicensesCount\": 0\n}\nProperties"},{"page":242,"heading":"Management.GetLicensesResponse","anchor":"managementgetlicensesresponse","text":"Name | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenses | [Management.License]¦null | false | none | none\ntotalLicensesCount | integer(int32)¦null | false | none | none"},{"page":242,"heading":"Management.GetOrderLicensesResponse","anchor":"managementgetorderlicensesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenses\": [\n    {\n      \"id\": 0,\n      \"licenseId\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"description\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"issueDate\": \"2019-08-24T14:15:22Z\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n      \"revoked\": true,\n      \"trace\": true,\n      \"licenseKey\": \"string\",\n      \"maxAllowedSites\": 0,\n      \"userKey\": \"string\",\n      \"licensingMode\": 0,\n      \"licenseeName\": \"string\",\n      \"licenseeCompany\": \"string\",\n      \"licenseeEmail\": \"string\",\n      \"hash\": \"string\",\n      \"meta\": \"string\",\n      \"templateId\": 0,\n      \"signatureKeysId\": 0,\n      \"customerId\": 0,\n      \"orderId\": 0,\n      \"product\": {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\","},{"page":242,"heading":"Management.GetOrderLicensesResponse","anchor":"managementgetorderlicensesresponse","text":"        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\""},{"page":242,"heading":"Management.GetOrderLicensesResponse","anchor":"managementgetorderlicensesresponse","text":"            }\n          ]\n        },\n        \"resellerId\": 0\n      },\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"template\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"code\": \"string\","},{"page":242,"heading":"Management.GetOrderLicensesResponse","anchor":"managementgetorderlicensesresponse","text":"        \"licenseType\": \"string\",\n        \"format\": 0,\n        \"licensingMode\": 0,\n        \"licenseFileName\": \"string\",\n        \"issueDate\": true,\n        \"expireDays\": 0,\n        \"supportDays\": 0,\n        \"generateKeyInfo\": true,\n        \"userKey\": \"string\",\n        \"description\": \"string\",\n        \"template\": \"string\",\n        \"productId\": 0,\n        \"signatureKeysId\": 0,\n        \"releaseId\": 0,\n        \"product\": {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"copyright\": \"string\",\n          \"url\": \"string\",\n          \"description\": \"string\"\n        },\n        \"components\": [\n          \"string\"\n        ],\n        \"assemblies\": [\n          {\n            \"id\": 0,\n            \"name\": \"string\",\n            \"version\": \"string\",\n            \"culture\": \"string\",\n            \"publicKeyToken\": \"string\",\n            \"mappingFileId\": 0,\n            \"debugSymbolsKey\": \"string\"\n          }\n        ],\n        \"fields\": [\n          {\n            \"name\": \"string\",\n            \"value\": \"string\"\n          }\n        ],\n        \"features\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"description\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\",\n            \"key\": \"string\",\n            \"data\": \"string\"\n          }\n        ],\n        \"restrictions\": [\n          {\n            \"id\": \"string\",\n            \"name\": \"string\",\n            \"expireDate\": \"2019-08-24T14:15:22Z\","},{"page":242,"heading":"Management.GetOrderLicensesResponse","anchor":"managementgetorderlicensesresponse","text":"            \"properties\": {\n              \"property1\": \"string\",\n              \"property2\": \"string\"\n            },\n            \"customXmlContent\": \"string\"\n          }\n        ]\n      },\n      \"licensee\": {\n        \"name\": \"string\",\n        \"company\": \"string\",\n        \"contactInfo\": \"string\",\n        \"url\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalLicensesCount\": 0\n}\nProperties"},{"page":242,"heading":"Management.GetOrderLicensesResponse","anchor":"managementgetorderlicensesresponse","text":"Name | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenses | [Management.License]¦null | false | none | none\ntotalLicensesCount | integer(int32)¦null | false | none | none"},{"page":242,"heading":"Management.InsertLicenseRequest","anchor":"managementinsertlicenserequest","text":"{\n  \"license\": {\n    \"id\": 0,\n    \"licenseId\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"description\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n    \"revoked\": true,\n    \"trace\": true,\n    \"licenseKey\": \"string\",\n    \"maxAllowedSites\": 0,\n    \"userKey\": \"string\",\n    \"licensingMode\": 0,\n    \"licenseeName\": \"string\",\n    \"licenseeCompany\": \"string\",\n    \"licenseeEmail\": \"string\",\n    \"hash\": \"string\",\n    \"meta\": \"string\",\n    \"templateId\": 0,\n    \"signatureKeysId\": 0,\n    \"customerId\": 0,\n    \"orderId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\","},{"page":242,"heading":"Management.InsertLicenseRequest","anchor":"managementinsertlicenserequest","text":"        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    },\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\","},{"page":242,"heading":"Management.InsertLicenseRequest","anchor":"managementinsertlicenserequest","text":"      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"template\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {"},{"page":242,"heading":"Management.InsertLicenseRequest","anchor":"managementinsertlicenserequest","text":"        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"licensee\": {\n      \"name\": \"string\",\n      \"company\": \"string\",\n      \"contactInfo\": \"string\",\n      \"url\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\","},{"page":242,"heading":"Management.InsertLicenseRequest","anchor":"managementinsertlicenserequest","text":"        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicense | Management.License | false | none | none"},{"page":242,"heading":"Management.InsertLicenseResponse","anchor":"managementinsertlicenseresponse","text":"{\n  \"licenseId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseKeyId\": \"string\",\n  \"userKey\": \"string\",\n  \"licenseKey\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicenseId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenseKeyId | string¦null | false | none | none\nuserKey | string¦null | false | none | none\nlicenseKey | string(byte)¦null | false | none | none"},{"page":242,"heading":"Management.InsertLicenseTemplateRequest","anchor":"managementinsertlicensetemplaterequest","text":"{\n  \"licenseTemplate\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"code\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"licensingMode\": 0,\n    \"licenseFileName\": \"string\",\n    \"issueDate\": true,\n    \"expireDays\": 0,\n    \"supportDays\": 0,\n    \"generateKeyInfo\": true,\n    \"userKey\": \"string\",\n    \"description\": \"string\",\n    \"template\": \"string\",\n    \"productId\": 0,\n    \"signatureKeysId\": 0,\n    \"releaseId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\",\n        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}\nProperties"},{"page":242,"heading":"Management.InsertLicenseTemplateRequest","anchor":"managementinsertlicensetemplaterequest","text":"Name | Type | Required | Restrictions | Description\nlicenseTemplate | Management.LicenseTemplate | false | none | none"},{"page":242,"heading":"Management.InsertLicenseTemplateResponse","anchor":"managementinsertlicensetemplateresponse","text":"{\n  \"templateId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"template\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\ntemplateId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\ntemplate | string(byte)¦null | false | none | none"},{"page":242,"heading":"Management.License","anchor":"managementlicense","text":"{\n  \"id\": 0,\n  \"licenseId\": \"string\",\n  \"licenseType\": \"string\",\n  \"format\": 0,\n  \"description\": \"string\",\n  \"createdAt\": \"2019-08-24T14:15:22Z\",\n  \"updatedAt\": \"2019-08-24T14:15:22Z\",\n  \"issueDate\": \"2019-08-24T14:15:22Z\",\n  \"expireDate\": \"2019-08-24T14:15:22Z\",\n  \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n  \"revoked\": true,\n  \"trace\": true,\n  \"licenseKey\": \"string\",\n  \"maxAllowedSites\": 0,\n  \"userKey\": \"string\",\n  \"licensingMode\": 0,\n  \"licenseeName\": \"string\",\n  \"licenseeCompany\": \"string\",\n  \"licenseeEmail\": \"string\",\n  \"hash\": \"string\",\n  \"meta\": \"string\",\n  \"templateId\": 0,\n  \"signatureKeysId\": 0,\n  \"customerId\": 0,\n  \"orderId\": 0,\n  \"product\": {\n    \"id\": \"string\",\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"copyright\": \"string\",\n    \"url\": \"string\",\n    \"description\": \"string\"\n  },\n  \"order\": {\n    \"id\": 0,\n    \"orderNumber\": \"string\",\n    \"status\": \"string\",\n    \"processedBy\": \"string\",\n    \"purchaseOrder\": \"string\",\n    \"total\": 0.1,\n    \"currency\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"invoiceNumber\": \"string\",\n    \"paymentType\": \"string\",\n    \"paymentNumber\": \"string\",\n    \"paymentStatus\": \"string\",\n    \"paymentDate\": \"2019-08-24T14:15:22Z\",\n    \"description\": \"string\",\n    \"customerId\": 0,\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\","},{"page":242,"heading":"Management.License","anchor":"managementlicense","text":"      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"resellerId\": 0\n  },\n  \"customer\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"company\": \"string\",\n    \"code\": \"string\",\n    \"vatCode\": \"string\",\n    \"invoiceCode\": \"string\",\n    \"rating\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"address\": \"string\",\n    \"address1\": \"string\",\n    \"address2\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\","},{"page":242,"heading":"Management.License","anchor":"managementlicense","text":"    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mapCoordinates\": \"string\",\n    \"mapZoomLevel\": 0.1,\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"website\": \"string\",\n    \"notes\": \"string\",\n    \"isReseller\": true,\n    \"image\": \"string\",\n    \"meta\": \"string\",\n    \"contacts\": [\n      {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"details\": \"string\",\n        \"notify\": true,\n        \"customerId\": 0,\n        \"meta\": \"string\"\n      }\n    ]\n  },\n  \"template\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"code\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"licensingMode\": 0,\n    \"licenseFileName\": \"string\",\n    \"issueDate\": true,\n    \"expireDays\": 0,\n    \"supportDays\": 0,\n    \"generateKeyInfo\": true,\n    \"userKey\": \"string\",\n    \"description\": \"string\",\n    \"template\": \"string\",\n    \"productId\": 0,\n    \"signatureKeysId\": 0,\n    \"releaseId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\","},{"page":242,"heading":"Management.License","anchor":"managementlicense","text":"        \"publicKeyToken\": \"string\",\n        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  },\n  \"licensee\": {\n    \"name\": \"string\",\n    \"company\": \"string\",\n    \"contactInfo\": \"string\",\n    \"url\": \"string\"\n  },\n  \"components\": [\n    \"string\"\n  ],\n  \"assemblies\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"culture\": \"string\",\n      \"publicKeyToken\": \"string\",\n      \"mappingFileId\": 0,\n      \"debugSymbolsKey\": \"string\"\n    }\n  ],\n  \"fields\": [\n    {\n      \"name\": \"string\",\n      \"value\": \"string\"\n    }\n  ],\n  \"features\": [\n    {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"key\": \"string\",\n      \"data\": \"string\"\n    }\n  ],\n  \"restrictions\": [\n    {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"properties\": {"},{"page":242,"heading":"Management.License","anchor":"managementlicense","text":"        \"property1\": \"string\",\n        \"property2\": \"string\"\n      },\n      \"customXmlContent\": \"string\"\n    }\n  ]\n}\nProperties"},{"page":242,"heading":"Management.License","anchor":"managementlicense","text":"Name | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\nlicenseId | string¦null | false | none | none\nlicenseType | string¦null | false | none | none\nformat | Licensing.LicenseFormat | false | none | none\ndescription | string¦null | false | none | none\ncreatedAt | string(date-time)¦null | false | none | none\nupdatedAt | string(date-time)¦null | false | none | none\nissueDate | string(date-time)¦null | false | none | none\nexpireDate | string(date-time)¦null | false | none | none\nsupportExpireDate | string(date-time)¦null | false | none | none\nrevoked | boolean¦null | false | none | none\ntrace | boolean¦null | false | none | none\nlicenseKey | string(byte)¦null | false | none | none\nmaxAllowedSites | integer(int32)¦null | false | none | none\nuserKey | string¦null | false | none | none\nlicensingMode | Management.LicensingMode | false | none | none\nlicenseeName | string¦null | false | none | none\nlicenseeCompany | string¦null | false | none | none\nlicenseeEmail | string¦null | false | none | none\nhash | string¦null | false | none | none\nmeta | string¦null | false | none | none\ntemplateId | integer(int32)¦null | false | none | none\nsignatureKeysId | integer(int32)¦null | false | none | none\ncustomerId | integer(int32)¦null | false | none | none\norderId | integer(int32)¦null | false | none | none\nproduct | Management.LicenseProduct | false | none | none\norder | Management.Order | false | none | none"},{"page":242,"heading":"Management.License","anchor":"managementlicense","text":"customer | Management.Customer | false | none | none\ntemplate | Management.LicenseTemplate | false | none | none\nlicensee | Management.Licensee | false | none | none\ncomponents | [string]¦null | false | none | none\nassemblies | [Management.Assembly]¦null | false | none | none\nfields | [Management.LicenseField]¦null | false | none | none\nfeatures | [Management.LicenseFeature]¦null | false | none | none\nrestrictions | [Management.LicenseRestriction]¦null | false | none | none"},{"page":242,"heading":"Management.LicenseFeature","anchor":"managementlicensefeature","text":"{\n  \"id\": \"string\",\n  \"name\": \"string\",\n  \"description\": \"string\",\n  \"expireDate\": \"2019-08-24T14:15:22Z\",\n  \"key\": \"string\",\n  \"data\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | string¦null | false | none | none\nname | string¦null | false | none | none\ndescription | string¦null | false | none | none\nexpireDate | string(date-time)¦null | false | none | none\nkey | string(byte)¦null | false | none | none\ndata | string(byte)¦null | false | none | none"},{"page":242,"heading":"Management.LicenseField","anchor":"managementlicensefield","text":"{\n  \"name\": \"string\",\n  \"value\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nname | string¦null | false | none | none\nvalue | string¦null | false | none | none"},{"page":242,"heading":"Management.LicenseProduct","anchor":"managementlicenseproduct","text":"{\n  \"id\": \"string\",\n  \"name\": \"string\",\n  \"version\": \"string\",\n  \"copyright\": \"string\",\n  \"url\": \"string\",\n  \"description\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | string¦null | false | none | none\nname | string¦null | false | none | none\nversion | string¦null | false | none | none\ncopyright | string¦null | false | none | none\nurl | string¦null | false | none | none\ndescription | string¦null | false | none | none"},{"page":242,"heading":"Management.LicenseRestriction","anchor":"managementlicenserestriction","text":"{\n  \"id\": \"string\",\n  \"name\": \"string\",\n  \"expireDate\": \"2019-08-24T14:15:22Z\",\n  \"properties\": {\n    \"property1\": \"string\",\n    \"property2\": \"string\"\n  },\n  \"customXmlContent\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | string¦null | false | none | none\nname | string¦null | false | none | none\nexpireDate | string(date-time)¦null | false | none | none\nproperties | object¦null | false | none | none\n» additionalProperties | string¦null | false | none | none\ncustomXmlContent | string¦null | false | none | none"},{"page":242,"heading":"Management.LicenseTemplate","anchor":"managementlicensetemplate","text":"{\n  \"id\": 0,\n  \"name\": \"string\",\n  \"code\": \"string\",\n  \"licenseType\": \"string\",\n  \"format\": 0,\n  \"licensingMode\": 0,\n  \"licenseFileName\": \"string\",\n  \"issueDate\": true,\n  \"expireDays\": 0,\n  \"supportDays\": 0,\n  \"generateKeyInfo\": true,\n  \"userKey\": \"string\",\n  \"description\": \"string\",\n  \"template\": \"string\",\n  \"productId\": 0,\n  \"signatureKeysId\": 0,\n  \"releaseId\": 0,\n  \"product\": {\n    \"id\": \"string\",\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"copyright\": \"string\",\n    \"url\": \"string\",\n    \"description\": \"string\"\n  },\n  \"components\": [\n    \"string\"\n  ],\n  \"assemblies\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"culture\": \"string\",\n      \"publicKeyToken\": \"string\",\n      \"mappingFileId\": 0,\n      \"debugSymbolsKey\": \"string\"\n    }\n  ],\n  \"fields\": [\n    {\n      \"name\": \"string\",\n      \"value\": \"string\"\n    }\n  ],\n  \"features\": [\n    {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"key\": \"string\",\n      \"data\": \"string\"\n    }\n  ],\n  \"restrictions\": [\n    {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"expireDate\": \"2019-08-24T14:15:22Z\",\n      \"properties\": {\n        \"property1\": \"string\",\n        \"property2\": \"string\"\n      },\n      \"customXmlContent\": \"string\"\n    }\n  ]\n}\nProperties"},{"page":242,"heading":"Management.LicenseTemplate","anchor":"managementlicensetemplate","text":"Name | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\nname | string¦null | false | none | none\ncode | string¦null | false | none | none\nlicenseType | string¦null | false | none | none\nformat | Licensing.LicenseFormat | false | none | none\nlicensingMode | Management.LicensingMode | false | none | none\nlicenseFileName | string¦null | false | none | none\nissueDate | boolean¦null | false | none | none\nexpireDays | integer(int32)¦null | false | none | none\nsupportDays | integer(int32)¦null | false | none | none\ngenerateKeyInfo | boolean¦null | false | none | none\nuserKey | string¦null | false | none | none\ndescription | string¦null | false | none | none\ntemplate | string(byte)¦null | false | none | none\nproductId | integer(int32)¦null | false | none | none\nsignatureKeysId | integer(int32)¦null | false | none | none\nreleaseId | integer(int32)¦null | false | none | none\nproduct | Management.LicenseProduct | false | none | none\ncomponents | [string]¦null | false | none | none\nassemblies | [Management.Assembly]¦null | false | none | none\nfields | [Management.LicenseField]¦null | false | none | none\nfeatures | [Management.LicenseFeature]¦null | false | none | none\nrestrictions | [Management.LicenseRestriction]¦null | false | none | none"},{"page":242,"heading":"Management.LicenseTrace","anchor":"managementlicensetrace","text":"{\n  \"id\": 0,\n  \"clientIp\": \"string\",\n  \"clientId\": \"string\",\n  \"clientName\": \"string\",\n  \"machineId\": \"string\",\n  \"createdDate\": \"2019-08-24T14:15:22Z\",\n  \"action\": 0,\n  \"geoLocation\": \"string\",\n  \"meta\": \"string\",\n  \"licenseId\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\nclientIp | string¦null | false | none | none\nclientId | string¦null | false | none | none\nclientName | string¦null | false | none | none\nmachineId | string¦null | false | none | none\ncreatedDate | string(date-time)¦null | false | none | none\naction | integer(int32)¦null | false | none | none\ngeoLocation | string¦null | false | none | none\nmeta | string¦null | false | none | none\nlicenseId | integer(int32)¦null | false | none | none"},{"page":242,"heading":"Management.Licensee","anchor":"managementlicensee","text":"{\n  \"name\": \"string\",\n  \"company\": \"string\",\n  \"contactInfo\": \"string\",\n  \"url\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nname | string¦null | false | none | none\ncompany | string¦null | false | none | none\ncontactInfo | string¦null | false | none | none\nurl | string¦null | false | none | none"},{"page":242,"heading":"Management.LicensingMode","anchor":"managementlicensingmode","text":"0\nProperties\nName | Type | Required | Restrictions | Description\nanonymous | integer(int32) | false | none | none\nEnumerated Values\nProperty | Value\nanonymous | 0\nanonymous | 1\nanonymous | 2"},{"page":242,"heading":"Management.ResolveLicenseTraceLocationsRequest","anchor":"managementresolvelicensetracelocationsrequest","text":"{\n  \"traceIds\": [\n    0\n  ],\n  \"limit\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\ntraceIds | [integer]¦null | false | none | none\nlimit | integer(int32)¦null | false | none | none"},{"page":242,"heading":"Management.ResolveLicenseTraceLocationsResponse","anchor":"managementresolvelicensetracelocationsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"resolvedCount\": 0,\n  \"unresolvedCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nresolvedCount | integer(int32)¦null | false | none | none\nunresolvedCount | integer(int32)¦null | false | none | none"},{"page":242,"heading":"Management.UpdateLicenseRequest","anchor":"managementupdatelicenserequest","text":"{\n  \"license\": {\n    \"id\": 0,\n    \"licenseId\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"description\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"issueDate\": \"2019-08-24T14:15:22Z\",\n    \"expireDate\": \"2019-08-24T14:15:22Z\",\n    \"supportExpireDate\": \"2019-08-24T14:15:22Z\",\n    \"revoked\": true,\n    \"trace\": true,\n    \"licenseKey\": \"string\",\n    \"maxAllowedSites\": 0,\n    \"userKey\": \"string\",\n    \"licensingMode\": 0,\n    \"licenseeName\": \"string\",\n    \"licenseeCompany\": \"string\",\n    \"licenseeEmail\": \"string\",\n    \"hash\": \"string\",\n    \"meta\": \"string\",\n    \"templateId\": 0,\n    \"signatureKeysId\": 0,\n    \"customerId\": 0,\n    \"orderId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\","},{"page":242,"heading":"Management.UpdateLicenseRequest","anchor":"managementupdatelicenserequest","text":"        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    },\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\","},{"page":242,"heading":"Management.UpdateLicenseRequest","anchor":"managementupdatelicenserequest","text":"      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"template\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"code\": \"string\",\n      \"licenseType\": \"string\",\n      \"format\": 0,\n      \"licensingMode\": 0,\n      \"licenseFileName\": \"string\",\n      \"issueDate\": true,\n      \"expireDays\": 0,\n      \"supportDays\": 0,\n      \"generateKeyInfo\": true,\n      \"userKey\": \"string\",\n      \"description\": \"string\",\n      \"template\": \"string\",\n      \"productId\": 0,\n      \"signatureKeysId\": 0,\n      \"releaseId\": 0,\n      \"product\": {"},{"page":242,"heading":"Management.UpdateLicenseRequest","anchor":"managementupdatelicenserequest","text":"        \"id\": \"string\",\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"copyright\": \"string\",\n        \"url\": \"string\",\n        \"description\": \"string\"\n      },\n      \"components\": [\n        \"string\"\n      ],\n      \"assemblies\": [\n        {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"version\": \"string\",\n          \"culture\": \"string\",\n          \"publicKeyToken\": \"string\",\n          \"mappingFileId\": 0,\n          \"debugSymbolsKey\": \"string\"\n        }\n      ],\n      \"fields\": [\n        {\n          \"name\": \"string\",\n          \"value\": \"string\"\n        }\n      ],\n      \"features\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"key\": \"string\",\n          \"data\": \"string\"\n        }\n      ],\n      \"restrictions\": [\n        {\n          \"id\": \"string\",\n          \"name\": \"string\",\n          \"expireDate\": \"2019-08-24T14:15:22Z\",\n          \"properties\": {\n            \"property1\": \"string\",\n            \"property2\": \"string\"\n          },\n          \"customXmlContent\": \"string\"\n        }\n      ]\n    },\n    \"licensee\": {\n      \"name\": \"string\",\n      \"company\": \"string\",\n      \"contactInfo\": \"string\",\n      \"url\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\","},{"page":242,"heading":"Management.UpdateLicenseRequest","anchor":"managementupdatelicenserequest","text":"        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nlicense | Management.License | false | none | none"},{"page":242,"heading":"Management.UpdateLicenseResponse","anchor":"managementupdatelicenseresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"licenseKeyId\": \"string\",\n  \"userKey\": \"string\",\n  \"licenseKey\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nlicenseKeyId | string¦null | false | none | none\nuserKey | string¦null | false | none | none\nlicenseKey | string(byte)¦null | false | none | none"},{"page":242,"heading":"Management.UpdateLicenseTemplateRequest","anchor":"managementupdatelicensetemplaterequest","text":"{\n  \"licenseTemplate\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"code\": \"string\",\n    \"licenseType\": \"string\",\n    \"format\": 0,\n    \"licensingMode\": 0,\n    \"licenseFileName\": \"string\",\n    \"issueDate\": true,\n    \"expireDays\": 0,\n    \"supportDays\": 0,\n    \"generateKeyInfo\": true,\n    \"userKey\": \"string\",\n    \"description\": \"string\",\n    \"template\": \"string\",\n    \"productId\": 0,\n    \"signatureKeysId\": 0,\n    \"releaseId\": 0,\n    \"product\": {\n      \"id\": \"string\",\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"copyright\": \"string\",\n      \"url\": \"string\",\n      \"description\": \"string\"\n    },\n    \"components\": [\n      \"string\"\n    ],\n    \"assemblies\": [\n      {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"version\": \"string\",\n        \"culture\": \"string\",\n        \"publicKeyToken\": \"string\",\n        \"mappingFileId\": 0,\n        \"debugSymbolsKey\": \"string\"\n      }\n    ],\n    \"fields\": [\n      {\n        \"name\": \"string\",\n        \"value\": \"string\"\n      }\n    ],\n    \"features\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"key\": \"string\",\n        \"data\": \"string\"\n      }\n    ],\n    \"restrictions\": [\n      {\n        \"id\": \"string\",\n        \"name\": \"string\",\n        \"expireDate\": \"2019-08-24T14:15:22Z\",\n        \"properties\": {\n          \"property1\": \"string\",\n          \"property2\": \"string\"\n        },\n        \"customXmlContent\": \"string\"\n      }\n    ]\n  }\n}\nProperties"},{"page":242,"heading":"Management.UpdateLicenseTemplateRequest","anchor":"managementupdatelicensetemplaterequest","text":"Name | Type | Required | Restrictions | Description\nlicenseTemplate | Management.LicenseTemplate | false | none | none"},{"page":242,"heading":"Management.UpdateLicenseTemplateResponse","anchor":"managementupdatelicensetemplateresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"template\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\ntemplate | string(byte)¦null | false | none | none"},{"page":243,"heading":"Management.Assembly","anchor":"managementassembly","text":"{\n  \"id\": 0,\n  \"name\": \"string\",\n  \"version\": \"string\",\n  \"culture\": \"string\",\n  \"publicKeyToken\": \"string\",\n  \"mappingFileId\": 0,\n  \"debugSymbolsKey\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\nname | string¦null | false | none | none\nversion | string¦null | false | none | none\nculture | string¦null | false | none | none\npublicKeyToken | string¦null | false | none | none\nmappingFileId | integer(int32)¦null | false | none | none\ndebugSymbolsKey | string¦null | false | none | none"},{"page":243,"heading":"Management.Contact","anchor":"managementcontact","text":"{\n  \"id\": 0,\n  \"title\": \"string\",\n  \"firstName\": \"string\",\n  \"lastName\": \"string\",\n  \"email\": \"string\",\n  \"phone\": \"string\",\n  \"mobile\": \"string\",\n  \"fax\": \"string\",\n  \"details\": \"string\",\n  \"notify\": true,\n  \"customerId\": 0,\n  \"meta\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\ntitle | string¦null | false | none | none\nfirstName | string¦null | false | none | none\nlastName | string¦null | false | none | none\nemail | string¦null | false | none | none\nphone | string¦null | false | none | none\nmobile | string¦null | false | none | none\nfax | string¦null | false | none | none\ndetails | string¦null | false | none | none\nnotify | boolean¦null | false | none | none\ncustomerId | integer(int32)¦null | false | none | none\nmeta | string¦null | false | none | none"},{"page":243,"heading":"Management.Customer","anchor":"managementcustomer","text":"{\n  \"id\": 0,\n  \"title\": \"string\",\n  \"firstName\": \"string\",\n  \"lastName\": \"string\",\n  \"company\": \"string\",\n  \"code\": \"string\",\n  \"vatCode\": \"string\",\n  \"invoiceCode\": \"string\",\n  \"rating\": 0,\n  \"createdAt\": \"2019-08-24T14:15:22Z\",\n  \"updatedAt\": \"2019-08-24T14:15:22Z\",\n  \"address\": \"string\",\n  \"address1\": \"string\",\n  \"address2\": \"string\",\n  \"postalCode\": \"string\",\n  \"region\": \"string\",\n  \"city\": \"string\",\n  \"country\": \"string\",\n  \"countryCode\": \"string\",\n  \"mapCoordinates\": \"string\",\n  \"mapZoomLevel\": 0.1,\n  \"email\": \"string\",\n  \"phone\": \"string\",\n  \"mobile\": \"string\",\n  \"fax\": \"string\",\n  \"website\": \"string\",\n  \"notes\": \"string\",\n  \"isReseller\": true,\n  \"image\": \"string\",\n  \"meta\": \"string\",\n  \"contacts\": [\n    {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"details\": \"string\",\n      \"notify\": true,\n      \"customerId\": 0,\n      \"meta\": \"string\"\n    }\n  ]\n}\nProperties"},{"page":243,"heading":"Management.Customer","anchor":"managementcustomer","text":"Name | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\ntitle | string¦null | false | none | none\nfirstName | string¦null | false | none | none\nlastName | string¦null | false | none | none\ncompany | string¦null | false | none | none\ncode | string¦null | false | none | none\nvatCode | string¦null | false | none | none\ninvoiceCode | string¦null | false | none | none\nrating | integer(int32)¦null | false | none | none\ncreatedAt | string(date-time)¦null | false | none | none\nupdatedAt | string(date-time)¦null | false | none | none\naddress | string¦null | false | none | none\naddress1 | string¦null | false | none | none\naddress2 | string¦null | false | none | none\npostalCode | string¦null | false | none | none\nregion | string¦null | false | none | none\ncity | string¦null | false | none | none\ncountry | string¦null | false | none | none\ncountryCode | string¦null | false | none | none\nmapCoordinates | string¦null | false | none | none\nmapZoomLevel | number(double)¦null | false | none | none\nemail | string¦null | false | none | none\nphone | string¦null | false | none | none\nmobile | string¦null | false | none | none\nfax | string¦null | false | none | none\nwebsite | string¦null | false | none | none\nnotes | string¦null | false | none | none\nisReseller | boolean¦null | false | none | none\nimage | string(byte)¦null | false | none | none\nmeta | string¦null | false | none | none\ncontacts | [Management.Contact]¦null | false | none | none"},{"page":243,"heading":"Management.DeleteAssemblyResponse","anchor":"managementdeleteassemblyresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.DeleteContactResponse","anchor":"managementdeletecontactresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.DeleteCustomerResponse","anchor":"managementdeletecustomerresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.DeleteOrderResponse","anchor":"managementdeleteorderresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.DeleteProductOrderResponse","anchor":"managementdeleteproductorderresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.DeleteProductResponse","anchor":"managementdeleteproductresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.DeleteResourceResponse","anchor":"managementdeleteresourceresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.GetAssembliesResponse","anchor":"managementgetassembliesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"assemblies\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"version\": \"string\",\n      \"culture\": \"string\",\n      \"publicKeyToken\": \"string\",\n      \"mappingFileId\": 0,\n      \"debugSymbolsKey\": \"string\"\n    }\n  ],\n  \"totalAssembliesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nassemblies | [Management.Assembly]¦null | false | none | none\ntotalAssembliesCount | integer(int32)¦null | false | none | none"},{"page":243,"heading":"Management.GetContactsResponse","anchor":"managementgetcontactsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"contacts\": [\n    {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"details\": \"string\",\n      \"notify\": true,\n      \"customerId\": 0,\n      \"meta\": \"string\"\n    }\n  ],\n  \"totalContactsCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\ncontacts | [Management.Contact]¦null | false | none | none\ntotalContactsCount | integer(int32) | false | none | none"},{"page":243,"heading":"Management.GetCustomerContactsResponse","anchor":"managementgetcustomercontactsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"contacts\": [\n    {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"details\": \"string\",\n      \"notify\": true,\n      \"customerId\": 0,\n      \"meta\": \"string\"\n    }\n  ],\n  \"totalContactsCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\ncontacts | [Management.Contact]¦null | false | none | none\ntotalContactsCount | integer(int32)¦null | false | none | none"},{"page":243,"heading":"Management.GetCustomerOrdersResponse","anchor":"managementgetcustomerordersresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"orders\": [\n    {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": ["},{"page":243,"heading":"Management.GetCustomerOrdersResponse","anchor":"managementgetcustomerordersresponse","text":"          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  ],\n  \"totalOrdersCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\norders | [Management.Order]¦null | false | none | none\ntotalOrdersCount | integer(int32)¦null | false | none | none"},{"page":243,"heading":"Management.GetCustomersResponse","anchor":"managementgetcustomersresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"customers\": [\n    {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    }\n  ],\n  \"totalCustomersCount\": 0\n}\nProperties"},{"page":243,"heading":"Management.GetCustomersResponse","anchor":"managementgetcustomersresponse","text":"Name | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\ncustomers | [Management.Customer]¦null | false | none | none\ntotalCustomersCount | integer(int32)¦null | false | none | none"},{"page":243,"heading":"Management.GetOrderProductsResponse","anchor":"managementgetorderproductsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"orderProducts\": [\n    {\n      \"productId\": 0,\n      \"orderId\": 0,\n      \"quantity\": 0,\n      \"unitPrice\": 0.1,\n      \"discount\": 0.1,\n      \"taxes\": 0.1,\n      \"description\": \"string\",\n      \"product\": {\n        \"id\": 0,\n        \"code\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"url\": \"string\",\n        \"copyright\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"image\": \"string\",\n        \"price\": 0.1,\n        \"resellerPrice\": 0.1,\n        \"currency\": \"string\",\n        \"signatureKeysId\": 0,\n        \"meta\": \"string\",\n        \"isApplication\": true,\n        \"updateChannelDefault\": \"string\",\n        \"renewalUrl\": \"string\",\n        \"signatureKeys\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"type\": \"string\",\n          \"code\": \"string\",\n          \"description\": \"string\",\n          \"source\": \"string\",\n          \"password\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"data\": \"string\",\n          \"dataFormat\": \"string\",\n          \"meta\": \"string\"\n        },\n        \"productOrders\": [\n          {}\n        ]\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\","},{"page":243,"heading":"Management.GetOrderProductsResponse","anchor":"managementgetorderproductsresponse","text":"        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\","},{"page":243,"heading":"Management.GetOrderProductsResponse","anchor":"managementgetorderproductsresponse","text":"              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      }\n    }\n  ],\n  \"totalOrderProductsCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\norderProducts | [Management.ProductOrder]¦null | false | none | none\ntotalOrderProductsCount | integer(int32)¦null | false | none | none"},{"page":243,"heading":"Management.GetOrdersResponse","anchor":"managementgetordersresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"orders\": [\n    {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\",\n      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": ["},{"page":243,"heading":"Management.GetOrdersResponse","anchor":"managementgetordersresponse","text":"          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  ],\n  \"totalOrdersCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\norders | [Management.Order]¦null | false | none | none\ntotalOrdersCount | integer(int32) | false | none | none"},{"page":243,"heading":"Management.GetProductOrdersResponse","anchor":"managementgetproductordersresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"productOrders\": [\n    {\n      \"productId\": 0,\n      \"orderId\": 0,\n      \"quantity\": 0,\n      \"unitPrice\": 0.1,\n      \"discount\": 0.1,\n      \"taxes\": 0.1,\n      \"description\": \"string\",\n      \"product\": {\n        \"id\": 0,\n        \"code\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"url\": \"string\",\n        \"copyright\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"image\": \"string\",\n        \"price\": 0.1,\n        \"resellerPrice\": 0.1,\n        \"currency\": \"string\",\n        \"signatureKeysId\": 0,\n        \"meta\": \"string\",\n        \"isApplication\": true,\n        \"updateChannelDefault\": \"string\",\n        \"renewalUrl\": \"string\",\n        \"signatureKeys\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"type\": \"string\",\n          \"code\": \"string\",\n          \"description\": \"string\",\n          \"source\": \"string\",\n          \"password\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"data\": \"string\",\n          \"dataFormat\": \"string\",\n          \"meta\": \"string\"\n        },\n        \"productOrders\": [\n          {}\n        ]\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\","},{"page":243,"heading":"Management.GetProductOrdersResponse","anchor":"managementgetproductordersresponse","text":"        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\",\n          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\","},{"page":243,"heading":"Management.GetProductOrdersResponse","anchor":"managementgetproductordersresponse","text":"              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      }\n    }\n  ],\n  \"totalProductOrdersCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nproductOrders | [Management.ProductOrder]¦null | false | none | none\ntotalProductOrdersCount | integer(int32)¦null | false | none | none"},{"page":243,"heading":"Management.GetProductsResponse","anchor":"managementgetproductsresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"products\": [\n    {\n      \"id\": 0,\n      \"code\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"url\": \"string\",\n      \"copyright\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"image\": \"string\",\n      \"price\": 0.1,\n      \"resellerPrice\": 0.1,\n      \"currency\": \"string\",\n      \"signatureKeysId\": 0,\n      \"meta\": \"string\",\n      \"isApplication\": true,\n      \"updateChannelDefault\": \"string\",\n      \"renewalUrl\": \"string\",\n      \"signatureKeys\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"type\": \"string\",\n        \"code\": \"string\",\n        \"description\": \"string\",\n        \"source\": \"string\",\n        \"password\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"data\": \"string\",\n        \"dataFormat\": \"string\",\n        \"meta\": \"string\"\n      },\n      \"productOrders\": [\n        {\n          \"productId\": 0,\n          \"orderId\": 0,\n          \"quantity\": 0,\n          \"unitPrice\": 0.1,\n          \"discount\": 0.1,\n          \"taxes\": 0.1,\n          \"description\": \"string\",\n          \"product\": {},\n          \"order\": {\n            \"id\": 0,\n            \"orderNumber\": \"string\",\n            \"status\": \"string\",\n            \"processedBy\": \"string\",\n            \"purchaseOrder\": \"string\",\n            \"total\": 0.1,\n            \"currency\": \"string\",\n            \"createdAt\": \"2019-08-24T14:15:22Z\","},{"page":243,"heading":"Management.GetProductsResponse","anchor":"managementgetproductsresponse","text":"            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"invoiceNumber\": \"string\",\n            \"paymentType\": \"string\",\n            \"paymentNumber\": \"string\",\n            \"paymentStatus\": \"string\",\n            \"paymentDate\": \"2019-08-24T14:15:22Z\",\n            \"description\": \"string\",\n            \"customerId\": 0,\n            \"customer\": {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"company\": \"string\",\n              \"code\": \"string\",\n              \"vatCode\": \"string\",\n              \"invoiceCode\": \"string\",\n              \"rating\": 0,\n              \"createdAt\": \"2019-08-24T14:15:22Z\",\n              \"updatedAt\": \"2019-08-24T14:15:22Z\",\n              \"address\": \"string\",\n              \"address1\": \"string\",\n              \"address2\": \"string\",\n              \"postalCode\": \"string\",\n              \"region\": \"string\",\n              \"city\": \"string\",\n              \"country\": \"string\",\n              \"countryCode\": \"string\",\n              \"mapCoordinates\": \"string\",\n              \"mapZoomLevel\": 0.1,\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"website\": \"string\",\n              \"notes\": \"string\",\n              \"isReseller\": true,\n              \"image\": \"string\",\n              \"meta\": \"string\",\n              \"contacts\": [\n                {\n                  \"id\": 0,"},{"page":243,"heading":"Management.GetProductsResponse","anchor":"managementgetproductsresponse","text":"                  \"title\": \"string\",\n                  \"firstName\": \"string\",\n                  \"lastName\": \"string\",\n                  \"email\": \"string\",\n                  \"phone\": \"string\",\n                  \"mobile\": \"string\",\n                  \"fax\": \"string\",\n                  \"details\": \"string\",\n                  \"notify\": true,\n                  \"customerId\": 0,\n                  \"meta\": \"string\"\n                }\n              ]\n            },\n            \"resellerId\": 0\n          }\n        }\n      ]\n    }\n  ],\n  \"totalProductsCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nproducts | [Management.Product]¦null | false | none | none\ntotalProductsCount | integer(int32) | false | none | none"},{"page":243,"heading":"Management.GetResourcesResponse","anchor":"managementgetresourcesresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"resources\": [\n    {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"code\": \"string\",\n      \"description\": \"string\",\n      \"source\": \"string\",\n      \"password\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"data\": \"string\",\n      \"dataFormat\": \"string\",\n      \"meta\": \"string\"\n    }\n  ],\n  \"totalResourcesCount\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\nresources | [Management.Resource]¦null | false | none | none\ntotalResourcesCount | integer(int32)¦null | false | none | none"},{"page":243,"heading":"Management.InsertAssemblyRequest","anchor":"managementinsertassemblyrequest","text":"{\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nassembly | Management.Assembly | false | none | none"},{"page":243,"heading":"Management.InsertAssemblyResponse","anchor":"managementinsertassemblyresponse","text":"{\n  \"assemblyId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nassemblyId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.InsertContactRequest","anchor":"managementinsertcontactrequest","text":"{\n  \"contact\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"details\": \"string\",\n    \"notify\": true,\n    \"customerId\": 0,\n    \"meta\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\ncontact | Management.Contact | false | none | none"},{"page":243,"heading":"Management.InsertContactResponse","anchor":"managementinsertcontactresponse","text":"{\n  \"contactId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\ncontactId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.InsertCustomerRequest","anchor":"managementinsertcustomerrequest","text":"{\n  \"customer\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"company\": \"string\",\n    \"code\": \"string\",\n    \"vatCode\": \"string\",\n    \"invoiceCode\": \"string\",\n    \"rating\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"address\": \"string\",\n    \"address1\": \"string\",\n    \"address2\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mapCoordinates\": \"string\",\n    \"mapZoomLevel\": 0.1,\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"website\": \"string\",\n    \"notes\": \"string\",\n    \"isReseller\": true,\n    \"image\": \"string\",\n    \"meta\": \"string\",\n    \"contacts\": [\n      {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"details\": \"string\",\n        \"notify\": true,\n        \"customerId\": 0,\n        \"meta\": \"string\"\n      }\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\ncustomer | Management.Customer | false | none | none"},{"page":243,"heading":"Management.InsertCustomerResponse","anchor":"managementinsertcustomerresponse","text":"{\n  \"customerId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"customerCode\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\ncustomerId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\ncustomerCode | string¦null | false | none | none"},{"page":243,"heading":"Management.InsertOrderRequest","anchor":"managementinsertorderrequest","text":"{\n  \"order\": {\n    \"id\": 0,\n    \"orderNumber\": \"string\",\n    \"status\": \"string\",\n    \"processedBy\": \"string\",\n    \"purchaseOrder\": \"string\",\n    \"total\": 0.1,\n    \"currency\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"invoiceNumber\": \"string\",\n    \"paymentType\": \"string\",\n    \"paymentNumber\": \"string\",\n    \"paymentStatus\": \"string\",\n    \"paymentDate\": \"2019-08-24T14:15:22Z\",\n    \"description\": \"string\",\n    \"customerId\": 0,\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\","},{"page":243,"heading":"Management.InsertOrderRequest","anchor":"managementinsertorderrequest","text":"          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"resellerId\": 0\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\norder | Management.Order | false | none | none"},{"page":243,"heading":"Management.InsertOrderResponse","anchor":"managementinsertorderresponse","text":"{\n  \"orderId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\",\n  \"orderNumber\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\norderId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none\norderNumber | string¦null | false | none | none"},{"page":243,"heading":"Management.InsertProductOrderRequest","anchor":"managementinsertproductorderrequest","text":"{\n  \"productOrder\": {\n    \"productId\": 0,\n    \"orderId\": 0,\n    \"quantity\": 0,\n    \"unitPrice\": 0.1,\n    \"discount\": 0.1,\n    \"taxes\": 0.1,\n    \"description\": \"string\",\n    \"product\": {\n      \"id\": 0,\n      \"code\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"url\": \"string\",\n      \"copyright\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"image\": \"string\",\n      \"price\": 0.1,\n      \"resellerPrice\": 0.1,\n      \"currency\": \"string\",\n      \"signatureKeysId\": 0,\n      \"meta\": \"string\",\n      \"isApplication\": true,\n      \"updateChannelDefault\": \"string\",\n      \"renewalUrl\": \"string\",\n      \"signatureKeys\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"type\": \"string\",\n        \"code\": \"string\",\n        \"description\": \"string\",\n        \"source\": \"string\",\n        \"password\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"data\": \"string\",\n        \"dataFormat\": \"string\",\n        \"meta\": \"string\"\n      },\n      \"productOrders\": [\n        {}\n      ]\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\","},{"page":243,"heading":"Management.InsertProductOrderRequest","anchor":"managementinsertproductorderrequest","text":"      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  }\n}\nProperties"},{"page":243,"heading":"Management.InsertProductOrderRequest","anchor":"managementinsertproductorderrequest","text":"Name | Type | Required | Restrictions | Description\nproductOrder | Management.ProductOrder | false | none | none"},{"page":243,"heading":"Management.InsertProductOrderResponse","anchor":"managementinsertproductorderresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.InsertProductRequest","anchor":"managementinsertproductrequest","text":"{\n  \"product\": {\n    \"id\": 0,\n    \"code\": \"string\",\n    \"name\": \"string\",\n    \"description\": \"string\",\n    \"url\": \"string\",\n    \"copyright\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"image\": \"string\",\n    \"price\": 0.1,\n    \"resellerPrice\": 0.1,\n    \"currency\": \"string\",\n    \"signatureKeysId\": 0,\n    \"meta\": \"string\",\n    \"isApplication\": true,\n    \"updateChannelDefault\": \"string\",\n    \"renewalUrl\": \"string\",\n    \"signatureKeys\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"code\": \"string\",\n      \"description\": \"string\",\n      \"source\": \"string\",\n      \"password\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"data\": \"string\",\n      \"dataFormat\": \"string\",\n      \"meta\": \"string\"\n    },\n    \"productOrders\": [\n      {\n        \"productId\": 0,\n        \"orderId\": 0,\n        \"quantity\": 0,\n        \"unitPrice\": 0.1,\n        \"discount\": 0.1,\n        \"taxes\": 0.1,\n        \"description\": \"string\",\n        \"product\": {},\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\","},{"page":243,"heading":"Management.InsertProductRequest","anchor":"managementinsertproductrequest","text":"          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\","},{"page":243,"heading":"Management.InsertProductRequest","anchor":"managementinsertproductrequest","text":"                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        }\n      }\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nproduct | Management.Product | false | none | none"},{"page":243,"heading":"Management.InsertProductResponse","anchor":"managementinsertproductresponse","text":"{\n  \"productId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nproductId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.InsertResourceRequest","anchor":"managementinsertresourcerequest","text":"{\n  \"resource\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"type\": \"string\",\n    \"code\": \"string\",\n    \"description\": \"string\",\n    \"source\": \"string\",\n    \"password\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"data\": \"string\",\n    \"dataFormat\": \"string\",\n    \"meta\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nresource | Management.Resource | false | none | none"},{"page":243,"heading":"Management.InsertResourceResponse","anchor":"managementinsertresourceresponse","text":"{\n  \"resourceId\": 0,\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nresourceId | integer(int32)¦null | false | none | none\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.Order","anchor":"managementorder","text":"{\n  \"id\": 0,\n  \"orderNumber\": \"string\",\n  \"status\": \"string\",\n  \"processedBy\": \"string\",\n  \"purchaseOrder\": \"string\",\n  \"total\": 0.1,\n  \"currency\": \"string\",\n  \"createdAt\": \"2019-08-24T14:15:22Z\",\n  \"updatedAt\": \"2019-08-24T14:15:22Z\",\n  \"invoiceNumber\": \"string\",\n  \"paymentType\": \"string\",\n  \"paymentNumber\": \"string\",\n  \"paymentStatus\": \"string\",\n  \"paymentDate\": \"2019-08-24T14:15:22Z\",\n  \"description\": \"string\",\n  \"customerId\": 0,\n  \"customer\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"company\": \"string\",\n    \"code\": \"string\",\n    \"vatCode\": \"string\",\n    \"invoiceCode\": \"string\",\n    \"rating\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"address\": \"string\",\n    \"address1\": \"string\",\n    \"address2\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mapCoordinates\": \"string\",\n    \"mapZoomLevel\": 0.1,\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"website\": \"string\",\n    \"notes\": \"string\",\n    \"isReseller\": true,\n    \"image\": \"string\",\n    \"meta\": \"string\",\n    \"contacts\": [\n      {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"details\": \"string\","},{"page":243,"heading":"Management.Order","anchor":"managementorder","text":"        \"notify\": true,\n        \"customerId\": 0,\n        \"meta\": \"string\"\n      }\n    ]\n  },\n  \"resellerId\": 0\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\norderNumber | string¦null | false | none | none\nstatus | string¦null | false | none | none\nprocessedBy | string¦null | false | none | none\npurchaseOrder | string¦null | false | none | none\ntotal | number(double)¦null | false | none | none\ncurrency | string¦null | false | none | none\ncreatedAt | string(date-time)¦null | false | none | none\nupdatedAt | string(date-time)¦null | false | none | none\ninvoiceNumber | string¦null | false | none | none\npaymentType | string¦null | false | none | none\npaymentNumber | string¦null | false | none | none\npaymentStatus | string¦null | false | none | none\npaymentDate | string(date-time)¦null | false | none | none\ndescription | string¦null | false | none | none\ncustomerId | integer(int32)¦null | false | none | none\ncustomer | Management.Customer | false | none | none\nresellerId | integer(int32)¦null | false | none | none"},{"page":243,"heading":"Management.Product","anchor":"managementproduct","text":"{\n  \"id\": 0,\n  \"code\": \"string\",\n  \"name\": \"string\",\n  \"description\": \"string\",\n  \"url\": \"string\",\n  \"copyright\": \"string\",\n  \"createdAt\": \"2019-08-24T14:15:22Z\",\n  \"image\": \"string\",\n  \"price\": 0.1,\n  \"resellerPrice\": 0.1,\n  \"currency\": \"string\",\n  \"signatureKeysId\": 0,\n  \"meta\": \"string\",\n  \"isApplication\": true,\n  \"updateChannelDefault\": \"string\",\n  \"renewalUrl\": \"string\",\n  \"signatureKeys\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"type\": \"string\",\n    \"code\": \"string\",\n    \"description\": \"string\",\n    \"source\": \"string\",\n    \"password\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"data\": \"string\",\n    \"dataFormat\": \"string\",\n    \"meta\": \"string\"\n  },\n  \"productOrders\": [\n    {\n      \"productId\": 0,\n      \"orderId\": 0,\n      \"quantity\": 0,\n      \"unitPrice\": 0.1,\n      \"discount\": 0.1,\n      \"taxes\": 0.1,\n      \"description\": \"string\",\n      \"product\": {\n        \"id\": 0,\n        \"code\": \"string\",\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"url\": \"string\",\n        \"copyright\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"image\": \"string\",\n        \"price\": 0.1,\n        \"resellerPrice\": 0.1,\n        \"currency\": \"string\",\n        \"signatureKeysId\": 0,\n        \"meta\": \"string\",\n        \"isApplication\": true,\n        \"updateChannelDefault\": \"string\",\n        \"renewalUrl\": \"string\",\n        \"signatureKeys\": {\n          \"id\": 0,\n          \"name\": \"string\",\n          \"type\": \"string\","},{"page":243,"heading":"Management.Product","anchor":"managementproduct","text":"          \"code\": \"string\",\n          \"description\": \"string\",\n          \"source\": \"string\",\n          \"password\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"data\": \"string\",\n          \"dataFormat\": \"string\",\n          \"meta\": \"string\"\n        },\n        \"productOrders\": []\n      },\n      \"order\": {\n        \"id\": 0,\n        \"orderNumber\": \"string\",\n        \"status\": \"string\",\n        \"processedBy\": \"string\",\n        \"purchaseOrder\": \"string\",\n        \"total\": 0.1,\n        \"currency\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"invoiceNumber\": \"string\",\n        \"paymentType\": \"string\",\n        \"paymentNumber\": \"string\",\n        \"paymentStatus\": \"string\",\n        \"paymentDate\": \"2019-08-24T14:15:22Z\",\n        \"description\": \"string\",\n        \"customerId\": 0,\n        \"customer\": {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"company\": \"string\",\n          \"code\": \"string\",\n          \"vatCode\": \"string\",\n          \"invoiceCode\": \"string\",\n          \"rating\": 0,\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"address\": \"string\",\n          \"address1\": \"string\",\n          \"address2\": \"string\",\n          \"postalCode\": \"string\",\n          \"region\": \"string\",\n          \"city\": \"string\",\n          \"country\": \"string\","},{"page":243,"heading":"Management.Product","anchor":"managementproduct","text":"          \"countryCode\": \"string\",\n          \"mapCoordinates\": \"string\",\n          \"mapZoomLevel\": 0.1,\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"website\": \"string\",\n          \"notes\": \"string\",\n          \"isReseller\": true,\n          \"image\": \"string\",\n          \"meta\": \"string\",\n          \"contacts\": [\n            {\n              \"id\": 0,\n              \"title\": \"string\",\n              \"firstName\": \"string\",\n              \"lastName\": \"string\",\n              \"email\": \"string\",\n              \"phone\": \"string\",\n              \"mobile\": \"string\",\n              \"fax\": \"string\",\n              \"details\": \"string\",\n              \"notify\": true,\n              \"customerId\": 0,\n              \"meta\": \"string\"\n            }\n          ]\n        },\n        \"resellerId\": 0\n      }\n    }\n  ]\n}\nProperties"},{"page":243,"heading":"Management.Product","anchor":"managementproduct","text":"Name | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\ncode | string¦null | false | none | none\nname | string¦null | false | none | none\ndescription | string¦null | false | none | none\nurl | string¦null | false | none | none\ncopyright | string¦null | false | none | none\ncreatedAt | string(date-time)¦null | false | none | none\nimage | string(byte)¦null | false | none | none\nprice | number(double)¦null | false | none | none\nresellerPrice | number(double)¦null | false | none | none\ncurrency | string¦null | false | none | none\nsignatureKeysId | integer(int32)¦null | false | none | none\nmeta | string¦null | false | none | none\nisApplication | boolean¦null | false | none | none\nupdateChannelDefault | string¦null | false | none | none\nrenewalUrl | string¦null | false | none | none\nsignatureKeys | Management.Resource | false | none | none\nproductOrders | [Management.ProductOrder]¦null | false | none | none"},{"page":243,"heading":"Management.ProductOrder","anchor":"managementproductorder","text":"{\n  \"productId\": 0,\n  \"orderId\": 0,\n  \"quantity\": 0,\n  \"unitPrice\": 0.1,\n  \"discount\": 0.1,\n  \"taxes\": 0.1,\n  \"description\": \"string\",\n  \"product\": {\n    \"id\": 0,\n    \"code\": \"string\",\n    \"name\": \"string\",\n    \"description\": \"string\",\n    \"url\": \"string\",\n    \"copyright\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"image\": \"string\",\n    \"price\": 0.1,\n    \"resellerPrice\": 0.1,\n    \"currency\": \"string\",\n    \"signatureKeysId\": 0,\n    \"meta\": \"string\",\n    \"isApplication\": true,\n    \"updateChannelDefault\": \"string\",\n    \"renewalUrl\": \"string\",\n    \"signatureKeys\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"code\": \"string\",\n      \"description\": \"string\",\n      \"source\": \"string\",\n      \"password\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"data\": \"string\",\n      \"dataFormat\": \"string\",\n      \"meta\": \"string\"\n    },\n    \"productOrders\": [\n      {\n        \"productId\": 0,\n        \"orderId\": 0,\n        \"quantity\": 0,\n        \"unitPrice\": 0.1,\n        \"discount\": 0.1,\n        \"taxes\": 0.1,\n        \"description\": \"string\",\n        \"product\": {},\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\","},{"page":243,"heading":"Management.ProductOrder","anchor":"managementproductorder","text":"          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\",\n          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\","},{"page":243,"heading":"Management.ProductOrder","anchor":"managementproductorder","text":"                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\",\n                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        }\n      }\n    ]\n  },\n  \"order\": {\n    \"id\": 0,\n    \"orderNumber\": \"string\",\n    \"status\": \"string\",\n    \"processedBy\": \"string\",\n    \"purchaseOrder\": \"string\",\n    \"total\": 0.1,\n    \"currency\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"invoiceNumber\": \"string\",\n    \"paymentType\": \"string\",\n    \"paymentNumber\": \"string\",\n    \"paymentStatus\": \"string\",\n    \"paymentDate\": \"2019-08-24T14:15:22Z\",\n    \"description\": \"string\",\n    \"customerId\": 0,\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\","},{"page":243,"heading":"Management.ProductOrder","anchor":"managementproductorder","text":"      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\",\n          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"resellerId\": 0\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nproductId | integer(int32)¦null | false | none | none\norderId | integer(int32)¦null | false | none | none\nquantity | integer(int32)¦null | false | none | none\nunitPrice | number(double)¦null | false | none | none\ndiscount | number(double)¦null | false | none | none\ntaxes | number(double)¦null | false | none | none\ndescription | string¦null | false | none | none\nproduct | Management.Product | false | none | none\norder | Management.Order | false | none | none"},{"page":243,"heading":"Management.Resource","anchor":"managementresource","text":"{\n  \"id\": 0,\n  \"name\": \"string\",\n  \"type\": \"string\",\n  \"code\": \"string\",\n  \"description\": \"string\",\n  \"source\": \"string\",\n  \"password\": \"string\",\n  \"createdAt\": \"2019-08-24T14:15:22Z\",\n  \"updatedAt\": \"2019-08-24T14:15:22Z\",\n  \"data\": \"string\",\n  \"dataFormat\": \"string\",\n  \"meta\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nid | integer(int32)¦null | false | none | none\nname | string¦null | false | none | none\ntype | string¦null | false | none | none\ncode | string¦null | false | none | none\ndescription | string¦null | false | none | none\nsource | string¦null | false | none | none\npassword | string¦null | false | none | none\ncreatedAt | string(date-time)¦null | false | none | none\nupdatedAt | string(date-time)¦null | false | none | none\ndata | string(byte)¦null | false | none | none\ndataFormat | string¦null | false | none | none\nmeta | string¦null | false | none | none"},{"page":243,"heading":"Management.UpdateAssemblyRequest","anchor":"managementupdateassemblyrequest","text":"{\n  \"assembly\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"version\": \"string\",\n    \"culture\": \"string\",\n    \"publicKeyToken\": \"string\",\n    \"mappingFileId\": 0,\n    \"debugSymbolsKey\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nassembly | Management.Assembly | false | none | none"},{"page":243,"heading":"Management.UpdateAssemblyResponse","anchor":"managementupdateassemblyresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.UpdateContactRequest","anchor":"managementupdatecontactrequest","text":"{\n  \"contact\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"details\": \"string\",\n    \"notify\": true,\n    \"customerId\": 0,\n    \"meta\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\ncontact | Management.Contact | false | none | none"},{"page":243,"heading":"Management.UpdateContactResponse","anchor":"managementupdatecontactresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.UpdateCustomerRequest","anchor":"managementupdatecustomerrequest","text":"{\n  \"customer\": {\n    \"id\": 0,\n    \"title\": \"string\",\n    \"firstName\": \"string\",\n    \"lastName\": \"string\",\n    \"company\": \"string\",\n    \"code\": \"string\",\n    \"vatCode\": \"string\",\n    \"invoiceCode\": \"string\",\n    \"rating\": 0,\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"address\": \"string\",\n    \"address1\": \"string\",\n    \"address2\": \"string\",\n    \"postalCode\": \"string\",\n    \"region\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\",\n    \"countryCode\": \"string\",\n    \"mapCoordinates\": \"string\",\n    \"mapZoomLevel\": 0.1,\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"mobile\": \"string\",\n    \"fax\": \"string\",\n    \"website\": \"string\",\n    \"notes\": \"string\",\n    \"isReseller\": true,\n    \"image\": \"string\",\n    \"meta\": \"string\",\n    \"contacts\": [\n      {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"details\": \"string\",\n        \"notify\": true,\n        \"customerId\": 0,\n        \"meta\": \"string\"\n      }\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\ncustomer | Management.Customer | false | none | none"},{"page":243,"heading":"Management.UpdateCustomerResponse","anchor":"managementupdatecustomerresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.UpdateOrderRequest","anchor":"managementupdateorderrequest","text":"{\n  \"order\": {\n    \"id\": 0,\n    \"orderNumber\": \"string\",\n    \"status\": \"string\",\n    \"processedBy\": \"string\",\n    \"purchaseOrder\": \"string\",\n    \"total\": 0.1,\n    \"currency\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"invoiceNumber\": \"string\",\n    \"paymentType\": \"string\",\n    \"paymentNumber\": \"string\",\n    \"paymentStatus\": \"string\",\n    \"paymentDate\": \"2019-08-24T14:15:22Z\",\n    \"description\": \"string\",\n    \"customerId\": 0,\n    \"customer\": {\n      \"id\": 0,\n      \"title\": \"string\",\n      \"firstName\": \"string\",\n      \"lastName\": \"string\",\n      \"company\": \"string\",\n      \"code\": \"string\",\n      \"vatCode\": \"string\",\n      \"invoiceCode\": \"string\",\n      \"rating\": 0,\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"address\": \"string\",\n      \"address1\": \"string\",\n      \"address2\": \"string\",\n      \"postalCode\": \"string\",\n      \"region\": \"string\",\n      \"city\": \"string\",\n      \"country\": \"string\",\n      \"countryCode\": \"string\",\n      \"mapCoordinates\": \"string\",\n      \"mapZoomLevel\": 0.1,\n      \"email\": \"string\",\n      \"phone\": \"string\",\n      \"mobile\": \"string\",\n      \"fax\": \"string\",\n      \"website\": \"string\",\n      \"notes\": \"string\",\n      \"isReseller\": true,\n      \"image\": \"string\",\n      \"meta\": \"string\",\n      \"contacts\": [\n        {\n          \"id\": 0,\n          \"title\": \"string\",\n          \"firstName\": \"string\",\n          \"lastName\": \"string\",\n          \"email\": \"string\","},{"page":243,"heading":"Management.UpdateOrderRequest","anchor":"managementupdateorderrequest","text":"          \"phone\": \"string\",\n          \"mobile\": \"string\",\n          \"fax\": \"string\",\n          \"details\": \"string\",\n          \"notify\": true,\n          \"customerId\": 0,\n          \"meta\": \"string\"\n        }\n      ]\n    },\n    \"resellerId\": 0\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\norder | Management.Order | false | none | none"},{"page":243,"heading":"Management.UpdateOrderResponse","anchor":"managementupdateorderresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.UpdateProductOrderRequest","anchor":"managementupdateproductorderrequest","text":"{\n  \"productOrder\": {\n    \"productId\": 0,\n    \"orderId\": 0,\n    \"quantity\": 0,\n    \"unitPrice\": 0.1,\n    \"discount\": 0.1,\n    \"taxes\": 0.1,\n    \"description\": \"string\",\n    \"product\": {\n      \"id\": 0,\n      \"code\": \"string\",\n      \"name\": \"string\",\n      \"description\": \"string\",\n      \"url\": \"string\",\n      \"copyright\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"image\": \"string\",\n      \"price\": 0.1,\n      \"resellerPrice\": 0.1,\n      \"currency\": \"string\",\n      \"signatureKeysId\": 0,\n      \"meta\": \"string\",\n      \"isApplication\": true,\n      \"updateChannelDefault\": \"string\",\n      \"renewalUrl\": \"string\",\n      \"signatureKeys\": {\n        \"id\": 0,\n        \"name\": \"string\",\n        \"type\": \"string\",\n        \"code\": \"string\",\n        \"description\": \"string\",\n        \"source\": \"string\",\n        \"password\": \"string\",\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"data\": \"string\",\n        \"dataFormat\": \"string\",\n        \"meta\": \"string\"\n      },\n      \"productOrders\": [\n        {}\n      ]\n    },\n    \"order\": {\n      \"id\": 0,\n      \"orderNumber\": \"string\",\n      \"status\": \"string\",\n      \"processedBy\": \"string\",\n      \"purchaseOrder\": \"string\",\n      \"total\": 0.1,\n      \"currency\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"invoiceNumber\": \"string\",\n      \"paymentType\": \"string\",\n      \"paymentNumber\": \"string\",\n      \"paymentStatus\": \"string\","},{"page":243,"heading":"Management.UpdateProductOrderRequest","anchor":"managementupdateproductorderrequest","text":"      \"paymentDate\": \"2019-08-24T14:15:22Z\",\n      \"description\": \"string\",\n      \"customerId\": 0,\n      \"customer\": {\n        \"id\": 0,\n        \"title\": \"string\",\n        \"firstName\": \"string\",\n        \"lastName\": \"string\",\n        \"company\": \"string\",\n        \"code\": \"string\",\n        \"vatCode\": \"string\",\n        \"invoiceCode\": \"string\",\n        \"rating\": 0,\n        \"createdAt\": \"2019-08-24T14:15:22Z\",\n        \"updatedAt\": \"2019-08-24T14:15:22Z\",\n        \"address\": \"string\",\n        \"address1\": \"string\",\n        \"address2\": \"string\",\n        \"postalCode\": \"string\",\n        \"region\": \"string\",\n        \"city\": \"string\",\n        \"country\": \"string\",\n        \"countryCode\": \"string\",\n        \"mapCoordinates\": \"string\",\n        \"mapZoomLevel\": 0.1,\n        \"email\": \"string\",\n        \"phone\": \"string\",\n        \"mobile\": \"string\",\n        \"fax\": \"string\",\n        \"website\": \"string\",\n        \"notes\": \"string\",\n        \"isReseller\": true,\n        \"image\": \"string\",\n        \"meta\": \"string\",\n        \"contacts\": [\n          {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"details\": \"string\",\n            \"notify\": true,\n            \"customerId\": 0,\n            \"meta\": \"string\"\n          }\n        ]\n      },\n      \"resellerId\": 0\n    }\n  }\n}\nProperties"},{"page":243,"heading":"Management.UpdateProductOrderRequest","anchor":"managementupdateproductorderrequest","text":"Name | Type | Required | Restrictions | Description\nproductOrder | Management.ProductOrder | false | none | none"},{"page":243,"heading":"Management.UpdateProductOrderResponse","anchor":"managementupdateproductorderresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.UpdateProductRequest","anchor":"managementupdateproductrequest","text":"{\n  \"product\": {\n    \"id\": 0,\n    \"code\": \"string\",\n    \"name\": \"string\",\n    \"description\": \"string\",\n    \"url\": \"string\",\n    \"copyright\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"image\": \"string\",\n    \"price\": 0.1,\n    \"resellerPrice\": 0.1,\n    \"currency\": \"string\",\n    \"signatureKeysId\": 0,\n    \"meta\": \"string\",\n    \"isApplication\": true,\n    \"updateChannelDefault\": \"string\",\n    \"renewalUrl\": \"string\",\n    \"signatureKeys\": {\n      \"id\": 0,\n      \"name\": \"string\",\n      \"type\": \"string\",\n      \"code\": \"string\",\n      \"description\": \"string\",\n      \"source\": \"string\",\n      \"password\": \"string\",\n      \"createdAt\": \"2019-08-24T14:15:22Z\",\n      \"updatedAt\": \"2019-08-24T14:15:22Z\",\n      \"data\": \"string\",\n      \"dataFormat\": \"string\",\n      \"meta\": \"string\"\n    },\n    \"productOrders\": [\n      {\n        \"productId\": 0,\n        \"orderId\": 0,\n        \"quantity\": 0,\n        \"unitPrice\": 0.1,\n        \"discount\": 0.1,\n        \"taxes\": 0.1,\n        \"description\": \"string\",\n        \"product\": {},\n        \"order\": {\n          \"id\": 0,\n          \"orderNumber\": \"string\",\n          \"status\": \"string\",\n          \"processedBy\": \"string\",\n          \"purchaseOrder\": \"string\",\n          \"total\": 0.1,\n          \"currency\": \"string\",\n          \"createdAt\": \"2019-08-24T14:15:22Z\",\n          \"updatedAt\": \"2019-08-24T14:15:22Z\",\n          \"invoiceNumber\": \"string\",\n          \"paymentType\": \"string\",\n          \"paymentNumber\": \"string\",\n          \"paymentStatus\": \"string\","},{"page":243,"heading":"Management.UpdateProductRequest","anchor":"managementupdateproductrequest","text":"          \"paymentDate\": \"2019-08-24T14:15:22Z\",\n          \"description\": \"string\",\n          \"customerId\": 0,\n          \"customer\": {\n            \"id\": 0,\n            \"title\": \"string\",\n            \"firstName\": \"string\",\n            \"lastName\": \"string\",\n            \"company\": \"string\",\n            \"code\": \"string\",\n            \"vatCode\": \"string\",\n            \"invoiceCode\": \"string\",\n            \"rating\": 0,\n            \"createdAt\": \"2019-08-24T14:15:22Z\",\n            \"updatedAt\": \"2019-08-24T14:15:22Z\",\n            \"address\": \"string\",\n            \"address1\": \"string\",\n            \"address2\": \"string\",\n            \"postalCode\": \"string\",\n            \"region\": \"string\",\n            \"city\": \"string\",\n            \"country\": \"string\",\n            \"countryCode\": \"string\",\n            \"mapCoordinates\": \"string\",\n            \"mapZoomLevel\": 0.1,\n            \"email\": \"string\",\n            \"phone\": \"string\",\n            \"mobile\": \"string\",\n            \"fax\": \"string\",\n            \"website\": \"string\",\n            \"notes\": \"string\",\n            \"isReseller\": true,\n            \"image\": \"string\",\n            \"meta\": \"string\",\n            \"contacts\": [\n              {\n                \"id\": 0,\n                \"title\": \"string\",\n                \"firstName\": \"string\",\n                \"lastName\": \"string\",\n                \"email\": \"string\",\n                \"phone\": \"string\",\n                \"mobile\": \"string\",\n                \"fax\": \"string\",\n                \"details\": \"string\","},{"page":243,"heading":"Management.UpdateProductRequest","anchor":"managementupdateproductrequest","text":"                \"notify\": true,\n                \"customerId\": 0,\n                \"meta\": \"string\"\n              }\n            ]\n          },\n          \"resellerId\": 0\n        }\n      }\n    ]\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nproduct | Management.Product | false | none | none"},{"page":243,"heading":"Management.UpdateProductResponse","anchor":"managementupdateproductresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"},{"page":243,"heading":"Management.UpdateResourceRequest","anchor":"managementupdateresourcerequest","text":"{\n  \"resource\": {\n    \"id\": 0,\n    \"name\": \"string\",\n    \"type\": \"string\",\n    \"code\": \"string\",\n    \"description\": \"string\",\n    \"source\": \"string\",\n    \"password\": \"string\",\n    \"createdAt\": \"2019-08-24T14:15:22Z\",\n    \"updatedAt\": \"2019-08-24T14:15:22Z\",\n    \"data\": \"string\",\n    \"dataFormat\": \"string\",\n    \"meta\": \"string\"\n  }\n}\nProperties\nName | Type | Required | Restrictions | Description\nresource | Management.Resource | false | none | none"},{"page":243,"heading":"Management.UpdateResourceResponse","anchor":"managementupdateresourceresponse","text":"{\n  \"success\": true,\n  \"code\": 0,\n  \"message\": \"string\"\n}\nProperties\nName | Type | Required | Restrictions | Description\nsuccess | boolean | false | none | none\ncode | integer(int32)¦null | false | none | none\nmessage | string¦null | false | none | none"}]}