SkyBellSharp 0.1.2
dotnet add package SkyBellSharp --version 0.1.2
NuGet\Install-Package SkyBellSharp -Version 0.1.2
<PackageReference Include="SkyBellSharp" Version="0.1.2" />
<PackageVersion Include="SkyBellSharp" Version="0.1.2" />
<PackageReference Include="SkyBellSharp" />
paket add SkyBellSharp --version 0.1.2
#r "nuget: SkyBellSharp, 0.1.2"
#:package SkyBellSharp@0.1.2
#addin nuget:?package=SkyBellSharp&version=0.1.2
#tool nuget:?package=SkyBellSharp&version=0.1.2
<img src="assets/icon-512.png" alt="SkyBellSharp" width="96" align="right" />
SkyBellSharp
Unofficial .NET client for the SkyBell Gen5 cloud API (https://api.skybell.network).
- Authentication: personal API key, email/password (SkyBell login endpoint or Amazon Cognito), automatic token refresh
- Devices: list, details (settings, hardware, telemetry), settings update, reboot, removal
- Live view: starts WebRTC sessions (Amazon Kinesis Video Streams signaling data, ICE servers, temporary credentials)
- Snapshots, activity history (paging, per-day previews, video download, deletion)
- Sharing, webhooks (triggers), tones (catalog, custom upload, test), locations, on-device rules, health
- Real-time events:
SkyBellEventMonitorcombines local UDP broadcasts with API confirmation and polling - Local network: UDP button/motion broadcasts and Wi-Fi provisioning of devices in AP mode
- Raw access (
GetRawAsync/SendRawAsync) for anything not modelled yet
Unofficial project. Not affiliated with, endorsed by, or supported by SkyBell Technologies, Inc. "SkyBell" is a trademark of its owner. Use it with your own account and respect SkyBell's terms of service. SkyBell asks API consumers not to poll more often than once every 60 seconds.
Install
dotnet add package SkyBellSharp
Targets .NET 10.
Quick start
using SkyBellSharp;
using SkyBellSharp.Models;
// Personal API key: https://api.skybell.network/developers
using var client = SkyBellClient.WithApiKey("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
var user = await client.GetUserAsync();
var devices = await client.GetDevicesAsync();
var door = devices[0];
// Fresh picture (the device answers within ~30 s, otherwise SkyBellApiException.IsDeviceTimeout)
var snapshot = await client.GetSnapshotAsync(door.Id);
await File.WriteAllBytesAsync("door.jpg", snapshot.Jpeg);
// Last doorbell presses (last 7 days unless Start is set)
var page = await client.GetActivitiesAsync(new ActivityQuery
{
DeviceId = door.Id,
EventType = SkyBellEventTypes.Doorbell,
Limit = 20
});
// Download the latest clip
await using var mp4 = File.Create("last.mp4");
await client.DownloadActivityVideoAsync(page.Rows[0].ActivityId, mp4);
// Change settings (only non-null values are sent)
await client.UpdateSettingsAsync(door.Id, new DeviceSettingsUpdate { LedColor = "#0055CC", MotionSensitivity = 2 });
Email / password
using var client = await SkyBellClient.LoginAsync("me@example.com", "password");
// Get (or create) a personal API key to avoid storing the password
var apiKey = await client.GetOrCreateApiKeyAsync();
To reuse a session, persist SkyBellLoginAuthenticator.Tokens (raised by TokensRefreshed) and
recreate the authenticator with new SkyBellLoginAuthenticator(http, tokens).
CognitoAuthenticator logs in directly against the SkyBell Cognito user pool like the mobile app
(requires the user-pool app client id).
With IHttpClientFactory / DI
services.AddHttpClient("skybell");
services.AddSingleton(sp => new SkyBellClient(
sp.GetRequiredService<IHttpClientFactory>().CreateClient("skybell"),
new ApiKeyAuthenticator(configuration["SkyBell:ApiKey"]!)));
Live view (WebRTC)
StartLiveStreamAsync returns everything a KVS WebRTC viewer needs: channel ARN, signaling
endpoints (WssEndpoint), ICE servers and temporary AWS credentials. Feed them to the
Kinesis Video Streams WebRTC SDK
(e.g. in a WebView2) as a VIEWER. Call StopLiveStreamAsync when done: it also finalizes the
recording.
var session = await client.StartLiveStreamAsync(door.Id);
// session.ChannelArn, session.WssEndpoint, session.IceServers, session.Credentials, session.Region
Real-time events
SkyBellEventMonitor raises doorbell presses and motion as they happen:
- UDP (same LAN): a broadcast triggers immediate API lookups (2, 4, 6, 8 s) to get the
confirmed activity, its type and preview; if the cloud does not confirm it, an
UdpOnlyevent is still raised; - polling every 60 s (the minimum allowed by SkyBell) as a fallback when away from home.
Each activity is raised once; events older than Start() are ignored; live views are skipped.
using var monitor = new SkyBellEventMonitor(client, new SkyBellEventMonitorOptions { DeviceId = door.Id });
monitor.EventDetected += (_, e) =>
Console.WriteLine($"{e.EventType} at {e.Time:T} via {e.Source}"); // e.Activity has the id, preview…
monitor.CheckFailed += (_, ex) => Console.WriteLine(ex.Message);
monitor.Start();
Local events (UDP)
Devices broadcast a fixed packet on UDP port 5000 when the button is pressed or motion is detected.
using SkyBellSharp.Local;
using var udp = new SkyBellUdpListener();
udp.EventReceived += (_, e) => Console.WriteLine($"{e.Kind} from {e.Source.Address}");
udp.Start(); // allow inbound UDP in the firewall
Packets matching the two samples of the SkyBell docs are reported as ButtonPressed /
MotionDetected; other SkyBell-formatted packets (encrypted payloads can differ) as Unidentified.
Raw access
JsonNode? shares = await client.GetRawAsync("/api/v5/shares");
Returns the whole JSON response (envelope included) for endpoints or fields the models do not cover.
Production API notes
Observed on the live API (v1.52), which differs from the published docs (v1.39):
GET /api/v5/activityreturns the last 7 days when nostartis given, and ignoreslimit/offset(limit: 100000):GetActivitiesAsyncapplies them client-side. Previews (image) are only returned for ranges within one day (ImagesIncluded).video_urlis now an API path (/activity/{id}/video); useGetActivityVideoUrlAsync.GET /api/v5/activity/dayreturns[{ activity_day, event_count }]→GetActivityDaysAsync.GET /api/v5/rulesreturnsname -> [rules]; device rules are underdata.rules.- Device
lat/lonare strings; settings includebasic_motion,pir_sensitivity, motion chime options; telemetry includes LAN/public IP, battery voltage and memory. /api/v5/user/api_accessrequires a JWT session (401 "Please login first." with an API key).
Error handling
Every API failure throws SkyBellApiException with StatusCode, ApiMessage, and helpers
IsDeviceTimeout (HTTP 599: the device did not answer within 30 s), IsAuthenticationError,
IsNotFound. JWT authenticators refresh the token before expiry and retry once after a 401.
API coverage
| Area | Endpoints |
|---|---|
| Auth | POST /api/v5/login, PUT /api/v5/token, GET /api/v5/logout, Cognito InitiateAuth, API key header |
| User | GET/POST/DELETE /api/v5/user, GET/POST/DELETE /api/v5/user/api_access |
| Devices | GET /api/v5/devices, GET/DELETE /api/v5/devices/{id}, POST …/settings, POST …/reboot, GET …/snapshot |
| Live | POST/DELETE /api/v5/devices/{id}/videostream |
| Activity | GET /api/v5/activity, GET/DELETE /api/v5/activity/day, GET /api/v5/activity/{id}/video, DELETE /api/v5/activity/{id} |
| Sharing | POST /api/v5/devices/{id}/share, GET /api/v5/shares, GET …/{id}/redeem, PUT/POST/DELETE /api/v5/shares/{id} |
| Triggers | GET/POST /api/v5/devices/{id}/triggers, DELETE …/triggers/{triggerId} |
| Tones | GET /api/v5/tones, GET /api/v5/tones/chime, POST/PUT /api/v5/devices/{id}/tone, POST …/testtone |
| Locations | GET/POST /api/v5/locations, POST/DELETE /api/v5/locations/{id} |
| Rules | GET /api/v5/rules, GET /api/v5/devices/{id}/rules |
| Misc | GET /health, POST/DELETE /api/v5/notification_token, GET /api/v5/devices/provision |
| Local | UDP broadcasts (port 5000), GET /ap/scan, POST /ap/provision |
Not covered: legacy SkyBell HD CoAP provisioning, OAuth 2.0 partner flow.
Sample app
dotnet run --project samples/SkyBellSharp.Sample -- <api-key> # account, devices, last events
dotnet run --project samples/SkyBellSharp.Sample -- <api-key> watch # real-time events
dotnet run --project samples/SkyBellSharp.Sample -- <api-key> dump # raw responses -> ./skybell-dump
dotnet run --project samples/SkyBellSharp.Sample -- <api-key> selftest # reversible write tests -> ./skybell-selftest
dotnet run --project samples/SkyBellSharp.Sample -- udp # raw UDP broadcasts
dump only calls read-only endpoints and redacts secrets and personal data (tokens, keys,
emails, serials, MAC addresses, coordinates, ids, signed URLs). Attaching those files to an issue
helps fix models for undocumented responses — review them before sharing.
selftest only performs reversible writes: it writes back the current speaker volume, takes a
snapshot, creates then deletes a webhook and a location, and plays the button tone only after
confirmation.
Build & pack
dotnet build
dotnet test
dotnet pack src/SkyBellSharp -c Release -o artifacts
Releasing
Pushing a vX.Y.Z tag runs .github/workflows/release.yml: build, tests, pack with that
version, push to nuget.org through Trusted Publishing (short-lived key obtained with GitHub
OIDC; secret NUGET_USER = nuget.org profile name) and GitHub release with the packages.
License
MIT
| 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
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.