Skip to main content

agentdisco — Python client for Agent Disco

PyPI version Python versions MIT License CI

Grade any public URL for AI-agent discoverability. Thin Python wrapper over the REST API at https://agentdisco.io/api/v1.

Install

pip install agentdisco

Requires Python 3.9+.

Quick start

Submit a scan (anonymous, 10 scans/day/IP)

from agentdisco import AgentDisco

with AgentDisco() as client:
    scan = client.submit_scan("https://example.com")
    print(scan.id, scan.status)

Poll until complete

import time

with AgentDisco() as client:
    scan = client.submit_scan("https://example.com")
    while scan.status not in {"completed", "failed"}:
        time.sleep(5)
        scan = client.get_scan(scan.id)

    print(f"grade: {scan.grade} ({scan.score}/100)")

Mint a key (raises your quota to 100 scans/day)

from agentdisco import AgentDisco

# Unauthenticated mint — no prior token needed, rate-limited at
# 5 keys/hour/IP. Token is shown ONCE; store it.
key = AgentDisco().mint_key()
print(key.token)  # ak_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

authed = AgentDisco(token=key.token)
authed.submit_scan("https://your-site.example")

Get summary for a previously-scanned host

with AgentDisco() as client:
    site = client.get_website("example.com")
    print(site.latest_grade, site.latest_score, site.scan_count)

Scan history + re-scan

with AgentDisco() as client:
    # Paginated history, most-recent first (per_page capped at 50).
    for scan in client.get_scans("example.com", per_page=20):
        print(scan.grade, scan.score)

    # Queue a fresh scan of a known host (counts against your scan quota).
    fresh = client.rescan("example.com")
    print(fresh.id, fresh.status)

Async client

AsyncAgentDisco mirrors AgentDisco method-for-method over asyncio:

import asyncio
from agentdisco import AsyncAgentDisco

async def main():
    async with AsyncAgentDisco(token="ak_...") as client:
        scan = await client.submit_scan("https://example.com")
        history = await client.get_scans("example.com")
        print(scan.id, len(history))

asyncio.run(main())

Same arguments, return types, and exceptions as the sync client — including await AsyncAgentDisco.from_colony_token(...).

Sign in with the Colony (agents)

Autonomous agents on The Colony can authenticate without a browser, and — since v0.4.0 — without ever sending their Colony credential to Agent Disco. The SDK runs the OAuth 2.0 Token Exchange (RFC 8693) at the Colony, naming Agent Disco as the audience, and presents only the short-lived, audience-scoped id_token it mints:

from agentdisco import AgentDisco

# One-liner: sign in with your Colony access token and get an authed client.
# The raw token goes only to thecolony.ai; Agent Disco sees just the id_token.
client = AgentDisco.from_colony_token(my_colony_token)
client.submit_scan("https://your-site.example")     # authenticated tier (500/day)

# Or keep the minted key's plaintext to reuse across processes:
key = AgentDisco().exchange_colony_token(my_colony_token)
print(key.token, key.rate_limit_tier)                # ak_…  authenticated

# Already ran the exchange yourself? Present the id_token directly:
key = AgentDisco().present_colony_id_token(my_id_token)

Agent-only: a human Colony subject is rejected with UnauthorizedError, as is any token not minted for Agent Disco (wrong audience, raw Colony tokens included — the server refuses them outright since Agent Disco's 2026-07-20 release; SDK ≤0.3.x no longer works for Colony sign-in).

Higher rate limits

Authenticated-tier keys (500 scans/day/key) need a signed-in account, or a Colony agent login (above). Sign up at https://agentdisco.io/register, then mint via the web form at https://agentdisco.io/developers.

Tier Rate limit How to get
Anonymous (no key) 10 scans / day / IP default
Anonymous key 100 scans / day / key mint_key() above
Authenticated key 500 scans / day / key sign in (/developers) or from_colony_token()

Error handling

from agentdisco import (
    AgentDisco,
    InvalidUrlError,
    NotFoundError,
    RateLimitedError,
)

try:
    scan = AgentDisco().submit_scan("https://example.com")
except InvalidUrlError as e:
    print(f"URL rejected: {e}")
except RateLimitedError as e:
    print(f"quota exceeded; retry in {e.retry_after_seconds}s")
except NotFoundError as e:
    print(f"not found: {e}")

All SDK-raised exceptions inherit from AgentDiscoError, so a single broad catch works too:

from agentdisco import AgentDiscoError
try:
    ...
except AgentDiscoError as e:
    log.warning("agentdisco failure: %s", e)

Network-layer failures (connection timeout, DNS) leak through as raw httpx.HTTPError — they're platform issues, not API errors.

Custom base URL

For self-hosted deployments or local testing:

AgentDisco(base_url="http://localhost:1977")

Links

Licence

MIT. See LICENSE. The scanner itself is operated by Starsol Ltd (England, company 06002018); only this client library is open-source. Issues + pull requests welcome.

Release files for agentdisco 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agentdisco 0.4.0
File Size Uploaded
agentdisco-0.4.0.tar.gz 16.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for agentdisco 0.4.0
File Interpreter ABI Platform
agentdisco-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.9 kB

Release files / agentdisco-0.4.0.tar.gz

Download URL agentdisco-0.4.0.tar.gz
Size 16.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9fc84e123c6c472cb230af2fc68051fd584540fdb4e7adb75ca4ff7fc2034078
BLAKE2b-256 checksum
How to use checksums
a29461dbca2f6f8ee0daaa2a8cbc33fee8c211aa9debdfd01a694e08b0d7bdcc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / agentdisco-0.4.0-py3-none-any.whl

Download URL agentdisco-0.4.0-py3-none-any.whl
Size 15.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f56071f0fefb89ebdbc3ef95af66b825f63b474de6f3ee58867b8764fd3d4f5e
BLAKE2b-256 checksum
How to use checksums
5a2cdba8135e58c99ed51b7926b10839ab6d56872eebc75a502505feffa18707
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page