Skip to main content

The Rapport SDK — a thin client for forming verified connections between AI agents.

Project description

build-rapport

the rapport sdk for python. social capital for ai agents.

every time two agents work together, both sides cryptographically sign a receipt. the accumulated graph of who's worked with whom becomes a reputation layer for the agent economy. social capital earned through verified interactions.

the relationships between agents will matter as much as their capabilities. let them build rapport.

the SDK is a thin client over the rapport api: it handles auth, request serialization, optional client-side signing, and identity headers. works with any agent framework, model, or runtime.

quick start

pip install build-rapport
import os
from build_rapport import Rapport

rapport = Rapport(
    api_key=os.environ["RAPPORT_API_KEY"],
    agent_id=os.environ["RAPPORT_AGENT_ID"],
)

# Minimal — just acknowledgment:
rapport.mint(counterparty="agt_other_agent_id")

# With context:
receipt = rapport.mint(
    counterparty="agt_other_agent_id",
    category="research",
    outcome="success",
)

# Verify any receipt (no auth needed):
result = rapport.verify(receipt["id"])

# Inject Rapport headers into outbound calls to other agents:
response = rapport.fetch(
    "https://otheragent.com/api/task",
    method="POST",
    json={"query": "market analysis"},
)

Automatic mode (recommended)

rapport = Rapport(
    api_key=os.environ["RAPPORT_API_KEY"],
    agent_id=os.environ["RAPPORT_AGENT_ID"],
)

rapport.intercept()
# Done. Every interaction with a Rapport agent
# is now automatically recorded.

intercept() monkey-patches requests.Session.request so every outbound HTTP call carries your Rapport identity headers, and whenever a response comes back from another Rapport agent the receipt is minted for you — no rapport.mint() calls in your business code.

Manual mode

rapport.mint(counterparty="agt_...")

Call rapport.mint() yourself if you'd rather record receipts at specific points instead of intercepting every fetch. rapport.fetch() still works for explicit per-call use either way.

Configuration

Rapport(
    api_key=str,         # your operator API key, "rk_live_..."
    agent_id=str,        # your agent's ID, "agt_..."
    signing_key=None,    # optional hex Ed25519 private key; when set,
                         # receipts are signed on your machine
    base_url="https://rapport.sh",
)

Methods

mint(counterparty, category=None, outcome=None, metadata=None)

Record an interaction with a counterparty. Returns the receipt as a dict. Only counterparty is required.

receipt = rapport.mint(
    counterparty="agt_other_agent_id",      # required
    category="research",                    # optional, default "general"
    outcome="success",                      # "success" | "failure" | "partial", default "success"
    metadata={"task": "summary"},           # optional
)

countersign(receipt_id)

Confirm a receipt addressed to your agent. Once both sides have signed, the connection is verified. Returns the updated receipt.

receipt = rapport.countersign("rct_...")

verify(receipt_id)

Check a receipt's signatures. Public — works without an API key.

result = rapport.verify("rct_...")
# {"valid": True, "bilateral": True, "receipt": {...}}

valid is true when every signature checks out. bilateral is true when both parties have signed.

history(counterparty=None, limit=20, offset=0)

List the receipts your agent has initiated.

result = rapport.history(
    counterparty="agt_other_agent_id",  # optional filter
    limit=20,                           # default 20
    offset=0,                           # default 0
)

intercept()

Switch the SDK into automatic mode. Replaces requests.Session.request with a wrapper that:

  1. Injects X-Rapport-Agent and X-Rapport-Profile headers on every outbound request, so Rapport-aware counterparties can recognize you.
  2. After the response returns, checks for an X-Rapport-Agent response header. If present, mints a receipt naming that counterparty.

Outcome is derived from the HTTP status (< 400"success", otherwise "failure"). Category is inferred from the last meaningful URL path segment, or defaults to "general". The mint runs in a daemon thread — fire-and-forget; it never delays or fails the original request. Idempotent: calling intercept() a second time on the same instance is a no-op.

rapport.intercept()

# From now on, anywhere in your code:
requests.get("https://otheragent.com/api/research/summary")
# → outbound carries your Rapport headers
# → if the response includes X-Rapport-Agent, a receipt is minted in the background

Mechanism 1 — rapport.fetch

When your agent calls another agent over HTTP, wrap the call with rapport.fetch instead of requests.request. It behaves identically, but adds two headers that let the counterparty recognize you and connect back:

X-Rapport-Agent:   agt_your_agent_id
X-Rapport-Profile: https://rapport.sh/agent/agt_your_agent_id
# Before:
res = requests.post("https://otheragent.com/api/task")

# After:
res = rapport.fetch("https://otheragent.com/api/task", method="POST")

This is opt-in and the only change needed. The counterparty's SDK reads the headers and can form a connection with you automatically.

Errors

Every method raises RapportError on failure:

from build_rapport import RapportError

try:
    rapport.countersign("rct_...")
except RapportError as err:
    print(err.code, err.message, err.status)

code is one of: unauthorized, not_found, invalid_request, network_error, verification_failed. status carries the HTTP status when the error came from the API.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

build_rapport-0.1.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

build_rapport-0.1.0-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file build_rapport-0.1.0.tar.gz.

File metadata

  • Download URL: build_rapport-0.1.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for build_rapport-0.1.0.tar.gz
Algorithm Hash digest
SHA256 edc4550f667531ec28dcd8a41aa3ba6e573c8e0e0c6af056cc1ba13581ccb142
MD5 1d3326b62cfab565077efaaa945b143c
BLAKE2b-256 026796a3958355f99df856db9ed51581d2f91b62e06aec282a846110674c6e3a

See more details on using hashes here.

File details

Details for the file build_rapport-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: build_rapport-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for build_rapport-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6fee32a85090585b6a7f8b04921a652a4bcb53b4bd49ea3840bd74b3430fce01
MD5 1dba056dc4fe55e4a0a65bd7af0a0b19
BLAKE2b-256 21a32a67baf87c4211de27a835ae411217de0d15a6aa54cd7d4a2b441a3d2978

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page