integrable-cloud
Official Python SDK for the Integrable Cloud API — website chat assistants, conversations, knowledge bases and analytics.
pip install integrable-cloud
Python 3.10+. Sync and async clients, one dependency (httpx).
Quick start
import os
from integrable_cloud import Integrable
client = Integrable(api_key=os.environ["INTEGRABLE_API_KEY"])
for bot in client.bots.walk():
print(bot["id"], bot["name"], bot["status"])
Create a key in the dashboard under Settings → API keys. It starts with sk_live_ and is shown once.
Async
The same surface, awaited:
from integrable_cloud import AsyncIntegrable
async with AsyncIntegrable(api_key=...) as client:
page = await client.bots.list()
async for conversation in client.conversations.walk(bot_id, days=30):
await sync_to_crm(conversation)
Both clients share one implementation of the retry policy, the idempotency rule and the error mapping — so they cannot drift apart, which is the usual failure when a library maintains two of everything.
What it does that httpx does not
Retries safely. Transient failures — 429, 5xx, connection resets — are retried with jittered exponential backoff. A Retry-After header always wins over the backoff curve, because the server knows when the window resets and the client is guessing.
Idempotency keys, automatically. Every mutating request carries one, and a retry reuses the same key — so a create that timed out and was retried produces one bot rather than three:
client.bots.create(name="Support", system_prompt="...") # key generated for you
client.post("/api/bots", json=body, idempotency_key=my_stable_id) # or supply one
A mutating request without a key is never retried: "did that land?" is exactly the question retrying cannot answer safely.
Pagination that stays fast.
for conversation in client.conversations.walk(bot_id, days=30):
process(conversation)
Follows the cursor lazily. Never increment a page number against this API — offset pagination makes the database read and discard every skipped row, so page 40 costs forty times page 1.
Errors you can branch on.
from integrable_cloud import QuotaExceededError, RateLimitError, ValidationError
try:
client.knowledge.add_text(bot_id, "Hours", "Open 9-5, Mon-Fri.")
except QuotaExceededError as e:
print("Plan limit reached:", e.details)
except ValidationError as e:
print("Bad request:", e.message, e.details)
except RateLimitError as e:
print(f"Retry in {e.retry_after}s")
Every error carries .request_id — quote it at support and the exact call can be found. Every error also has .retryable, so a caller running its own queue can ask directly instead of re-deriving it from a status code.
Rate-limit visibility.
client.bots.list()
print(client.rate_limit) # RateLimit(limit=120, remaining=118, reset=41)
Configuration
client = Integrable(
api_key=os.environ["INTEGRABLE_API_KEY"],
base_url="https://api.integrable.cloud", # override for staging
timeout=60.0, # seconds, per request
max_retries=2, # 0 disables
default_headers={"x-app": "my-service"},
http_client=my_instrumented_httpx_client, # for tests or a proxy
)
Reaching an endpoint with no wrapper
The typed resources cover the common calls. All 149 endpoints are reachable directly:
response = client.get(f"/api/bots/{bot_id}/contacts", query={"limit": 50})
print(response.data["items"])
print(response.api_version, response.request_id)
Also available over MCP
If you want to ask about your workspace rather than write code against it, the same API key connects it to Claude, ChatGPT or your editor over the Model Context Protocol — see the MCP guide.
Development
pip install -e ".[dev]"
ruff check src tests
mypy src
pytest -q
Tests are entirely offline, against a mocked transport — no credentials, no network.
Releasing
Bump version in pyproject.toml, commit, then tag:
git tag v0.2.0 && git push origin v0.2.0
The release workflow verifies the tag matches the package version, runs the full gate, and publishes.
Links
MIT © Integrable Cloud
Release files for integrable-cloud 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| integrable_cloud-0.1.0.tar.gz | 68.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| integrable_cloud-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.0 kB
Release files / integrable_cloud-0.1.0.tar.gz
| Download URL | integrable_cloud-0.1.0.tar.gz |
|---|---|
| Size | 68.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b8b6455cdb5d85c0434c1c2f3aa0e21252817d2fd44b4ce98a794eb714cefb37
|
|
BLAKE2b-256 checksum How to use checksums |
5697d859ffafe0af59e7d85396515b56192665bca15d97fb6e0f56ca67d49363
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / integrable_cloud-0.1.0-py3-none-any.whl
| Download URL | integrable_cloud-0.1.0-py3-none-any.whl |
|---|---|
| Size | 14.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
68c2940adf5639880c4974e095e0dc6a90f31d1b3bbed6baa69527763f8c6305
|
|
BLAKE2b-256 checksum How to use checksums |
f564c6dc5ddb0a0cd11f5ff6d31fd74c1ee57154b4e3b3e8afe209f71eb6a1da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|