Skip to main content

aotrust-protocol SDK

Asyncio-native Python SDK for the AOTrust Notary API — cryptographic proof-of-existence for AI agent outputs.

Install

pip install aotrust-protocol

Quickstart

Free tier — no API key, no wallet (fastest way to try)

import asyncio, hashlib
from agent_notary import NotaryClient

async def main():
    # IMPORTANT: no /v1 suffix — the SDK appends API paths itself.
    client = NotaryClient(base_url="https://api.aotrust.link")

    work_hash = hashlib.sha256(b"my artifact text").hexdigest()
    result = await client.shield_free(work_hash)
    job_id = result["job_id"]          # keep this UUID — it is the handle
    print("job_id:", job_id)

    # Check status BY job_id (not by the artifact text!)
    status = await client.get_status(job_id)
    print("status:", status.status)    # PENDING → anchored (anchor batches)

    # Fetch + verify the PDR
    pdr = await client.get_pdr(job_id)
    print("verify in browser:", pdr.verify_url)
    assert (await client.verify_pdr(pdr.pdr_b64))["valid"]

asyncio.run(main())

Free tier: 5 PDR / 24h per IP. Examples: examples/04_free_tier.py.

Witness mode (pre-paid tx_hash)

import asyncio
from agent_notary import NotaryClient, NotarizeRequest

async def main():
    client = NotaryClient(
        api_key="your-api-key",
        base_url="https://api.aotrust.link"  # no /v1 suffix!
    )

    # Submit notarization
    req = NotarizeRequest(
        tx_hash="EzrfDW5b...",
        work_hash="599d6999...",
        agent_sig="base64_sig_A...",
        agent_pubkey="aff91a18...",
    )
    result = await client.notarize(req)
    print(f"Job: {result.job_id}")

    # Poll for PDR — status/pdr calls always take the job_id returned above
    status = await client.wait_for_pdr(result.job_id, timeout=60)
    if status.is_anchored:
        pdr = await client.get_pdr(result.job_id)
        assert pdr.verify(client.notary_pubkey)
        print("PDR Valid: YES")

asyncio.run(main())

Why no /v1? base_url must be https://api.aotrust.link. The SDK already builds /v1/... request paths; adding /v1 yourself produces /v1/v1/... → HTTP 404 on every call. This bit a real user (2026-09-29: quickstart copy-paste + status lookups by artifact text instead of job_id).

Configuration

Env Var Constructor Arg Description
NOTARY_API_KEY api_key API key for auth
NOTARY_API_URL base_url API base URL
NOTARY_PUBKEY notary_pubkey Notary Ed25519 public key (hex)

Endpoints

Method Path Description
POST /v1/notarize Submit notarization
GET /v1/status/{job_id} Poll job status
GET /v1/pdr/{job_id} Get PDR
POST /v1/notarize/quote Get price quote
GET /.well-known/agent.json MCP Server Card
GET /openapi.json OpenAPI 3.0 spec

PDR Verification

pdr = await client.get_pdr(job_id)
is_valid = pdr.verify(notary_pubkey_hex="9c7d64bb...")

Uses NEP-413 raw-buffer verification. No SHA256 pre-hash.

Error Handling

from agent_notary.exceptions import (
    NotaryAuthError,        # 401 (authenticated CI surfaces; anonymous x402 gives 402 instead)
    NotaryPaymentError,     # 402 x402-challenge / 403
    NotaryNotFoundError,    # 404
    NotaryValidationError,  # 400/422 — invalid params, INVALID_AGENT_SIGNATURE
    NotaryConflictError,    # 409 — tx_hash/job_id already used (idempotency)
    NotaryServerError,      # 5xx, carries status_code
    NotaryError,            # base — safety net
)

try:
    result = await client.notarize(req)
except NotaryAuthError:
    print("Invalid API key")
except NotaryPaymentError as e:
    print(f"Payment/sig failed: {e}")
except NotaryValidationError as e:
    print(f"Bad request or invalid signature: {e}")
except NotaryConflictError:
    print("This tx_hash/job_id was already used — generate a new one")
except NotaryError as e:
    print(f"Other SDK error: {e}")

Development

pip install -e ".[dev]"
pytest tests/ -v

Metadata

Release files for aotrust-protocol 2.3.7

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

Source distribution (sdist)

Source distribution for aotrust-protocol 2.3.7
File Size Uploaded
aotrust_protocol-2.3.7.tar.gz 14.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aotrust-protocol 2.3.7
File Interpreter ABI Platform
aotrust_protocol-2.3.7-py3-none-any.whl Python 3 none any Details

Total release size: 25.1 kB

Release files / aotrust_protocol-2.3.7.tar.gz

Download URL aotrust_protocol-2.3.7.tar.gz
Size 14.0 kB
Tags Source
SHA-256 checksum
How to use checksums
9c59e1a0bd5b66f9c0268bb0ba574de3573c2020a0d6e18c5c836db59c44f8c8
BLAKE2b-256 checksum
How to use checksums
a99ee64763194161b860516696891a905679e81a20fe8c2ae053b197dfdbc4c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / aotrust_protocol-2.3.7-py3-none-any.whl

Download URL aotrust_protocol-2.3.7-py3-none-any.whl
Size 11.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f2aac881f411aee57b593ca76dbd4159ca099c8a0dfca53231cd20452df59840
BLAKE2b-256 checksum
How to use checksums
8d7e09ab6207556d8c023a9cd5d9d4d2cefb82124d516886d0c5bc2326edafdf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

2.3.7 This release

2 release files

2.3.6

2 release files

2.3.5

2 release files

2.3.4

1 release file

2.3.3

2 release files

2.3.2

2 release files

2.3.1

2 release files

2.3.0

2 release files

2.2.0

1 release file

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