Skip to content

Client SDKs

Official thin clients for the Planisphere compliant-AI API. Both wrap the same HTTP surface — gate an action, get a signed offline-verifiable receipt, route what needs a human — with typed errors and the decision signals. No runtime dependencies (Python: standard library; Node: built-in fetch, Node 18+).

The SDK sources and full READMEs live in sdk/python and sdk/typescript.

Python

pip install planisphere
from planisphere_sdk import Planisphere, PlanisphereNeedsReview, PlanisphereBlocked

ps = Planisphere(api_key="ps_live_...")   # or ps_test_ for a free sandbox key

decision = ps.gate(
    pack="law",
    proposed_action="File this motion with the court.",
    surface="agent",
    source_key="agent:run:42",
    law_context={"matter_band": "litigation", "tool_id": "harvey"},
    idempotency_key="run-42",   # safe to retry — returns the original result, meters once
)

if decision["decision"] == "allow":
    ...  # proceed, and keep decision["evidence_packet"] as your receipt

Prefer exceptions? require_allow raises PlanisphereNeedsReview / PlanisphereBlocked unless the action is allowed.

Node / TypeScript

npm install planisphere-sdk
import { Planisphere, PlanisphereNeedsReview, PlanisphereBlocked } from "planisphere-sdk";

const ps = new Planisphere("ps_live_...");   // or a free ps_test_ sandbox key

const decision = await ps.gate({
  pack: "law",
  proposed_action: "File this motion with the court.",
  surface: "agent",
  source_key: "agent:run:42",
  law_context: { matter_band: "litigation", tool_id: "harvey" },
  idempotencyKey: "run-42",   // safe to retry — returns the original result, meters once
});

if (decision.decision === "allow") {
  // proceed, and keep decision.evidence_packet as your receipt
}

requireAllow throws the decision signals instead of returning them.

What both clients cover

  • gate / require_allow (requireAllow) — gate an action, with an optional idempotency key so retries return the original result and meter once.
  • verify and verify_kit (verifyKit) — check a receipt, or fetch the offline verification recipe.
  • get_record (getRecord) — fetch a stored evidence packet.
  • record_review / review_queue (recordReview / reviewQueue) — the human review loop.
  • Typed errors: PlanisphereErrorPlanisphereAuthError (401/403), PlanisphereRateLimited (429, with retry-after), and the decision signals PlanisphereBlocked / PlanisphereNeedsReview (both carry .decision).

Sandbox

Get a free ps_test_ key with no card via POST /signup/test-key. Sandbox receipts are signed with a non-production key (dev_key: true) so they can never be mistaken for production evidence. Upgrade in place by completing checkout with the same email.

Webhooks

To receive events (record.sealed, receipt.anchored, verify.failed, meter.threshold) rather than poll, register an event webhook — see webhooks.md.

Payload Retention: Recording Completed Acts

The record verb (POST /v1/record, POST /v1/record/batch) attests completed acts with hash commitments. Planisphere stores hash commitments only — retain your payload to re-prove WHAT was recorded. Archive the payload bytes (or a durable pointer) alongside the returned action_key; every record response repeats this warning in its payload_retention field. For period evidence: GET /tenant/exports/records?from=&to=&cursor=POST /evidence-packets/seal-bundle/batch (body is {"action_keys": [...]}; POST /v1/record/batch by contrast takes a bare JSON array of record bodies) → GET /v1/records/{action_key}/inclusion-proof (records anchor on the hourly roll-up epoch; a just-sealed record returns 409 with an estimated_next_epoch_at hint until the next epoch).