SolarWinds.Api
2026.5.57
dotnet add package SolarWinds.Api --version 2026.5.57
NuGet\Install-Package SolarWinds.Api -Version 2026.5.57
<PackageReference Include="SolarWinds.Api" Version="2026.5.57" />
<PackageVersion Include="SolarWinds.Api" Version="2026.5.57" />
<PackageReference Include="SolarWinds.Api" />
paket add SolarWinds.Api --version 2026.5.57
#r "nuget: SolarWinds.Api, 2026.5.57"
#:package SolarWinds.Api@2026.5.57
#addin nuget:?package=SolarWinds.Api&version=2026.5.57
#tool nuget:?package=SolarWinds.Api&version=2026.5.57
SolarWinds.Api NuGet package
A .NET API client for SolarWinds Orion and Service Desk.
OpenAPI UI (GitHub Pages)
This repository publishes an interactive Swagger UI for the generated Service Desk OpenAPI document via GitHub Pages.
- Workflow:
.github/workflows/gh-pages.yml - UI source:
docs/openapi/index.html - OpenAPI document:
SolarWinds.ServiceDesk.OpenApi.json - Live UI: https://panoramicdata.github.io/SolarWinds.Api/
To regenerate the OpenAPI document after changing the API surface, run:
dotnet run --project ./SolarWinds.Api.OpenApi/SolarWinds.Api.OpenApi.csproj --configuration Release -- ./SolarWinds.ServiceDesk.OpenApi.json
The document version is the version.json version family (e.g. 2026.5) without git height, so regeneration is deterministic: the committed document only changes when the API surface (or version.json) does.
After enabling GitHub Pages with Build and deployment: GitHub Actions, the site is published at:
https://<org-or-user>.github.io/SolarWinds.Api/
Breaking Changes
Version 2026.6.13
The SolarWindsClient has been deprecated and replaced by SolarWindsOrionClient. The new client uses an options pattern for configuration, providing more flexibility for setting credentials, proxy settings, and logging.
The SolarWindsClient is now marked as obsolete and its usage will result in a compile-time error.
- "But that Breaks SEMVER!"
- Yep.
- "But... but..."
- We do this for free. Update your code.
Installation
Install the NuGet package:
Install-Package SolarWinds.Api
Configuration
This library expects an appsettings.json file in your project's output directory with the following structure for connecting to SolarWinds Orion:
{
"Hostname": "YOUR_ORION_HOSTNAME",
"Username": "YOUR_ORION_USERNAME",
"Password": "YOUR_ORION_PASSWORD",
"IgnoreSslCertificateErrors": true
}
For the SolarWinds Service Desk API, see API documentation and the configuration below.
Usage
Initializing the Client
SolarWinds Orion Client
The SolarWindsOrionClient is configured using the SolarWindsOrionClientOptions class.
using SolarWinds.Api;
using Microsoft.Extensions.Logging;
var options = new SolarWindsOrionClientOptions
{
Hostname = "YOUR_ORION_HOSTNAME",
Username = "YOUR_ORION_USERNAME",
Password = "YOUR_ORION_PASSWORD",
IgnoreSslCertificateErrors = true,
Logger = logger, // Your ILogger instance
// ProxySettings = new HttpProxySettings { ... } // Optional
};
var client = new SolarWindsOrionClient(options);
SolarWinds Service Desk Client
The SolarWindsServiceDeskClient requires options to be passed during initialization.
using SolarWinds.Api;
using SolarWinds.Api.ServiceDesk;
var serviceDeskOptions = new SolarWindsServiceDeskClientOptions
{
// Regional base URLs:
// US: https://api.samanage.com
// EU: https://apieu.samanage.com
// APJ: https://apiau.samanage.com
BaseUrl = "https://api.samanage.com",
AccessToken = "YOUR_SERVICEDESK_ACCESS_TOKEN"
};
var serviceDeskClient = new SolarWindsServiceDeskClient(serviceDeskOptions);
Making API Calls
SolarWinds Orion API Examples
Get Nodes
using SolarWinds.Api.Orion;
using SolarWinds.Api.Queries;
using System.Collections.Generic;
using System.Threading.Tasks;
// Get all nodes
var allNodes = await client.GetAllAsync<Node>();
// Get nodes with a filter
var filteredNodes = await client.FilterQueryAsync(new FilterQuery<Node>
{
Constraints = new List<Constraint>
{
new Eq(nameof(Node.Status), 1) // Filter by status (e.g., Up)
},
OrderBy = nameof(Node.Caption),
Take = 10
});
// Get nodes using SQL query
var sqlNodes = await client.SqlQueryAsync<Node>(new SqlQuery
{
Sql = "SELECT TOP 5 Caption, IPAddress FROM Orion.Nodes WHERE Status = @status",
Parameters = new Dictionary<string, object> { { "status", 1 } }
});
Get Custom Properties
using SolarWinds.Api.Orion;
using SolarWinds.Api.Queries;
// Get all custom properties
var customProperties = await client.GetAllAsync<CustomProperty>();
// Get custom property values
var customPropertyValues = await client.GetAllAsync<CustomPropertyValue>();
SolarWinds Service Desk API Examples
Get Incidents
using SolarWinds.Api.ServiceDesk.Models;
// Get incidents using a query request
var allIncidents = await serviceDeskClient.Incidents.GetAsync(new GetIncidentsRequest
{
Layout = ResponseLayout.Short,
Page = 1,
PerPage = 50
}, CancellationToken.None);
// Get a specific incident by ID (layout is required)
var incident = await serviceDeskClient.Incidents.GetAsync(123, ResponseLayout.Long, CancellationToken.None);
Get Users
using SolarWinds.Api.ServiceDesk.Models;
// Get all users
var allUsers = await serviceDeskClient.Users.GetAllAsync();
// Get a specific user by ID (layout is required)
var user = await serviceDeskClient.Users.GetAsync(456, ResponseLayout.Short, CancellationToken.None);
Breaking Changes (Current Migration Wave)
This release contains wide-reaching breaking changes across the Service Desk client to align with official API behavior and payload shapes.
What changed
- GET-by-ID methods now require layout explicitly:
GetAsync(int id, ResponseLayout layout, CancellationToken cancellationToken)
- Object-scoped endpoints no longer take free-form strings for
objectType:- now use
ObjectType objectTypeenum values (serialized viaEnumMemberstring mappings).
- now use
- Many write operations now require wrapper request payloads instead of raw entity bodies:
- examples:
IncidentCreateRequest,IncidentUpdateRequest,CategoryCreateRequest,ContractUpdateRequest, and similar domain-specific request models.
- examples:
- List/query reads in migrated domains now use typed query request models:
- examples:
GetIncidentsRequest,GetChangesRequest,GetContractsRequest.
- examples:
- Legacy convenience signatures are being removed as domains are migrated:
- examples:
GetAllAsync(...),GetPageAsync(...).
- examples:
Why this changed
- To match Service Desk OpenAPI paths and payload roots.
- To make request intent explicit and strongly typed.
- To reduce ambiguous signatures and reduce runtime shape mismatches.
Service Desk Migration Guide
Use this as a checklist when upgrading existing code.
1) Update GET-by-ID calls to include layout
Before:
var category = await serviceDeskClient.Categories.GetAsync(categoryId, cancellationToken);
After:
var category = await serviceDeskClient.Categories.GetAsync(categoryId, ResponseLayout.Short, cancellationToken);
2) Replace string objectType with ObjectType enum
Before:
var comment = await serviceDeskClient.Comments.CreateAsync("incidents", incidentId, request, cancellationToken);
After:
var comment = await serviceDeskClient.Comments.CreateAsync(ObjectType.Incidents, incidentId, request, cancellationToken);
3) Replace raw write bodies with wrapper requests
Before:
var updated = await serviceDeskClient.Incidents.UpdateAsync(incidentId, incident, cancellationToken);
After:
var updated = await serviceDeskClient.Incidents.UpdateAsync(
incidentId,
new IncidentUpdateRequest
{
Incident = new IncidentWriteFields
{
Name = "Updated title"
}
},
cancellationToken);
4) Use typed query requests for list endpoints
Before:
var changes = await serviceDeskClient.Changes.GetAllAsync(cancellationToken);
After:
var changes = await serviceDeskClient.Changes.GetAsync(new GetChangesRequest
{
Layout = ResponseLayout.Long
}, cancellationToken);
5) Confirm date and enum serialization assumptions
- Date query values use
MMM d yyyyformatting. - Enums are serialized using
EnumMembervalues where present.
6) Upgrade strategy for consumers
- Compile and fix all Service Desk call sites by signature.
- Start with read-path calls (
GetAsync) then write-path wrappers. - Run integration tests against your tenant, especially workflows touching category/group/department payloads.
Querying
The library provides flexible querying capabilities for the Orion API using FilterQuery and SqlQuery.
FilterQuery<T>
Allows filtering, ordering, and pagination using strongly-typed properties.
using SolarWinds.Api.Queries;
using SolarWinds.Api.Orion;
using System.Collections.Generic;
var query = new FilterQuery<Node>
{
Constraints = new List<Constraint>
{
new Gt(nameof(Node.CpuLoad), 50), // CPU Load greater than 50
new Le(nameof(Node.MemoryUsed), 80) // Memory Used less than or equal to 80
},
OrderBy = nameof(Node.Caption),
Skip = 0,
Take = 20
};
var result = await client.FilterQueryAsync(query);
Supported constraints: Eq, Ne, Gt, Ge, Lt, Le.
SqlQuery
For more complex queries, you can use raw SWQL (SolarWinds Query Language).
using SolarWinds.Api.Queries;
using System.Collections.Generic;
var sqlQuery = new SqlQuery
{
Sql = "SELECT N.Caption, N.IPAddress, CP.Value FROM Orion.Nodes N JOIN Orion.NodesCustomProperties CP ON N.NodeID = CP.NodeID WHERE CP.CustomPropertyID = @cpId",
Parameters = new Dictionary<string, object> { { "cpId", 123 } }
};
var result = await client.SqlQueryAsync<dynamic>(sqlQuery); // You can use dynamic or a custom class
Error Handling
API calls may throw SolarWindsApiException for API-specific errors or SolarWindsApiHttpException for HTTP-related errors.
using SolarWinds.Api.Exceptions;
using System;
using System.Net.Http;
try
{
// Your API call here
await client.GetAllAsync<Node>();
}
catch (SolarWindsApiHttpException ex)
{
Console.WriteLine($"HTTP Error: {ex.StatusCode} - {ex.Message}");
Console.WriteLine($"Response Body: {ex.Content}");
}
catch (SolarWindsApiException ex)
{
Console.WriteLine($"API Error: {ex.Message}");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Network Error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"An unexpected error occurred: {ex.Message}");
}
SolarWinds Service Desk API Reference
- API Documentation
- Authentication header:
X-Samanage-Authorization: Bearer <token> - Accept header:
application/vnd.samanage.v2.1+json - Regional base URLs:
| Region | Base URL |
|--------|----------|
| US |
https://api.samanage.com| | EU |https://apieu.samanage.com| | APJ |https://apiau.samanage.com|
Test Credentials
The test project uses .NET User Secrets to store credentials. To run the ServiceDesk integration tests:
cd SolarWinds.Api.Test
dotnet user-secrets set "ServiceDesk:BaseUrl" "https://api.samanage.com"
dotnet user-secrets set "ServiceDesk:AccessToken" "<your-token>"
Contributing
Contributions are welcome! Please feel free to open issues or submit pull requests.
License
This project is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.11)
- Newtonsoft.Json (>= 13.0.4)
- Refit (>= 15.2.0)
- Refit.HttpClientFactory (>= 15.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2026.5.57 | 158 | 9/3/2026 |
| 2026.5.49 | 680 | 8/28/2026 |
| 2026.5.44 | 1,216 | 7/2/2026 |
| 2026.5.43 | 868 | 7/2/2026 |
| 2026.5.39 | 542 | 6/13/2026 |
| 2026.5.32 | 192 | 6/8/2026 |
| 2026.5.30 | 157 | 6/8/2026 |
| 2026.5.24 | 178 | 6/6/2026 |
| 2026.5.21 | 234 | 6/1/2026 |
| 2026.5.18 | 167 | 5/31/2026 |
| 2025.2.50 | 166 | 5/30/2026 |
| 2025.2.47 | 157 | 5/30/2026 |
| 2025.2.44 | 161 | 5/30/2026 |
| 2025.2.42 | 172 | 5/30/2026 |
| 2025.2.17 | 22,734 | 4/29/2026 |
| 2025.2.16 | 22,713 | 4/16/2026 |
| 2025.2.11 | 26,091 | 3/31/2026 |
| 2025.2.8 | 25,448 | 3/19/2026 |
| 2025.2.7 | 25,391 | 3/19/2026 |
| 2025.2.4 | 46,326 | 7/14/2025 |
Security fix: sensitive HTTP headers are now redacted in diagnostic output.
Previously LoggingDelegatingHandler wrote every request and response header verbatim into
its Debug level log message. Service Desk authenticates with an X-Samanage-Authorization
header, so a usable access token was written out whenever a consumer ran at Debug, and was
retained for the life of its log store.
Authorization, Proxy-Authorization, Cookie, Set-Cookie and common API key headers are now
redacted, along with any vendor-prefixed variant whose name ends in "Authorization", which
is what covers this client's own credential. The authentication scheme and the credential
length are retained, so requests remain diagnosable without exposing the credential.
The log message format is otherwise unchanged. Consumers should upgrade and then review
existing Debug logs for previously captured tokens.
See CHANGELOG.md for release notes.