till
Python SDK for Till - activation-limited API key proxy.
Ship disposable API keys without handing over the real one. Give agents and contractors scoped access that auto-expires after N activations, tokens, or dollars spent.
Install
pip install till-ac
With OpenAI SDK support:
pip install till-ac[openai]
Quick start
Create and manage scoped keys
from till import TillClient
client = TillClient(admin_key="till_admin_...")
# Create a scoped key (50 activations, then dead)
key = client.create_key(
provider="openai",
upstream_key="sk-proj-...",
max_activations=50,
name="research-agent",
)
# This is shown once - save it
print(key.scoped_key) # till_sk_abc123.xyz...
# List all keys
for k in client.list_keys():
print(f"{k.metadata.get('name')}: {k.used_activations}/{k.max_activations}")
# Revoke a key
client.revoke_key(key.id)
Use scoped keys with OpenAI
The scoped key works as a drop-in replacement. Just point the base URL at Till:
import openai
client = openai.OpenAI(
api_key="till_sk_abc123.xyz...",
base_url="https://api.till.ac/v1",
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
)
Or use the helper:
from till.openai_compat import patched_openai
client = patched_openai("till_sk_abc123.xyz...")
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
)
Set token and dollar limits
# Key dies after 100K tokens OR $5, whichever comes first
key = client.create_key(
provider="openai",
upstream_key="sk-proj-...",
max_activations=1000,
max_tokens=100_000,
max_spend_cents=500, # $5.00
name="budget-agent",
)
Async support
import asyncio
from till.client import AsyncTillClient
async def main():
async with AsyncTillClient(admin_key="till_admin_...") as client:
key = await client.create_key(
provider="openai",
upstream_key="sk-...",
max_activations=50,
)
print(key.scoped_key)
asyncio.run(main())
Multi-provider
Till proxies to OpenAI, Anthropic, and Google. The scoped key holder doesn't need to know which provider they're hitting:
# OpenAI key
openai_key = client.create_key(
provider="openai",
upstream_key="sk-proj-...",
max_activations=100,
)
# Anthropic key
anthropic_key = client.create_key(
provider="anthropic",
upstream_key="sk-ant-...",
max_activations=100,
)
# Google key
google_key = client.create_key(
provider="google",
upstream_key="AIza...",
max_activations=100,
)
Account info
account = client.account()
print(f"Plan: {account.tenant.plan}")
print(f"Keys: {account.keys_used}/{account.tenant.max_keys}")
print(f"Activations this month: {account.tenant.activations_this_month}")
Error handling
from till.client import TillError
try:
key = client.create_key(...)
except TillError as e:
print(f"Error {e.status_code}: [{e.code}] {e}")
How it works
- You create a scoped key via the admin API (this SDK)
- The upstream API key is encrypted into the scoped token - Till's database stores zero upstream keys
- Hand the scoped key to an agent/contractor
- They use it exactly like a normal API key (pointed at Till's proxy URL)
- After N activations (or token/dollar limit), the key auto-expires
Links
License
MIT
Metadata
Release files for till-ac 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| till_ac-0.1.1.tar.gz | 6.3 kB | Without provenance | Details for till_ac-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| till_ac-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for till_ac-0.1.1-py3-none-any.whl |
Total release size: 14.4 kB
Release files / till_ac-0.1.1.tar.gz
| Download URL | till_ac-0.1.1.tar.gz |
|---|---|
| Size | 6.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b411c8e1c9f96205cb304ba0cd5b47346db330cd2efe3486da96d21ab0fdaf5
|
|
BLAKE2b-256 checksum How to use checksums |
c1e4ab473292cddc86eee4f74404992eece1e4f744699efbace0c6d8039142ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / till_ac-0.1.1-py3-none-any.whl
| Download URL | till_ac-0.1.1-py3-none-any.whl |
|---|---|
| Size | 8.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
835958d7d3534c91c448d8da10833d4de6d5b6159605a32c860aa8873d4720d2
|
|
BLAKE2b-256 checksum How to use checksums |
27b85e821e738ce149829cef9753c4e8914b62056d7df987dfc3e5b4a881b68c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Security for till-ac 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.