Namespace: TeleQuick.SDK. Type: TeleQuickClient.

Constructor

public TeleQuickClient(string endpoint, string credentialsPath);
ArgumentNotes
endpointquic://host:port
credentialsPathPath to your service-account JSON.
The constructor reads and parses the JSON, generates a per-instance Guid-based client id, and stores the QUIC endpoint. It does not connect — that happens on first RPC.

Public delegates

public Action<byte[]>? OnAudioFrame;
public Action<byte[]>? OnCallEvent;
Both receive the raw serde envelope.

RPC methods (all async)

public Task DialAsync(
    string to, string trunkId,
    string callFrom = "",
    int maxDurationMs = 0,
    int defaultApp = 1,                 // PARK
    string defaultAppArgs = "",
    string aiWs = "",
    string aiQuic = "",
    bool autoBargeIn = false,
    int bargeInPatienceMs = 250
);

public Task OriginateBulkAsync(
    string csvUrl, string trunkId,
    int callsPerSecond, string campaignId,
    int defaultApp = 1, string defaultAppArgs = "",
    string aiWs = "", string aiQuic = "",
    bool autoBargeIn = false, int bargeInPatienceMs = 250
);

public Task TerminateAsync(string callSid);
public Task BargeAsync(string callSid);
public Task AbortBulkAsync(string campaignId);
public Task StreamEventsAsync(string clientId);

public Task SetInboundRoutingAsync(
    string trunkId, int rule,
    string audioUrl, string webhookUrl,
    string aiWs, string aiQuic
);

public Task GetIncomingCallsAsync(string trunkId);
public Task AnswerIncomingCallAsync(string callSid, string aiWs, string aiQuic);

public Task GetActiveBucketsAsync();
public Task GetBucketCallsAsync(string bucketId);
public Task ExecuteBucketActionAsync(string bucketId, int action);

public Task PushAudioAsync(
    string callSid, byte[] payload, string codec,
    ulong sequenceNumber, bool endOfStream
);

Decoding helpers

public AudioFrame DeserializeAudioFrame(IntPtr payloadBuffer, UIntPtr length);
public CallEvent  DeserializeCallEvent(IntPtr payloadBuffer, UIntPtr length);
AudioFrame and CallEvent are P/Invoke [StructLayout] structs declared in NativeMethods.cs. Their fields mirror Types. For typical use, marshal your callback’s byte[] into unmanaged memory:
client.OnCallEvent = raw =>
{{
    var unmanaged = Marshal.AllocHGlobal(raw.Length);
    Marshal.Copy(raw, 0, unmanaged, raw.Length);
    var ev = client.DeserializeCallEvent(unmanaged, (UIntPtr)raw.Length);
    Marshal.FreeHGlobal(unmanaged);

    Console.WriteLine($"{{ev.call_sid}} → {{Marshal.PtrToStringAnsi(ev.status)}}");
}};

Method ID constants

using TeleQuick.SDK;

MethodID.ORIGINATE
MethodID.AUDIO_FRAME
MethodID.STREAM_EVENTS
// …

Threading model

The internal ReceiveLoop runs on a Task.Run worker. Callbacks invoke on that task’s thread — keep them quick or marshal to your own SynchronizationContext (e.g. UI thread for WPF/WinForms).
var ctx = SynchronizationContext.Current;
client.OnCallEvent = raw =>
{{
    ctx?.Post(_ => UpdateUi(raw), null);
}};

Errors

ErrorCause
DllNotFoundExceptiontelequick_core_ffi not on DllImport search path.
QuicException from ConnectAsyncGateway unreachable or TLS handshake failed.
EndOfStreamException in ReadExactAsyncServer-pushed stream closed; safe to ignore — the loop accepts the next stream.