Iteradian 1.0.1

dotnet add package Iteradian --version 1.0.1
                    
NuGet\Install-Package Iteradian -Version 1.0.1
                    
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="Iteradian" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Iteradian" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Iteradian" />
                    
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 Iteradian --version 1.0.1
                    
#r "nuget: Iteradian, 1.0.1"
                    
#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 Iteradian@1.0.1
                    
#: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=Iteradian&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Iteradian&version=1.0.1
                    
Install as a Cake Tool

<p align="center"> <h1 align="center">Iteradian .NET SDK</h1> <p align="center">Official .NET client library for the Iteradian Control Plane API</p> </p>

<p align="center"> <img src="https://img.shields.io/badge/language-C%23-239120?style=flat-square&logo=csharp" alt="C#" /> <img src="https://img.shields.io/badge/.NET-6.0%2B-512BD4?style=flat-square&logo=dotnet" alt=".NET 6+" /> <img src="https://img.shields.io/badge/version-1.0.1-green?style=flat-square" alt="Version" /> <img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License" /> <img src="https://img.shields.io/badge/NuGet-Iteradian-004880?style=flat-square&logo=nuget" alt="NuGet" /> <img src="https://img.shields.io/badge/async%2Fawait-✓-brightgreen?style=flat-square" alt="Async" /> <img src="https://img.shields.io/badge/nullable-enabled-blueviolet?style=flat-square" alt="Nullable" /> </p>


Features

  • Fully async — all methods return Task<T> for async/await usage
  • Resource-based API — clean client.Auth, client.Organizations, client.Endpoints access pattern
  • Full API coverage — Auth, Organizations, API Keys, Endpoints, Alerts, Logs, Subscriptions, Plans, Support
  • Strongly typed — all API responses deserialized into C# models with System.Text.Json
  • Automatic auth — login automatically sets the bearer token
  • Dual auth — supports both Bearer tokens and X-API-Key headers
  • Factory methods — IteradianClient.WithApiKey() for API-key-only usage
  • IDisposable — proper HttpClient lifecycle management
  • Nullable enabled — full nullable reference type support

Requirements

  • .NET 6.0 or later
  • System.Text.Json v8.0.0 (included)

Installation

NuGet

dotnet add package Iteradian

Package Reference

<PackageReference Include="Iteradian" Version="1.0.1" />

Quick Start

using Iteradian;
using Iteradian.Models;

// Create client and login
using var client = new IteradianClient("https://api.iteradian.com/api/v1");
var tokens = await client.Auth.LoginAsync("user@example.com", "password123");
Console.WriteLine($"Logged in as {tokens.User}");

// List organizations
var orgs = await client.Organizations.ListAsync();
var orgId = orgs[0]["id"]!.GetValue<string>();

// List endpoints
var endpoints = await client.Endpoints.ListAsync(orgId);
foreach (var ep in endpoints)
{
    Console.WriteLine($"{ep.Name}: {ep.Status} ({ep.Region})");
}

// Create an API key
var key = await client.ApiKeys.CreateAsync(orgId, new CreateApiKeyRequest
{
    Name = "Production Key",
    Environment = "live",
    IpAllowlist = new List<string> { "10.0.0.0/8" },
});
Console.WriteLine($"Created key: {key.Prefix}...");

// Query logs
var logs = await client.Logs.QueryAsync(orgId, "page=1&pageSize=20");
Console.WriteLine($"Total logs: {logs.Total}");

Using API Key Authentication

using var client = IteradianClient.WithApiKey(
    "https://api.iteradian.com/api/v1",
    "itrd_live_abc123..."
);

var endpoints = await client.Endpoints.ListAsync("org-id");

API Reference

Resource Accessors

Property Type Description
client.Auth AuthResource Authentication & account management
client.Organizations OrganizationsResource Organization CRUD & members
client.ApiKeys ApiKeysResource API key management
client.Endpoints EndpointsResource Endpoint & network management
client.Alerts AlertsResource Alerts, rules & notification channels
client.Logs LogsResource Request log querying
client.Subscriptions SubscriptionsResource Subscription & billing
client.Plans PlansResource Plan catalog
client.Support SupportResource Support ticket management

Authentication (client.Auth)

Method Description
LoginAsync(email, password, twoFactorCode?) Login and auto-set token
RegisterAsync(email, password, name) Register a new account
RefreshAsync(refreshToken) Refresh access token
LogoutAsync() Invalidate session
Enable2FAAsync(password) Enable 2FA → TwoFASetup
Verify2FAAsync(code) Verify 2FA code
Disable2FAAsync(password, code) Disable 2FA (code = current 6-digit TOTP)
RequestMagicLinkAsync(email) Send magic login link
ForgotPasswordAsync(email) Request password reset
ResetPasswordAsync(token, password) Reset password

Organizations (client.Organizations)

Method Description
ListAsync() List all orgs
GetAsync(orgId) Get org by ID → Organization
CreateAsync(name) Create org → Organization
UpdateAsync(orgId, name) Update org → Organization
DeleteAsync(orgId) Delete org
ListMembersAsync(orgId) List members
InviteMemberAsync(orgId, email, role) Invite member
RemoveMemberAsync(orgId, memberId) Remove member

API Keys (client.ApiKeys)

Method Description
ListAsync(orgId) List keys → List<ApiKey>
CreateAsync(orgId, req) Create key → ApiKey
RevokeAsync(orgId, keyId) Revoke key
RotateAsync(orgId, keyId) Rotate key → ApiKey
AnalyticsAsync(orgId, keyId) Key analytics

Endpoints (client.Endpoints)

Method Description
GetNetworksAsync() List networks → List<Network>
ListAsync(orgId) List endpoints → List<Endpoint>
GetAsync(orgId, endpointId) Get endpoint → Endpoint
CreateAsync(orgId, req) Create endpoint → Endpoint
DeleteAsync(orgId, endpointId) Delete endpoint
PauseAsync(orgId, endpointId) Pause endpoint
ResumeAsync(orgId, endpointId) Resume endpoint
HealthAsync(orgId, endpointId) Health check
MetricsAsync(orgId, endpointId) Performance metrics

Alerts (client.Alerts)

Method Description
ListAsync(orgId) List alerts → List<Alert>
ListRulesAsync(orgId) List rules → List<AlertRule>
CreateRuleAsync(orgId, req) Create rule → AlertRule
DeleteRuleAsync(orgId, ruleId) Delete rule
TestChannelAsync(orgId, channelId) Send a test notification through a channel
ListChannelsAsync(orgId) List notification channels

Logs (client.Logs)

Method Description
QueryAsync(orgId, queryString?) Query logs → LogsResponse
GetAsync(orgId, logId) Get single log → RequestLog
StatsAsync(orgId) Aggregated stats
FilterOptionsAsync(orgId) Available filter values

Subscriptions (client.Subscriptions)

Method Description
GetAsync(orgId) Get subscription → Subscription
ChangePlanAsync(orgId, planId, acceptedTerms) Change plan → Subscription. acceptedTerms is the caller's confirmation that the user accepted the plan-change billing terms; the server rejects the change unless it is true.
CancelAsync(orgId) Cancel subscription
ReactivateAsync(orgId) Reactivate subscription
InvoicesAsync(orgId) List invoices

Plans (client.Plans)

Method Description
ListAsync() List all plans → List<Plan>
GetAsync(planId) Get plan → Plan

Support (client.Support)

Method Description
CreateTicketAsync(orgId, req) Create ticket → SupportTicket
ListTicketsAsync(orgId) List tickets → List<SupportTicket>
GetTicketAsync(orgId, ticketId) Get ticket → SupportTicket
AddMessageAsync(orgId, ticketId, msg) Add message
UpdateStatusAsync(orgId, ticketId, status) Update status

Models

All models are defined in Models.cs with full System.Text.Json serialization attributes:

Model Key Fields
AuthTokens AccessToken, RefreshToken, User
TwoFASetup Secret, QrCode
Organization Id, Name, Slug, CreatedAt, UpdatedAt
ApiKey Id, Name, Prefix, Key?, Environment, Status, CreatedAt
Network Id, Slug, Name, ChainId, Type, Environment, IsActive
Endpoint Id, OrganizationId, NetworkId, Region, Name, Priority, Status, IsEnabled, TimeoutMs, RetryCount, metrics fields
RequestLog Id, OrganizationId, Method, Status, StatusCode?, LatencyMs?, Timestamp
LogsResponse Logs, Total, Page, PageSize, TotalPages
Alert Id, Severity, Status, Title, Message, CreatedAt
AlertRule Id, Name, Metric, Condition, Threshold, Severity, IsEnabled, CooldownMinutes
Plan Id, Name, Slug, Price, Currency, Interval, IsActive
Subscription Id, OrganizationId, PlanId, Status, CancelAtPeriodEnd
SupportTicket Id, Subject, Category, Priority, Status, CreatedAt

Request Models

LoginRequest · RegisterRequest · CreateApiKeyRequest · CreateEndpointRequest · CreateAlertRuleRequest · CreateTicketRequest

Error Handling

try
{
    var orgs = await client.Organizations.ListAsync();
}
catch (IteradianException ex)
{
    Console.WriteLine($"Status: {ex.StatusCode}");   // HTTP status code
    Console.WriteLine($"Message: {ex.Message}");     // Error message
    Console.WriteLine($"Error: {ex.Error}");         // Error type identifier
}

Project Structure

sdks/csharp/
├── Iteradian.csproj            # Project file (.NET 6.0, NuGet metadata)
├── IteradianClient.cs          # Main client class with resource accessors (384 lines)
├── IteradianException.cs       # Typed exception class
├── Models.cs                   # All request/response models (433 lines)
└── README.md                   # This file

License

MIT © Iteradian

RPC gateway, rate limits and quotas

The RPC gateway is a different host from the control-plane API:

Surface Base URL
Control plane https://api.iteradian.com/api/v1
RPC gateway https://rpc.iteradian.com

This SDK takes both, and defaults the gateway to https://rpc.iteradian.com.

  • A batch of N calls costs N against your per-second rate limit and your monthly quota. Batching saves round trips, not allowance.
  • Limits are per subscription, aggregated over every API key your organization holds. Creating more keys does not raise them.
  • The gateway returns HTTP 429 with a JSON-RPC error body: -32005 rate limited (retry after error.data.retryAfter), -32006 monthly quota exhausted, -32007 overage spend cap reached, -32008 the API key's own daily limit reached (error.data = { dailyLimit, used, cost, resetsAt }). None of the last three recover before resetsAt (the billing period roll-over, or the next 00:00 UTC for -32008), so retrying them is wasted work.

Plans (defaults; an admin can change them): Free 25 rps / 3M per month with no overage (requests stop at the quota, no card needed), Developer 100 rps / 5M with overage at $6 per million, Professional 500 rps / 30M at $4.50 per million, Dedicated per contract from $4 per million. Trials are offered on Developer only; a trial that ends unpaid falls back to Free. See sdks/SDK_CONTRACT.md for the full table.

WebSocket

The gateway also serves JSON-RPC over WebSocket at wss://rpc.iteradian.com/ws/v1/{network}. This SDK does not wrap it on purpose: connect with any WebSocket client, such as the built-in System.Net.WebSockets.ClientWebSocket. Authenticate with the X-Api-Key header, Authorization: Bearer <key>, or ?apiKey=<key> on the URL (browsers cannot set headers on a WebSocket).

using System.Net.WebSockets;
using System.Text;

using var ws = new ClientWebSocket();
ws.Options.SetRequestHeader("X-Api-Key", "itrd_live_...");
await ws.ConnectAsync(
    new Uri("wss://rpc.iteradian.com/ws/v1/eth-mainnet"), CancellationToken.None);

var subscribe = Encoding.UTF8.GetBytes(
    "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_subscribe\",\"params\":[\"newHeads\"]}");
await ws.SendAsync(subscribe, WebSocketMessageType.Text, true, CancellationToken.None);

var buffer = new byte[1024 * 1024];
while (ws.State == WebSocketState.Open)
{
    var result = await ws.ReceiveAsync(buffer, CancellationToken.None);
    if (result.MessageType == WebSocketMessageType.Close)
    {
        // 1012: reconnect and re-subscribe. 4003: key revoked; do not reconnect.
        Console.WriteLine($"Closed: {(int?)ws.CloseStatus}");
        break;
    }
    Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, result.Count));
}
  • Each message you send is charged like an HTTP request (a batch of N costs N). Subscription notifications pushed to you are not charged.
  • A message refused by a limit gets an ordinary JSON-RPC error under that call's id, with the same codes as above (-32005 to -32008). The socket stays open.
  • An organization can hold max(5, floor(concurrency / 4)) streams at once; past that the upgrade is refused with HTTP 429. Other upgrade failures: 400 bad path, 401/403 bad key, 404 unknown network, 503 no WebSocket-capable node.
  • Close code 1012 means the upstream node restarted: reconnect and re-subscribe. 4003 means the key was revoked or the organization suspended (keys are re-checked every 60 s): do not reconnect.
  • The server pings every 30 s. Messages are limited to 1 MB.

Changelog

1.0.1

  • Subscriptions.ChangePlanAsync takes a required bool acceptedTerms and sends it as acceptedTerms; the server rejects plan changes without it.
  • Auth.Disable2FAAsync takes the 6-digit TOTP code alongside the password, as the server requires.
  • Support.UpdateStatusAsync now calls PUT /orgs/{orgId}/support/tickets/{ticketId}/status (it sent PATCH /support/tickets/{id}, which does not exist).
  • Removed Alerts.TestRuleAsync: it posted a rule ID to the channel-test route. Use Alerts.TestChannelAsync(orgId, channelId).
  • Gateway error -32008 (per-API-key daily limit) is never retried; IteradianException.IsQuotaExhausted covers it and IsDailyLimitReached identifies it.
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 68 9/29/2026
1.0.0 123 4/23/2026