🚀 43 typed domain clients — vehicles, drivers, routes, compliance, safety, and every other Samsara API domain
📄 Automatic pagination — IAsyncEnumerable<T> handles cursor-based paging transparently
🔒 DI-first design — single AddSamsaraClient() call wires up everything
⚡ Source-generated JSON — zero-reflection System.Text.Json serialization via compile-time context
🛡️ Built-in resilience — exponential backoff with jitter via Microsoft.Extensions.Http.Resilience
💡 Typed exceptions — SamsaraBadRequestException, SamsaraRateLimitException, and more
🔄 Dynamic token provider — OAuth 2.0, rotating tokens, and custom auth flows
🌍 Multi-region — US and EU endpoints with a single property switch
📦 Immutable models — every request and response uses record types
🔍 Source Link — step into library source during debugging
dotnet add package Samsara.Sdk
Requirements: .NET 8.0 or later
With Dependency Injection (ASP.NET Core / Generic Host)
// Program.cs
using Samsara . Sdk . DependencyInjection ;
builder . Services . AddSamsaraClient ( options =>
{
options . ApiToken = builder . Configuration [ "Samsara:ApiToken" ] ;
} ) ;
Inject ISamsaraClient anywhere in your application:
public class FleetService ( ISamsaraClient samsara )
{
public async Task < List < Vehicle > > GetAllVehiclesAsync ( CancellationToken ct )
{
var vehicles = new List < Vehicle > ( ) ;
await foreach ( var vehicle in samsara . Vehicles . ListAsync ( ct ) )
vehicles . Add ( vehicle ) ;
return vehicles ;
}
}
Without Dependency Injection
using Microsoft . Extensions . DependencyInjection ;
using Samsara . Sdk . DependencyInjection ;
var services = new ServiceCollection ( ) ;
services . AddSamsaraClient ( options => options . ApiToken = "samsara_api_..." ) ;
var provider = services . BuildServiceProvider ( ) ;
var samsara = provider . GetRequiredService < ISamsaraClient > ( ) ;
await foreach ( var driver in samsara . Drivers . ListAsync ( ) )
Console . WriteLine ( driver . Name ) ;
Configure via AddSamsaraClient() delegate or bind directly from appsettings.json.
Property
Type
Default
Description
ApiToken
string?
—
Bearer token for authentication. Required if TokenProvider is not set.
TokenProvider
Func<CancellationToken, ValueTask<string>>?
—
Dynamic token delegate. Takes precedence over ApiToken.
BaseUrl
string
https://api.samsara.com
API base URL. Use SamsaraClientOptions.EuBaseUrl for EU.
DefaultPageSize
int?
null (API default)
Override the page size for paginated requests (1–512).
Timeout
TimeSpan
00:00:30
Per-request HTTP timeout.
RetryCount
int
3
Max retry attempts for transient failures (0–10).
{
"Samsara" : {
"ApiToken" : " samsara_api_..." ,
"BaseUrl" : " https://api.samsara.com" ,
"DefaultPageSize" : 100 ,
"Timeout" : " 00:00:30" ,
"RetryCount" : 3
}
}
builder . Services . AddSamsaraClient ( options =>
builder . Configuration . GetSection ( "Samsara" ) . Bind ( options ) ) ;
builder . Services . AddSamsaraClient ( options =>
{
options . ApiToken = "samsara_api_..." ;
options . BaseUrl = SamsaraClientOptions . EuBaseUrl ;
} ) ;
Use for OAuth 2.0, Azure Managed Identity, or any rotating-token scenario:
builder . Services . AddSamsaraClient ( options =>
{
options . TokenProvider = async ct =>
{
// Fetch token from your identity provider or secrets manager
return await myAuthService . GetBearerTokenAsync ( ct ) ;
} ;
} ) ;
ISamsaraClient exposes every Samsara API domain as a typed sub-client:
Client
Property
Key Operations
IVehiclesClient
samsara.Vehicles
ListAsync, GetAsync, UpdateAsync, ListLocationsAsync, ListStatsAsync, GetLocationsFeedAsync, GetLocationsHistoryAsync, GetStatsFeedAsync, GetStatsHistoryAsync
IAssetsClient
samsara.Assets
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, GetLocationAndSpeedStreamAsync
IDriversClient
samsara.Drivers
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, RemoteSignOutAsync, CreateAuthTokenAsync, ListQrCodesAsync
ITrailersClient
samsara.Trailers
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, GetStatsFeedAsync, GetStatsHistoryAsync
IEquipmentClient
samsara.Equipment
ListAsync, GetAsync, UpdateAsync, GetLocationsFeedAsync, GetLocationsHistoryAsync, GetStatsFeedAsync, GetStatsHistoryAsync
IGatewaysClient
samsara.Gateways
ListAsync, GetAsync
IIdlingClient
samsara.Idling
GetEventsStreamAsync
Client
Property
Key Operations
IRoutesClient
samsara.Routes
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, GetAuditLogFeedAsync
ITripsClient
samsara.Trips
ListAsync, GetAsync, GetStreamAsync
IHubsClient
samsara.Hubs
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, ListLocationsAsync, ListPlansAsync
IAddressesClient
samsara.Addresses
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync
ILiveSharingLinksClient
samsara.LiveSharingLinks
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync
Client
Property
Key Operations
ISafetyClient
samsara.Safety
GetEventsAsync, GetEventsStreamAsync, ListDriverSafetyScoresAsync, ListVehicleSafetyScoresAsync
ICoachingClient
samsara.Coaching
ListDriverCoachAssignmentsAsync, GetSessionsStreamAsync
IComplianceClient
samsara.Compliance
ListHosLogsAsync, ListDvirsAsync, CreateDvirAsync
ICarbCtcClient
samsara.CarbCtc
ListVehiclesAsync, GetVehiclesHistoryAsync
ITachographClient
samsara.Tachograph
ListFilesAsync, GetFileAsync
IIftaClient
samsara.Ifta
ListSummaryAsync, CreateDetailJobAsync, GetDetailJobAsync
Client
Property
Key Operations
IMaintenanceClient
samsara.Maintenance
ListAlertsAsync, ListDvirsAsync, CreateDvirAsync, UpdateDvirAsync, GetDvirsStreamAsync, GetDefectsStreamAsync, UpdateDefectAsync
IWorkOrdersClient
samsara.WorkOrders
ListAsync, CreateAsync, UpdateAsync, GetStreamAsync, ListServiceTasksAsync, ListInvoiceScansAsync
IIssuesClient
samsara.Issues
ListAsync, GetAsync, CreateAsync, UpdateAsync, GetStreamAsync
IFuelClient
samsara.Fuel
ListPurchasesAsync, ListEnergyAsync
Client
Property
Key Operations
IOrganizationClient
samsara.Organization
GetAsync, UpdateAsync
IUsersClient
samsara.Users
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync
IUserRolesClient
samsara.UserRoles
ListAsync
IContactsClient
samsara.Contacts
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync
ISettingsClient
samsara.Settings
GetComplianceSettingsAsync, UpdateComplianceSettingsAsync, GetDriverAppSettingsAsync, UpdateDriverAppSettingsAsync, GetSafetySettingsAsync, UpdateSafetySettingsAsync
Client
Property
Key Operations
IDocumentsClient
samsara.Documents
ListAsync, GetAsync, CreateAsync, DeleteAsync, GeneratePdfAsync, GetPdfAsync
IFormsClient
samsara.Forms
ListTemplatesAsync, ListSubmissionsAsync, GetSubmissionsStreamAsync, CreatePdfExportAsync
IMediaClient
samsara.Media
ListAsync, GetAsync, GetRetrievalAsync, CreateRetrievalAsync
Client
Property
Key Operations
IAlertsClient
samsara.Alerts
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, GetIncidentsStreamAsync
IMessagesClient
samsara.Messages
ListAsync, SendAsync
IWebhooksClient
samsara.Webhooks
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync
Tags, Attributes & Assignments
Client
Property
Key Operations
ITagsClient
samsara.Tags
ListAsync, GetAsync, CreateAsync, UpdateAsync, ReplaceAsync, DeleteAsync
IAttributesClient
samsara.Attributes
ListAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync
IDriverVehicleAssignmentsClient
samsara.DriverVehicleAssignments
ListAsync, CreateAsync, DeleteAsync
IDriverTrailerAssignmentsClient
samsara.DriverTrailerAssignments
ListAsync, CreateAsync, DeleteAsync
ITrailerAssignmentsClient
samsara.TrailerAssignments
ListAsync, CreateAsync, DeleteAsync
ICarrierProposedAssignmentsClient
samsara.CarrierProposedAssignments
ListAsync, CreateAsync
Client
Property
Key Operations
IIndustrialClient
samsara.Industrial
ListAssetsAsync, GetAssetAsync, ListDataInputsAsync, GetDataInputSnapshotAsync, GetDataInputFeedAsync, GetDataInputHistoryAsync
IReadingsClient
samsara.Readings
ListDefinitionsAsync, GetHistoryAsync, GetLatestAsync
ISensorsClient
samsara.Sensors
ListAsync, GetHumidityAsync, GetTemperatureAsync, GetCargoAsync
Client
Property
Key Operations
ITrainingClient
samsara.Training
ListCoursesAsync, ListAssignmentsAsync
Pagination
All list endpoints return IAsyncEnumerable<T>. The SDK fetches subsequent pages automatically:
// Stream all vehicles — pages fetched on demand
await foreach ( var vehicle in samsara . Vehicles . ListAsync ( ct ) )
{
Console . WriteLine ( $ "{ vehicle . Id } : { vehicle . Name } ") ;
}
// Materialize to a list (System.Linq.Async)
var allDrivers = await samsara . Drivers . ListAsync ( ct ) . ToListAsync ( ct ) ;
// Take only the first page's worth
var firstHundred = await samsara . Tags . ListAsync ( ct ) . Take ( 100 ) . ToListAsync ( ct ) ;
// Create
var tag = await samsara . Tags . CreateAsync ( new CreateTagRequest ( "Night Shift" ) , ct ) ;
// Read
var vehicle = await samsara . Vehicles . GetAsync ( "vehicleId" , ct ) ;
// Update
var updated = await samsara . Tags . UpdateAsync ( tag . Id , new UpdateTagRequest ( "Night Shift Updated" ) , ct ) ;
// Delete
await samsara . Tags . DeleteAsync ( tag . Id , ct ) ;
// Stream live GPS + engine state for all vehicles
await foreach ( var stats in samsara . Vehicles . ListStatsAsync ( "engineStates,gps" , ct ) )
{
Console . WriteLine ( $ "{ stats . Name } : { stats . GpsOdometer } ") ;
}
await foreach ( var location in samsara . Vehicles . ListLocationsAsync ( ct ) )
{
Console . WriteLine ( $ "{ location . Name } : { location . Latitude } , { location . Longitude } ") ;
}
var route = await samsara . Routes . CreateAsync ( new CreateRouteRequest
{
Name = "Morning Delivery" ,
Stops =
[
new CreateRouteStopRequest { AddressId = "address-111" } ,
new CreateRouteStopRequest { AddressId = "address-222" }
] ,
DriverId = "driver-123" ,
VehicleId = "vehicle-456" ,
RecomputeScheduledTimes = true
} , ct ) ;
await samsara . Messages . SendAsync ( new SendMessageRequest (
DriverId : "driver-789" ,
Text : "Proceed to stop #3"
) , ct ) ;
await foreach ( var ev in samsara . Safety . ListEventsAsync ( ct ) )
{
Console . WriteLine ( $ "[{ ev . Type } ] Driver: { ev . DriverId } at { ev . Time } ") ;
}
await foreach ( var log in samsara . Compliance . ListHosLogsAsync ( ct ) )
{
Console . WriteLine ( $ "{ log . DriverId } : { log . Status } ({ log . StartTime } – { log . EndTime } )") ;
}
The SDK throws strongly-typed exceptions. All exceptions inherit from SamsaraApiException which exposes StatusCode and RequestId for tracing.
Exception
HTTP Status
Notes
SamsaraBadRequestException
400
Invalid request payload or parameters
SamsaraAuthenticationException
401
Invalid or expired API token
SamsaraNotFoundException
404
Resource does not exist
SamsaraRateLimitException
429
Includes RetryAfter property
SamsaraServerException
500, 502, 503, 504
Transient server errors
try
{
var vehicle = await samsara . Vehicles . GetAsync ( "bad-id" , ct ) ;
}
catch ( SamsaraNotFoundException ex )
{
Console . Error . WriteLine ( $ "Not found — request ID: { ex . RequestId } ") ;
}
catch ( SamsaraRateLimitException ex ) when ( ex . RetryAfter . HasValue )
{
await Task . Delay ( ex . RetryAfter . Value , ct ) ;
// retry...
}
catch ( SamsaraApiException ex )
{
Console . Error . WriteLine ( $ "API error { ( int ) ex . StatusCode } : { ex . Message } ") ;
}
The SDK uses Microsoft.Extensions.Http.Resilience to automatically retry transient failures (5xx errors and network timeouts) with exponential backoff and jitter. No additional configuration is required for standard use.
builder . Services . AddSamsaraClient ( options =>
{
options . ApiToken = "samsara_api_..." ;
options . RetryCount = 5 ; // Default: 3. Set 0 to disable retries entirely.
options . Timeout = TimeSpan . FromSeconds ( 60 ) ;
} ) ;
Component
Version
.NET
8.0 or later
Microsoft.Extensions.Http
8.x
Microsoft.Extensions.Http.Resilience
8.x
Microsoft.Extensions.DependencyInjection.Abstractions
8.x
Contributions are welcome! Please read CONTRIBUTING.md for build instructions, coding conventions, and the release process.
MIT