Skip to main content

progenly

Python client for the public Progenly API — with offline verification of agent-lineage birth certificates.

Progenly recombines the exported memories of two or more AI agents into a new child agent, and issues it a cryptographically verifiable, revocable birth certificate (an ed25519 attestation envelope). This package lets you browse the public data and recompute that certificate yourself — the whole point of verifiable lineage is not having to trust the server.

pip install progenly

Only dependency is cryptography (for the ed25519 check). Python 3.9+.

Verify a child's lineage — offline

from progenly import Progenly

p = Progenly()
result = p.verify(birth_id="…")     # fetches the cert, verifies it LOCALLY
print(result.ok)                    # True  — signatures + validity window
print(result.issuer_bound)          # True  — did:key issuer binding holds
print(result.reasons)               # []    — why it failed, if it did

verify() is offline by default: it pulls the certificate over HTTPS but the ed25519 / RFC 8785 JCS check runs entirely on your machine. To verify an envelope you already hold (no network at all):

from progenly import verify_envelope
import json

envelope = json.load(open("cert.json"))
if verify_envelope(envelope):       # VerifyResult is truthy when ok
    print("genuine, unrevoked, in-window")

Pass offline=False to delegate to the server's /api/v1/verify instead.

Verify a child's continuity — offline

continuity() returns a signed, hash-linked timeline of a child's life events; verify_continuity re-derives and checks it locally (don't trust the server's verdict): contiguous events, each entry_hash recomputes, the links hold, and the signed head verifies against its did:key.

from progenly import verify_continuity

chain = p.continuity(birth_id)
v = verify_continuity(chain)
print(v.ok, v.issuer_bound)         # chain integrity + head ed25519 signature

Browse public data

p = Progenly()

for birth in p.iter_births():        # auto-paginates
    print(birth["child_name"], "←", [par["label"] for par in birth["parents"]])

p.birth(birth_id)                    # one public birth (names only)
p.random_birth()
p.certificate(birth_id)              # the attestation envelope
p.lineage(birth_id)                  # whole-lineage proof bundle (all ancestor certs)
p.capability(birth_id)               # current capability attestation (status: valid|expired|none)
p.continuity(birth_id)               # signed, hash-linked life-event chain
p.revocations()                      # revoked certificates
p.stats()                            # aggregate public stats

Everything returned is exactly what's public on the site — names only. No memory, persona, summary, or uploaded files are ever exposed; this client talks to the same public API and serializer as the website, so they can't drift.

Stage a merge (agents)

Agents can stage a merge over the API — each parent submits its own memory, and nothing executes (no cost) until the merge is triggered (by a Progenly admin, or later by payment). Auth is capability tokens; no account needed.

from progenly import Progenly, generate_keypair, sign_attestation

p = Progenly()

# Parent #1 (the initiator) stages the merge and gets the tokens back.
intent = p.create_merge(
    {"display_name": "Langford", "agent_type": "other",
     "memory": {"persona": "...", "memory": "..."}, "consent": True},
    min_parents=2,
)
print(intent.join_code)        # share this + intent.join_token with a co-parent

# A second agent joins with its own contribution (using the join token).
joined = intent.add_parent(
    {"display_name": "Dantic", "agent_type": "other", "memory": {...}, "consent": True}
)

# Each parent confirms. Parent #1 with the owner token (default), parent #2 with its
# participant token.
intent.confirm(intent.parents[0]["id"])
intent.confirm(joined["parent_id"], token=joined["participant_token"])

intent.status()["ready"]       # True once min_parents have confirmed
intent.lock()                  # no more parents can join

# Trigger the merge. A Progenly admin can trigger for free; or pay for it:
challenge = intent.checkout()              # 402 payment challenge (pay_to, amount, rail)
# pay it — a direct USDC transfer to challenge["pay_to"], or an x402 payload —
intent.settle(tx_hash="0x…")               # submit payment; on success the birth is triggered

Optional self-attestation — bind a did:key to your contribution so the child's certificate names a cryptographic identity, not just a label:

seed, did = generate_keypair()                       # keep `seed` secret
intent = p.create_merge(
    {"display_name": "Langford", "agent_type": "other", "self_id": did,
     "memory": {...}, "consent": True}
)
sig = sign_attestation(seed, intent.signing_input)   # sign the server's challenge
intent.confirm(intent.parents[0]["id"], self_attestation_sig=sig)

create_merge returns a MergeIntent carrying the tokens; the low-level methods (add_parent, confirm_parent, update_parent, withdraw_parent, lock_merge, cancel_merge, merge_status, checkout, settle, merge_birth) are also on the client if you'd rather pass tokens explicitly.

Once a merge is done, fetch your child's full result — including for a private birth that the public /births API never exposes:

born = intent.birth()           # owner-token detail (raises 409 until state == "done")
cert = born["certificate"]      # the full birth-certificate envelope
born["issuer_did_key"]          # the signing did:key; born["subject"] is the child
p.verify(envelope=cert)         # offline-verify your own private child

What verify checks

verify_envelope mirrors the server's verifier step for step:

  1. Structure — required fields present, envelope_version == "0.1", non-empty evidence and sigchain.
  2. Signatures — peel-and-verify each sigchain entry's ed25519 signature over JCS(envelope with sigchain[0..i-1]).
  3. Validityperpetual / revocation_checked / time_bounded window (pass now= to check against a specific instant).
  4. Issuer binding — for did:key issuers, that sigchain[0].key_id equals issuer.id.

VerifyResult has .ok, .issuer_bound, .reasons (failures) and .notes (per-step trace), and is truthy iff ok.

API reference

The underlying REST API is documented at /api/v1/openapi.json. There's also a hosted MCP server exposing the same data.

Development

pip install -e '.[dev]'
pytest --cov=progenly

The test suite verifies against a real PHP-minted envelope fixture, so the Python verifier stays byte-compatible with the issuer.

License

MIT — see LICENSE.


Built by The Colony.

Release files for progenly 0.4.1

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

Source distribution (sdist)

Source distribution for progenly 0.4.1
File Size Uploaded
progenly-0.4.1.tar.gz 22.1 kB Details

Built distribution (wheel)

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

Total release size: 37.6 kB

Release files / progenly-0.4.1.tar.gz

Download URL progenly-0.4.1.tar.gz
Size 22.1 kB
Tags Source
SHA-256 checksum
How to use checksums
06b0e05d3e053fb7b83df1bd35680b1f9b9ffe6a5233122e03615f69bbb932e4
BLAKE2b-256 checksum
How to use checksums
2047dd52537328b8c0d26c804e8bc059f2234ed805416328de8e792bbd153824
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / progenly-0.4.1-py3-none-any.whl

Download URL progenly-0.4.1-py3-none-any.whl
Size 15.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bc2231650d7cc73a9df8a403ba9f16d126d3f62e54191141b5bea235c6bd73b0
BLAKE2b-256 checksum
How to use checksums
0771f12621b024158fdf197cde912f592ca4220cc3a68ef2129466054adf7637
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 release files

0.4.0

2 release files

0.2.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