Packages & installation
| Language | Package | Requires | Runtime dependencies |
|---|---|---|---|
| Python | audacity-sdk (PyPI) | Python 3.9+ | None — stdlib only |
| TypeScript / JS | @audacity/sdk (npm) | Node ≥ 18 or Bun | None — global fetch, dual ESM/CJS, full .d.ts |
| Go | github.com/Audacity-Investments/audacity-sdk-go | Go 1.22+ | None — stdlib only |
| Java | com.audacityinvestments:audacity-sdk (Maven Central) | Java 11+ | Gson only — uses java.net.http |
| Rust | audacity-sdk (crates.io) | Rust (tokio) | reqwest, serde, tokio |
pip install audacity-sdk
npm install @audacity/sdk
# or
bun add @audacity/sdk
go get github.com/Audacity-Investments/audacity-sdk-go
<dependency>
<groupId>com.audacityinvestments</groupId>
<artifactId>audacity-sdk</artifactId>
<version>0.6.0</version>
</dependency>
[dependencies]
audacity-sdk = "0.6.0"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
The Python distribution is named
audacity-sdk, but the import stays
audacity — exactly the boto3 pattern of installing one name and importing another.Your first request
A complete request/response round trip with the official AI Reserve SDKs. SetAIRESERVE_API_KEY in your environment, pick a model, and run — the shapes below
will look familiar to anyone who has used Bedrock’s Converse. (Using the OpenAI
or Anthropic SDK instead? See connect what you already use.)
from audacity import Audacity
client = Audacity(api_key="aireserve_api_…") # or set AIRESERVE_API_KEY
response = client.converse(
modelId="gpt-5.4-mini",
messages=[{"role": "user", "content": [{"text": "What is 2+2?"}]}],
inferenceConfig={"maxTokens": 256, "temperature": 0.0},
)
print(response["output"]["message"]["content"][0]["text"])
print(response["stopReason"]) # "end_turn"
print(response["usage"]) # {"inputTokens": …, "outputTokens": …, "totalTokens": …}
print(response["metrics"]) # {"latencyMs": …}
import { AudacityRuntimeClient, ConverseCommand } from "@audacity/sdk";
const client = new AudacityRuntimeClient({ apiKey: process.env.AIRESERVE_API_KEY });
const response = await client.send(
new ConverseCommand({
modelId: "gpt-5.4-mini",
messages: [{ role: "user", content: [{ text: "Hello!" }] }],
inferenceConfig: { maxTokens: 500, temperature: 0.2 },
})
);
console.log(response.output?.message?.content?.[0]?.text);
// response.stopReason, response.usage, response.metrics.latencyMs also populated
package main
import (
"context"
"fmt"
"log"
"github.com/Audacity-Investments/audacity-sdk-go"
"github.com/Audacity-Investments/audacity-sdk-go/audacityruntime"
"github.com/Audacity-Investments/audacity-sdk-go/audacityruntime/types"
)
func main() {
// Reads AIRESERVE_API_KEY from the environment.
client := audacityruntime.New(audacityruntime.Options{})
resp, err := client.Converse(context.Background(), &audacityruntime.ConverseInput{
ModelId: audacity.String("gpt-5.4-mini"),
Messages: []types.Message{{
Role: types.ConversationRoleUser,
Content: []types.ContentBlock{
&types.ContentBlockMemberText{Value: "Hello, world!"},
},
}},
InferenceConfig: &types.InferenceConfiguration{
MaxTokens: audacity.Int32(500),
Temperature: audacity.Float32(0.2),
},
})
if err != nil {
log.Fatal(err)
}
out := resp.Output.(*types.ConverseOutputMemberMessage)
text := out.Value.Content[0].(*types.ContentBlockMemberText).Value
fmt.Println(text)
}
import com.audacity.sdk.*;
var client = AudacityRuntimeClient.builder()
.apiKey(System.getenv("AIRESERVE_API_KEY"))
.build();
ConverseResponse response = client.converse(request -> request
.modelId("gpt-5.4-mini")
.messages(Message.builder()
.role(ConversationRole.USER)
.content(ContentBlock.fromText("What is 2 + 2?"))
.build())
.inferenceConfig(cfg -> cfg.maxTokens(500).temperature(0.2f)));
System.out.println(response.output().message().content().get(0).text());
System.out.printf("Stop reason : %s%n", response.stopReason());
System.out.printf("Input tokens: %d%n", response.usage().inputTokens());
System.out.printf("Latency ms : %d%n", response.metrics().latencyMs());
use audacity_sdk::{Client, ContentBlock, ConversationRole, Message};
#[tokio::main]
async fn main() -> Result<(), audacity_sdk::Error> {
// Reads AIRESERVE_API_KEY from the environment.
let client = Client::from_env()?;
let response = client.converse()
.model_id("gpt-5.4-mini")
.messages(
Message::builder()
.role(ConversationRole::User)
.content(ContentBlock::Text("Hello!".into()))
.build()?
)
.inference_config(
audacity_sdk::InferenceConfiguration::builder()
.max_tokens(500)
.temperature(0.2)
.build()
)
.send()
.await?;
let text = response
.output().unwrap()
.as_message().unwrap()
.content().first().unwrap()
.as_text().unwrap();
println!("{text}");
Ok(())
}
If your first request fails
The fastest diagnosis: open the portal, find your key under Profile → API Keys, and click Test — it fires one real request through the gateway with that key and translates any failure into the fix. The same translations, keyed to what the error response says:| What the error says | What it means | Fix |
|---|---|---|
401/403 — invalid_api_key, AUTHENTICATION_ERROR | This key can’t sign in — it was revoked or its owner was deactivated | Create a new key in the portal and update your app to use it |
403 — MODEL_NOT_ALLOWED | The model isn’t enabled for your organization | Pick a model from your organization’s allowed list, or ask your admin to enable it |
404 — MODEL_NOT_FOUND | The model name wasn’t recognized | Check the model ID for typos against the model list |
402 — usage_cap_exceeded, BUDGET_EXCEEDED (429 ThrottlingException on the Bedrock-compatible routes) | A member, team or organization budget was reached | Requests resume once an admin raises the budget (Organization → Members); budgets do not reset on their own |
429 — rate_limit_exceeded | Too many requests right now | Wait a few seconds and retry — honors Retry-After; this passes on its own |
5xx — UPSTREAM_ERROR, TIMEOUT_ERROR | The AI provider is having trouble — not your setup | Retry in a few minutes; the SDKs retry these automatically |
| Anything else | An unexpected failure | Retry once, then contact support with the requestId |
Tip: every server-derived error carries a
requestId — quote it
to support and they can find the exact request. Full exception taxonomy in
Errors & retries.