Python SDK for calling APIs on the Orthogonal platform.
Call any API on the Orthogonal platform through one client and one credit balance — authentication, routing, and billing are handled for you.
- Why Orthogonal
- Installation
- Quick Start
- Authentication
- Usage
- Async Usage
- Error Handling
- API Reference
- Related
- License
Orthogonal puts a catalog of APIs behind one account and one balance:
- One integration — call any API on the platform through a single
run()method. - Pay per use — a single credit balance instead of juggling dozens of provider subscriptions.
- Sync and async — a blocking
Orthogonalclient and anawait-ableAsyncOrthogonal, both usable as context managers. - Typed —
RunOptions/RunResponsetyped dicts and full type hints.
Requires Python 3.9+.
pip install orthimport os
from orthogonal import Orthogonal
with Orthogonal(api_key=os.environ["ORTHOGONAL_API_KEY"]) as orthogonal:
res = orthogonal.run(
api="tavily",
path="/search",
query={"query": "latest AI news"},
)
print(res["data"]) # the upstream API's response
print(res["price"]) # amount charged, e.g. "0.01"Get an API key from your Orthogonal dashboard.
Pass your key to the constructor (reading it from the environment keeps keys out of source):
orthogonal = Orthogonal(api_key=os.environ["ORTHOGONAL_API_KEY"])res = orthogonal.run(
api="fantastic-jobs",
path="/v1/active-ats",
query={"time_frame": "1h", "limit": 10},
)res = orthogonal.run(
api="some-api",
path="/v1/generate",
body={"prompt": "a red bicycle"},
)res = orthogonal.run({
"api": "tavily",
"path": "/search",
"query": {"query": "hello world"},
})Headers passed to the constructor are sent on every request:
orthogonal = Orthogonal(
api_key=os.environ["ORTHOGONAL_API_KEY"],
headers={"x-my-trace-id": "abc123"},
)AsyncOrthogonal mirrors the sync client with await and async with:
import asyncio
from orthogonal import AsyncOrthogonal
async def main():
async with AsyncOrthogonal(api_key=os.environ["ORTHOGONAL_API_KEY"]) as orthogonal:
res = await orthogonal.run(
api="tavily",
path="/search",
query={"query": "orthogonal"},
)
print(res["data"])
asyncio.run(main())run() returns the response on success and raises OrthogonalError on any non-2xx response (invalid key, insufficient credits, or an upstream/validation error). The message describes what went wrong.
from orthogonal import Orthogonal, OrthogonalError
try:
res = orthogonal.run(api="tavily", path="/search", query={"query": "x"})
except OrthogonalError as err:
print(f"request failed: {err}")| Argument | Type | Description |
|---|---|---|
api_key |
str |
Required. Your Orthogonal API key (orth_live_… / orth_test_…). |
headers |
Mapping[str, str] | None |
Optional headers sent on every request. |
base_url |
str |
Override the API base URL (advanced). |
Call an endpoint. Pass either an options dict or keyword arguments (not both).
| Argument | Type | Description |
|---|---|---|
api |
str |
Required. The API slug (e.g. "tavily"). |
path |
str |
Required. The endpoint path (e.g. "/search"). |
query |
Mapping[str, JSONValue] |
Query parameters. |
body |
Mapping[str, JSONValue] |
Request body for POST/PUT/PATCH. |
RunResponse (a TypedDict)
| Key | Type | Description |
|---|---|---|
success |
bool |
Whether the call succeeded. |
price |
str |
Amount charged in USD (e.g. "0.01"). |
data |
JSONValue |
The upstream API's response. |
Same constructor and run(...) signature as Orthogonal, but run() is a coroutine (await) and the client supports async with / await client.close().
Raised by run() on a non-2xx response. Subclass of Exception; str(err) is a human-readable message.
Both clients are context managers — use with / async with (or call close()) so the underlying HTTP connection is released.
MIT © Orthogonal