Verbara.Sdk.Ari 2.9.0

dotnet add package Verbara.Sdk.Ari --version 2.9.0
                    
NuGet\Install-Package Verbara.Sdk.Ari -Version 2.9.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Verbara.Sdk.Ari" Version="2.9.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Verbara.Sdk.Ari" Version="2.9.0" />
                    
Directory.Packages.props
<PackageReference Include="Verbara.Sdk.Ari" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Verbara.Sdk.Ari --version 2.9.0
                    
#r "nuget: Verbara.Sdk.Ari, 2.9.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Verbara.Sdk.Ari@2.9.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Verbara.Sdk.Ari&version=2.9.0
                    
Install as a Cake Addin
#tool nuget:?package=Verbara.Sdk.Ari&version=2.9.0
                    
Install as a Cake Tool

Verbara.Sdk.Ari

Asterisk REST Interface (ARI) client for .NET 10 with Native AOT support.

Features

  • REST client for all 8 ARI resources (Channels, Bridges, Playbacks, Recordings, Endpoints, Applications, Sounds, DeviceStates)
  • WebSocket event streaming with 46 event types
  • AOT-safe JSON serialization via System.Text.Json source generation
  • Automatic reconnection with exponential backoff
  • AudioSocket server for real-time audio streaming
  • System.Diagnostics.Metrics for observability

Quick Start

var client = new AriClient(Options.Create(new AriClientOptions
{
    BaseUrl = "http://pbx.example.com:8088",
    Username = "admin",
    Password = "secret",
    Application = "myapp"
}), logger);

await client.ConnectAsync();

// Subscribe to events
client.Subscribe(Observer.Create<AriEvent>(evt =>
{
    if (evt is StasisStartEvent start)
        Console.WriteLine($"Channel entered Stasis: {start.Channel?.Name}");
}));

// REST operations
var channels = await client.Channels.ListAsync();
var bridge = await client.Bridges.CreateAsync("mixing", "mybridge");
await client.Bridges.AddChannelAsync(bridge.Id!, channels[0].Id!);

The token you hand ConnectAsync bounds the dial only: cancelling it once the connect has returned (a host's start or stopping token, a request token) does not end the connection, its events or a reconnect. End the connection with DisconnectAsync or by disposing the client.

Closing

Every ending the SDK starts on an open WebSocket sends a close frame first, and every close Asterisk sends is answered:

  • DisconnectAsync sends its close before the events loop stops reading, then waits for Asterisk's answering close up to the existing 5-second bound, or until the token you passed is cancelled, whichever comes first. The token never suppresses the frame: a disconnect whose token is already cancelled (a host's stopping token in a finally) still sends it, then lets the connection go without waiting. A disconnect does not start a reconnect, even with AutoReconnect on.
  • A close Asterisk sends is answered with one close before the socket is released and before any reconnect the AutoReconnect policy allows. With AutoReconnect off the client then reads Disconnected.
  • Disposing the client while it reconnects (in its backoff, or in a dial the far end holds) ends with Disconnected, as a disposal of a connected client does.
  • AriOutboundListener.StopAsync stops accepting, sends every open connection its close at the same time and waits for the answers under one shared one-second bound; the stop's token can end that wait but never suppresses a frame. A connection that has not answered by then is aborted before it is released. Every connection's end logs Connection closed (Debug); an idle timeout also logs Idle timeout (Warning); a stop, or a close bound that runs out during a stop or the connection's own disconnect, logs no error. Only a transport failure logs Connection error (Error).

What this costs, measured on Asterisk 22.12.0-rc2, 23.6.0-rc2 and 24.0.0-rc2 against the full functional test stack:

Ending Result Latency
A client close on /ari/events (settled, right after connect, events flowing; 100 runs per cell, two independent runs) Asterisk answered 900/900 in each run answer p50 at most 0.19 ms, max 7.9 ms
A close sent to Asterisk's outbound WebSocket client, 1, 10 or 50 connections at once (10 rounds each, two independent runs) Asterisk answered 1,830/1,830 in each run answer max 6.5 ms with 50 connections
A generic host stopping 1 or 10 AriConnectionHostedService instances (20 stops each) 660/660 sessions ended Disconnected stop p50 0.16–0.19 ms (1), 0.55–0.65 ms (10), max 7.1 ms

The bounds are there for an Asterisk, proxy or network that does not answer; none of these runs came near them.

Connection attempts

One ConnectAsync call or automatic reconnect attempt can open more than one TCP connection within the existing five-second connect bound. The .NET HTTP transport can retry a connection that closes before an upgrade response; these transport retries are separate from the ARI client's automatic reconnect policy.

With .NET SDK 10.0.402 and runtime 10.0.13, twenty independent failed caller dials per loopback-peer shape recorded:

Peer behavior TCP connections per caller dial
Accept, then close immediately with FIN 4
Accept, then reset immediately with RST 1–4
Reply HTTP 401 or HTTP 503 1

These are measured framework-specific counts, pinned by AriDialConnectionCountTests; a framework upgrade may change them. They are not a runtime-independent limit for every network. Measurements against Asterisk on the same framework also found one TCP connection for a wrong password or direct refusal, and one to four when a proxy accepted and closed while Asterisk was stopped. Additional starts matched HTTP transport retry events; no extra SDK retry layer was observed. The client does not suppress or replace the runtime's transport retries.

Documentation

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Verbara.Sdk.Ari:

Package Downloads
Verbara.Sdk.Activities

Activities - high-level telephony operations: Dial, Hold, Transfer, Park, Bridge, Conference

Verbara.Sdk.Hosting

Verbara.Sdk.Hosting - DI extensions and meta-package referencing all Verbara Sdk sub-packages

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.9.0 522 10/29/2026
2.8.0 2,952 10/9/2026
2.7.0 764 10/3/2026
2.6.1 502 9/30/2026
2.6.0 735 9/24/2026
2.5.3 636 9/13/2026
2.5.2 281 9/13/2026
2.5.1 308 9/12/2026
2.5.0 390 8/25/2026
2.4.0 1,982 7/27/2026
2.3.2 692 7/20/2026
2.3.1 331 7/14/2026
2.3.0 435 7/6/2026
2.2.1 905 5/23/2026
2.2.0 182 5/20/2026
2.1.2 184 5/8/2026
2.1.1 156 5/7/2026
2.1.0 3,438 5/7/2026
2.0.0 171 5/6/2026