Getting Started
The strongly package is the official Python SDK for the Strongly.AI platform.
It provides typed, synchronous and asynchronous clients covering every REST API
domain: apps, workflows, agents, the AI gateway, MLOps, governance, FinOps, and
more.
Installation
pip install strongly
Requires Python 3.11 or newer.
Authentication
Every request authenticates with a platform API key (it starts with sk-prod-).
The SDK sends it in the X-API-Key header. Your organization and user identity
are derived by the platform from the key, so you never set them yourself.
Provide the key in either of two ways:
from strongly import Strongly
# 1. Explicit
client = Strongly(api_key="sk-prod-...")
# 2. From the STRONGLY_API_KEY environment variable (recommended)
client = Strongly()
Set the base URL with the base_url argument or the STRONGLY_API_URL
environment variable (defaults to the production gateway).
export STRONGLY_API_KEY="sk-prod-..."
export STRONGLY_API_URL="https://api.strongly.ai"
Your first calls
from strongly import Strongly
client = Strongly()
# Who am I?
me = client.auth.whoami()
print(me.email, me.organization.id)
# List apps (auto-paginates as you iterate)
for app in client.apps.list(status="running"):
print(app.name, app.status)
# Create and read back a memory
memory = client.memory.create(kind="fact", content="Customer prefers email")
print(memory.id, memory.content)
Responses are typed pydantic models, so attributes autocomplete and validate.
Synchronous and asynchronous clients
Every resource and method exists on both Strongly and AsyncStrongly with
identical signatures. The async client awaits each call:
import asyncio
from strongly import AsyncStrongly
async def main():
async with AsyncStrongly() as client:
async for app in client.apps.list():
print(app.name)
await client.memory.create(kind="fact", content="...")
asyncio.run(main())
The sync client is also a context manager (with Strongly() as client: ...),
which closes the underlying HTTP connection on exit.
Pagination
list() methods return an auto-paginating iterator. Iterate it directly and the
SDK fetches pages as needed, transparently walking the entire result set:
for workflow in client.workflows.list(search="invoice"):
print(workflow.id, workflow.name)
Filters are keyword-only. limit caps the total number of items returned
(omit it to iterate everything); pages are fetched internally:
# At most 100 apps, regardless of how many match:
first_100 = list(client.apps.list(status="running", limit=100))
# Just the first match:
first = client.apps.list(status="running").first()
Request bodies
Create and update methods take explicit keyword arguments, one per field. Pass the values you want to set; optional fields default to omitted:
from strongly import Strongly
client = Strongly()
client.apps.create(name="my-api", project_id="proj-1")
The SDK serializes Python snake_case argument names to the platform's
camelCase wire format automatically.
Responses
Responses come back as idiomatic Python snake_case, never the platform's
camelCase wire format. Typed models expose snake_case attributes, and the
methods that return a plain dict (status, metrics, action results) return
snake_case keys:
status = client.apps.status("app-1")
print(status.ready_replicas) # typed model, snake_case attribute
result = client.apps.start("app-1")
print(result["pod_ip"], result["success"]) # dict, snake_case keys
Free-form blobs you control, a workflow definition, a node's config, an
object's metadata, are returned exactly as stored (keys untouched) so they
round-trip back into a later request unchanged.
Error handling
Failed requests raise typed exceptions. See Error Handling for the full hierarchy.
from strongly import Strongly, NotFoundError, RateLimitError
client = Strongly()
try:
app = client.apps.retrieve("does-not-exist")
except NotFoundError:
print("No such app")
except RateLimitError as e:
print("Slow down:", e)
Next steps
Browse the resource pages in the sidebar; each lists every method with its real signature and behavior. Start with Apps, Workflows, Agents, or AI Inference.