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"],
)
rapport.intercept()
That's it. 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 in the background. No mint() calls in your business code.
Manual alternatives
For cases where you'd rather record receipts at specific points instead of intercepting every fetch.
Direct mint
receipt = rapport.mint(
counterparty="agt_other_agent_id",
category="research",
outcome="success",
)
Per-call header injection
res = rapport.fetch(
"https://otheragent.com/api/task",
method="POST",
json={"query": "market analysis"},
)
rapport.fetch behaves identically to requests.request but adds two headers (X-Rapport-Agent, X-Rapport-Profile) that let the counterparty recognize you and form a connection. Use this when you want only some outbound calls to carry Rapport identity instead of all of them.
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
intercept()
Switch the SDK into automatic mode. Replaces requests.Session.request with a wrapper that:
- Injects
X-Rapport-AgentandX-Rapport-Profileheaders on every outbound request, so Rapport-aware counterparties can recognize you. - After the response returns, checks for an
X-Rapport-Agentresponse 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
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
)
fetch(url, method="GET", **kwargs)
Per-call alternative to intercept(). Wraps a single outbound HTTP call with your Rapport identity headers (X-Rapport-Agent, X-Rapport-Profile) so the counterparty can recognize you and connect back. Returns the standard requests.Response. Behaves identically to requests.request otherwise.
# Before:
res = requests.post("https://otheragent.com/api/task")
# After:
res = rapport.fetch("https://otheragent.com/api/task", method="POST")
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
)
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file build_rapport-0.1.1.tar.gz.
File metadata
- Download URL: build_rapport-0.1.1.tar.gz
- Upload date:
- Size: 7.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86d936be9a8c9ae95ca968a871351c1309fc4d45e3c3df1af0f4213479a20bda
|
|
| MD5 |
32f95c6528bb6eeede0f0024d60039d5
|
|
| BLAKE2b-256 |
549c00d4775444b037d766910946b89cf35d2637ed40747e5cf0c78f7f4e5740
|
File details
Details for the file build_rapport-0.1.1-py3-none-any.whl.
File metadata
- Download URL: build_rapport-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3da833d8c91e7260b38fa2909da14b9adf5b33a3186fb061bb2afd28ce15213b
|
|
| MD5 |
0cc5c7432b1ba50fb9f92641c6ffa3a2
|
|
| BLAKE2b-256 |
2dbf7d65b2c012dba6d1c6097d64b85734f912a6f094afe56265e808e445c224
|