Developer tools
SDKs
The client libraries for Rust, TypeScript, Python, Go, C# and Java, how to add each, and what they do the same in every language.
Six libraries, at 0.2.2 (Go at 0.2.3, which changed only its README), all open source in inorbithr/sdk. Each is a hand-written runtime (the client, credentials, retries, errors, streams) plus the API's operations as typed calls. Four are on their language's registry; C# and Java are built and tested at 0.2.2 but not published yet.
| Language | Package | Needs | Where |
|---|---|---|---|
| Rust | inorbithr | Rust 1.94 | crates.io |
| TypeScript | @inorbithr/sdk | Node 22.12, Bun, Deno, browsers | npm, JSR |
| Python | inorbithr | Python 3.11 | PyPI |
| Go | github.com/inorbithr/sdk/go | Go 1.26 | pkg.go.dev |
| C# | InOrbit.Sdk | .NET 8 | build from source; not on NuGet yet |
| Java | hr.inorbit:inorbit-sdk | Java 17 | build from source; not on Maven Central yet |
Every library reads its credential from the environment: an API token in INORBIT_TOKEN
(made in the console or with iohr token create), or an API key in INORBIT_KEY_ID and
INORBIT_KEY_SECRET with the scopes to ask for in INORBIT_SCOPES, which it exchanges for
15-minute tokens and refreshes itself.
iohr sdk add (command line 0.1.0-alpha.10 and later) adds the library to the project in the current
directory with the package manager the project already uses, so each section below shows it
first and the package manager's own command beside it. Without a language it finds the
project from the current directory up to the repository root (Cargo.toml, package.json
or deno.json, pyproject.toml, requirements.txt or a Python lock file, go.mod); when it
finds several or none it exits 2 and names the commands. It picks the manager from the
project's files: pnpm, yarn, bun or npm by lock file or packageManager, deno add jsr: for
deno.json without package.json; uv, poetry or pdm by lock file, otherwise pip only inside
an active virtualenv, and it refuses (exit 2) to install into a system Python. cargo add
needs a Cargo.toml and go get a go.mod.
iohr sdk add # the language and the package manager from the project's files
iohr sdk add go --version 0.2.2 # that release
iohr sdk add --dry-run # print the command, run nothing
iohr sdk add ts --json # {"lang", "manager", "dir", "command", "dry_run"}It always prints the command first, then runs that one program directly in the project
directory: no shell, never sudo, the program found only in absolute PATH entries. The
exit code is the package manager's. iohr contacts no host for it; the package manager
reaches its own registry. C# and Java are refused (exit 1): they are not on NuGet or Maven
Central yet.
Rust
iohr sdk add rust # or: cargo add inorbithruse inorbithr::{Client, Error, Method, Operation, Response};
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Error> {
let client: Client = Client::from_env()?;
let me: Response<serde_json::Value> = client
.request(Operation::new(Method::Get, "/v1/me"))
.await?;
println!("{} ({})", me.value["subject"], me.value["kind"]);
Ok(())
}TypeScript
iohr sdk add typescript # or: npm install @inorbithr/sdk, pnpm add @inorbithr/sdk, deno add jsr:@inorbithr/sdkimport { Public } from "@inorbithr/sdk";
const api = Public.fromEnv();
const { value: me } = await api.me();
const { value: page } = await api.radar.listDigests({ limit: 3 });ESM only, no dependencies; runs on Node, Bun, Deno, browsers and Workers. 64-bit integers are
bigint.
Python
iohr sdk add python # or: uv add inorbithr, pip install inorbithr in a virtualenvfrom inorbithr import Public
api = Public.from_env()
me = api.me().value
digests = api.radar.list_digests(limit=3).valueAsyncPublic is the same on asyncio.
Go
iohr sdk add go # or: go get github.com/inorbithr/sdk/go@latestimport (
inorbit "github.com/inorbithr/sdk/go"
"github.com/inorbithr/sdk/go/public"
)
api, err := public.FromEnv()
if err != nil {
return err
}
me, err := api.Me(ctx)
var apiErr *inorbit.APIError
if errors.As(err, &apiErr) && apiErr.Code == inorbit.CodeForbidden {
// the token lacks identity:read
}inorbit is the runtime; public is the surface an API token or key may call.
OpenTelemetry is a separate module, github.com/inorbithr/sdk/go/otel, so the runtime does not
depend on it.
C#
InOrbit.Sdk 0.2.2 (net8.0) is built and tested in the open, and its NuGet release has not
happened yet. Build from source until then, and reference the project:
git clone https://github.com/inorbithr/sdk
dotnet add reference path/to/sdk/csharp/src/InOrbit.Sdkusing InOrbit.Sdk;
using InOrbit.Sdk.Api;
using var client = Client.FromEnv();
var me = (await client.MeAsync()).Value;Java
hr.inorbit:inorbit-sdk 0.2.2 is built and tested in the open, and its Maven Central release
has not happened yet. Build from source until then: put it in your local Maven repository and
depend on it by the coordinates it will be published under.
git clone https://github.com/inorbithr/sdk && cd sdk
mvn -f java install<dependency>
<groupId>hr.inorbit</groupId>
<artifactId>inorbit-sdk</artifactId>
<version>0.2.2</version>
</dependency>Public api = Public.fromEnv();
Me me = api.me().value();Configuration and middleware
From 0.2.2 every library has the same configuration and middleware:
load(Client::load,Client.load,inorbit.Load,Client.Load) reads settings in one order: code, thenINORBIT_*environment variables, then theiohrconfig file, then defaults.describe()shows each value and where it came from, with secrets redacted;iohr sdk configprints the same for a program on your machine.- The credential chain: environment, token and key secret files, then your
iohrlogin (iohr auth token). - Proxy, CA bundle, mTLS, key pinning and connect timeout, or your own HTTP client.
- A named middleware pipeline with built-ins for logging, OpenTelemetry, rate limits and a retry budget.
Two changes a running program can notice: writes whose operation takes an Idempotency-Key
are now retried, with one key per call sent on every attempt, and calls have a 120 s total
deadline by default, every attempt and wait included. The settings are in
docs/config.md, worked examples
in docs/recipes.md.
A client cut to your credentials
Public (and its counterpart in each language) holds every operation an API credential may
call. iohr sdk generate writes a surface into your repository with only the operations your
profiles' credentials may call, so a call a profile may not make does not compile (in Python,
pyright and mypy refuse it), and iohr sdk check fails in CI when that set moves:
iohr sdk generate --lang rust --for default --out src/iohr # or typescript, python, go, csharp, java
iohr sdk checkThe full guide is public: Generate an SDK for your account.
What every library does
- Authenticates with an API token, or exchanges an API key for a short-lived token, caches it and refreshes it.
- Returns typed results and one error type per language, carrying the API's error
codeanddetails; a code the library does not know yet is kept, not dropped. - Retries what is safe to retry (
429,503,504, connection failures), honouringRetry-After; a write is retried only when the operation is marked safe to repeat. - Reads streams over server-sent events or one
/v1/wssocket. - Behaves the same in every language: one set of conformance cases runs against all six.
Checking a package
| Registry | How |
|---|---|
| npm | npm audit signatures checks registry signatures and provenance |
| PyPI | each file carries a PEP 740 attestation; pypi-attestations verify pypi --repository https://github.com/inorbithr/sdk <file> |
| Go | the toolchain checks every module against sum.golang.org |
| JSR | provenance on the package page, linked to the transparency log |
| crates.io | Cargo checks every download against the index's checksum |
The details are in the SDK repository's verifying releases.