tautulli
A Dart client for the Tautulli API.
Installation
dart pub add tautulli
Or add manually to pubspec.yaml:
dependencies:
tautulli: ^3.2.0
Quick Start
import 'package:tautulli/tautulli.dart';
void main() async {
final client = TautulliClient(
connection: const TautulliConnection(
protocol: 'http',
domain: '192.168.0.2:8181',
apiKey: 'your_api_key',
),
);
try {
final activity = await client.activity.getActivity();
print('Streaming: ${activity.streamCount} sessions');
final history = await client.history.getHistory(length: 10);
for (final entry in history.data) {
print('${entry.title} watched by ${entry.friendlyName}');
}
} on TautulliAuthException {
print('Invalid API key or authorization required');
} on TautulliConnectionException {
print('Could not reach Tautulli server');
} finally {
client.close();
}
}
Services
All API commands are accessible through namespaced service properties on TautulliClient:
| Property | Description |
|---|---|
client.activity |
Current playback sessions |
client.devices |
Mobile device registration |
client.exports |
Export metadata and download exports |
client.graphs |
Time-series chart data |
client.history |
Watch history and home statistics |
client.images |
Image proxy URL construction |
client.libraries |
Library/section management and media info |
client.logs |
Tautulli and Plex log retrieval |
client.media |
Metadata, search, rating keys |
client.network |
GeoIP and WHOIS lookups |
client.newsletters |
Newsletter configuration and delivery |
client.notifications |
Notifier configuration and notification log |
client.users |
User management and statistics |
client.api |
API documentation endpoints |
client.plex |
Plex Media Server identity and status |
client.tautulli |
Tautulli settings, info, backups, and restart |
Custom HTTP Client
Pass a custom http.Client for SSL certificate handling or testing:
import 'dart:io';
import 'package:http/io_client.dart';
// Self-signed certificate support (native platforms only)
final httpClient = HttpClient()
..badCertificateCallback = (cert, host, port) => allowedHosts.contains(host);
final client = TautulliClient(
connection: const TautulliConnection(
protocol: 'http',
domain: '192.168.0.2:8181',
apiKey: 'your_api_key',
),
httpClient: IOClient(httpClient),
);
Native only. This example uses
dart:ioandIOClient, which don't exist on the web — see Platform Support below.
Client ownership. An
httpClientyou inject is yours to manage:client.close()will not close it. Close it yourself when you're done. When you don't pass one, the client creates its own andclose()disposes it.
Platform Support
Runs on the Dart VM, Flutter (Android/iOS/desktop), server, and Flutter web / WASM. Two things differ on the web:
- Custom HTTP clients and self-signed certificates are native-only.
dart:io,IOClient, andbadCertificateCallbackare unavailable on the web (the browser controls TLS), so self-signed certificates cannot be accepted and the defaultBrowserClientis used. Connection failures surface asTautulliConnectionException— the finerTautulliCertVerificationExceptionmapping is native-only. - CORS. With the default query-parameter auth the client sends simple GET
requests. Request headers (opt-in
ApiKeyLocation.header, or customheadersonTautulliConnection) make requests non-simple and trigger a CORS preflight, which Tautulli answers from v2.18.0 onward — so both work from the browser on every supported server.
Security
By default the API key is sent as the apikey query parameter. Setting
apiKeyLocation: ApiKeyLocation.header on the connection sends it as an
X-Api-Key header instead, keeping the key out of URLs and therefore out of
server access logs, proxy logs, and browser tooling. Header auth is supported
by every server version this package targets, so it is worth enabling.
Two caveats regardless of mode: image URLs from buildImageUrl() always embed
the key as a query parameter (an <img> tag cannot send headers), and you
should use protocol: 'https' in production so the key and every response are
encrypted in transit.
Dates
All model DateTime values are in UTC (they come from Unix epoch
timestamps). Call .toLocal() before displaying them:
final entry = history.data.first;
print(entry.date?.toLocal());
Exception Handling
All exceptions extend the sealed TautulliException class:
| Exception | Thrown when |
|---|---|
TautulliConnectionException |
Network unreachable or socket error |
TautulliAuthException |
HTTP 401 or "Authorization Required" response |
TautulliInvalidApiKeyException |
Tautulli returns "Invalid apikey" |
TautulliServerException |
Non-200, non-401 HTTP status |
TautulliBadResponseException |
Malformed JSON or unexpected response structure |
TautulliTimeoutException |
Request exceeds configured timeout |
TautulliVersionException |
Server rejects register_device for being below the requested min_version |
TautulliCertExpiredException |
TLS certificate has expired |
TautulliCertVerificationException |
TLS certificate verification failed |
TautulliProtocolException |
Protocol is not http or https |
TautulliTerminateStreamException |
Stream termination command failed |
Testing
Inject a MockClient from package:http/testing.dart to unit-test code that calls
Tautulli without making real network requests:
import 'package:http/testing.dart';
import 'package:http/http.dart' as http;
import 'package:tautulli/tautulli.dart';
final mockClient = MockClient((request) async {
return http.Response(
'{"response":{"result":"success","data":{"stream_count":2,"sessions":[]}}}',
200,
);
});
final client = TautulliClient(
connection: const TautulliConnection(
protocol: 'http',
domain: '192.168.0.2:8181',
apiKey: 'your_api_key',
),
httpClient: mockClient,
);
API Reference
All commands are documented in the Tautulli API Reference.
- Requires Tautulli v2.18.0 or newer
- Last audited against: v2.18.1
Older servers are not supported: v2.18.0 removed several parameters this client sends.
importConfig() and importDatabase() are not implemented and throw
UnimplementedError.
License
GPL-3.0-or-later
Libraries
- tautulli
- Dart client for the Tautulli API.