Authentication
OpenApp SDKs authenticate with API keys in the encoded form described in
API keys. The token embeds the deployment origin;
each SDK derives the API root {origin}/api/v1 from it and sends the token in
the X-API-Key header, unless you override the base URL.
For Python-only topics (rotation snippets, repr privacy), see
Python — Authentication.
Obtain a key
Section titled “Obtain a key”- Sign in to the OpenApp dashboard.
- Open Settings → API keys.
- Click Add, pick Organization for new keys, set expiry, and copy the token once.
Creating keys requires the api_keys:create role in the target organization.
Construct the client
Section titled “Construct the client”Pass the full token string (including the https://…_openapp_ origin prefix).
from openapp_sdk import Client
client = Client.connect( api_key="https://openapp.house_openapp_YOUR_SECRET",)import { AsyncClient } from "@tomers/openapp-sdk";
const client = new AsyncClient( "https://openapp.house_openapp_YOUR_SECRET",);use openapp_sdk::Client;
let client = Client::builder() .api_key("https://openapp.house_openapp_YOUR_SECRET") .build()?;import openapiclient "github.com/tomers/openapp-sdk/go"
client, err := openapiclient.NewAPIClient( "https://openapp.house_openapp_YOUR_SECRET",)if err != nil { return err}defer func() { _ = client.Close() }()Go: NewAPIClient uses CGO and the core C bridge; call Close when finished so native runtime handles are released.
Rust / TypeScript: Prefer one long-lived client per process and reuse it (clone in Rust; keep a single AsyncClient in Node).
Override the base URL
Section titled “Override the base URL”Use this when the token’s embedded origin does not match the server you need (staging, proxy, or on‑prem). The override is the full API root, including /api/v1.
client = Client.connect( api_key="https://openapp.house_openapp_YOUR_SECRET", base_url="https://staging.openapp.house/api/v1",)import { AsyncClient } from "@tomers/openapp-sdk";
const client = new AsyncClient("https://openapp.house_openapp_YOUR_SECRET", { baseUrl: "https://staging.openapp.house/api/v1",});use openapp_sdk::Client;
let client = Client::builder() .api_key("https://openapp.house_openapp_YOUR_SECRET") .base_url("https://staging.openapp.house/api/v1")? .build()?;client, err := openapiclient.NewAPIClientWithBaseURL( "https://openapp.house_openapp_YOUR_SECRET", "https://staging.openapp.house/api/v1",)if err != nil { return err}defer client.Close()Environment variables
Section titled “Environment variables”None of the SDKs read OPENAPP_API_KEY (or similar) by default — configure explicitly or wrap yourself:
import osfrom openapp_sdk import Client
def client_from_env() -> Client: return Client.connect(api_key=os.environ["OPENAPP_API_KEY"])import { AsyncClient } from "@tomers/openapp-sdk";
function clientFromEnv(): AsyncClient { const apiKey = process.env.OPENAPP_API_KEY; if (!apiKey) throw new Error("OPENAPP_API_KEY is not set"); return new AsyncClient(apiKey);}use openapp_sdk::Client;
fn client_from_env() -> Result<Client, openapp_sdk::SdkError> { let key = std::env::var("OPENAPP_API_KEY") .map_err(|e| openapp_sdk::SdkError::Config(format!("OPENAPP_API_KEY: {e}")))?; Client::builder().api_key(key).build()}import ( "fmt" "os"
openapiclient "github.com/tomers/openapp-sdk/go")
func ClientFromEnv() (*openapiclient.APIClient, error) { key := os.Getenv("OPENAPP_API_KEY") if key == "" { return nil, fmt.Errorf("OPENAPP_API_KEY is not set") } return openapiclient.NewAPIClient(key)}Related HTTP operations
Section titled “Related HTTP operations”Key lifecycle over the wire is documented in the API reference
under the OpenAPI API Keys tag — for example POST /api-keys, revoke, restore, and purge.
Language surfaces differ (client.api_keys in Python, APIKeysAPI in Go, etc.);
map tags from the OpenAPI document to your SDK.
Browser sessions (Kratos) — introspection (GET /auth/whoami, GET /auth/session, …)
and cookie logout are under the Auth tag; see Auth (browser session).
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause |
|---|---|
| Invalid token format | Missing _openapp_ separator — copy the full dashboard token. |
| Cannot derive base URL | Origin prefix is malformed or contains a path (for example https://host/api/v1_openapp_…); copy a freshly issued dashboard token, or set the base URL explicitly (Python / TypeScript / Rust). |
401 with Authorization: Bearer | API keys are accepted only in X-API-Key; the SDKs do this for you. |
| 401 Unauthorized | Revoked or expired key, wrong org, or wrong backend. |