Conventions
The shared rules every module follows: imports, result metadata, the wire contract, idempotency and BYOK.
Import patterns
Python exposes three namespaces — ai, infra and account:
from infrai import infra, ai, account
infra.activate() # one-time onboarding (Python only)
ai.chat("hello") # ai.* namespace
infra.email.send(to="x@y.com", subject="Hi", body="...") # infra.* namespace
account.balance() # account.* namespaceTypeScript uses one client whose namespaces mirror the modules:
import { InfraiClient } from "@infrai/sdk";
const client = new InfraiClient({ apiKey: process.env.INFRAI_API_KEY! });
await client.ai.chat({ messages: "hello" });
await client.email.send({ to: "x@y.com", subject: "Hi", text: "..." });
await client.account.balance();Result metadata
Every call returns its data plus a metadata block, so an agent can read cost and latency without a vendor round-trip.
result = ai.chat("Hello")
if result["_metadata"]:
print(result["_metadata"]["cost_usd"], result["_metadata"]["request_id"])cost_usd· USD cost of this call, reconcilable with your bill.latency_ms· End-to-end latency in milliseconds.vendor· The upstream vendor that served the call.cache_hit· Whether the response was served from cache.request_id· Globally unique id (UUID v7) for support and reconciliation.
Wire contract
Every SDK speaks the same wire contract. If you call the HTTP API directly, follow these:
| Authentication | Authorization: Bearer <infrai_project_key> |
| Request body | Canonical JSON: sorted keys, no spaces, trailing newline, UTF-8. |
| Idempotency header | Idempotency-Key |
| Request id | metadata.request_id (UUID v7) |
Idempotency
Idempotency keeps retries safe — the same key never double-charges or duplicates a resource within the dedup window.
- Read (GET) calls are idempotent by default — no key needed.
- Cost-incurring calls derive a key server-side; passing your own is recommended.
- Resource-creation calls require an explicit idempotency_key.
# Cost-incurring calls: pass a key so retries never double-charge
infra.email.send(
to="customer@x.com",
subject="Order #123 confirmed",
body="...",
idempotency_key=f"order-confirmed-{order_id}",
)
# Resource creation requires a key
account.keys.create(label="prod", idempotency_key="bootstrap-prod-key-v1")When you omit a key on a cost-incurring call, the server derives one deterministically:
idempotency_key = sha256(account_id + request_id + capability + content_hash)The default dedup window is 24 hours (minimum 1 hour, maximum 7 days). A repeat within the window returns the original result without re-charging.
BYOK (Bring Your Own Key)
Register your own vendor credentials so calls dispatch through your key instead of the shared pool.
# Register your own vendor key; calls dispatch through it
account.byok.register(
provider="openai",
alias="prod-gpt4o",
credentials={"api_key": "sk-..."},
idempotency_key="byok-openai-prod-v1",
)
account.byok.list()
account.byok.test(id="byok_01HX...")
account.byok.revoke(id="byok_01HX...")Credentials are write-only: the API never returns the plaintext key, only a short fingerprint you can recognize.