Getting started with SCPN Studio
Five steps from reading the platform to verifying your first sealed evidence bundle. Each step expands to show the goal, the links you need, and the next action.
1 What is SCPN Studio?
SCPN Studio is a federation of standalone scientific studios. Each studio owns its domain, its verbs, and its evidence, while the Hub federates their interfaces and audits every claim against the shared studio.*.v1 contract.
Read the platform overview →2 Explore a project
Browse the live federation to see how a studio advertises its capabilities, its evidence types, and its latest sealed results. Every project page is reflected from its source repository.
Browse projects →3 Run a demo studio
Open the hosted demo studio to see a federated UI load inside the Hub shell, emit a studio.demo.v1 evidence bundle, and verify it in the browser without installing anything.
Launch demo studio →4 Verify your first evidence bundle
Download a sealed artifact, inspect its studio.publication-seal.v1 envelope, and check the content digest and signature against the pinned root key and well-known keyring.
Open the trust guide →5 Create an account / subscribe
Create a free account to run jobs in your own tenant, or subscribe to the research newsletter to receive releases, preprints, and transparency-log checkpoints.
Create account →SCPN Studio quickstart notebook
This notebook demonstrates the end-to-end SCPN Studio flow:
1. Create an account through the commerce API.
2. Run a deterministic hosted-studio demo.
3. Download and verify a sample evidence bundle with the platform SDK.
**Prerequisites**
- Python 3.12+
- `httpx` installed (`pip install httpx`)
- `scpn-studio-platform` installed (`pip install -e /path/to/SCPN-STUDIO-PLATFORM`)
- A running commerce backend (or use `https://www.anulum.org` for the public API).
Download the notebook → Interactive API docs
-
1. Create an account
Registration is asynchronous: the endpoint queues a verification email and returns `202 Accepted`. Duplicate emails are accepted silently so the endpoint does not leak account existence.
import uuid email = f"user-{uuid.uuid4().hex[:8]}@example.org" password = "correct-horse-battery-staple!42" display_name = "Notebook User" resp = client.post('/api/v1/auth/register', json={ 'email': email, 'display_name': display_name, 'password': password, }) print(resp.status_code, resp.text) -
2. Verify email and log in (local development)
In production the verification link is sent by email. For a local backend running the recording mail transport, inspect the mail outbox or call the verification endpoint directly if you have the token. Once verified, log in to obtain the session cookies.
Skip this cell when running against the public site unless you own the mailbox.
# This cell is a placeholder for local verification. # In a real local run you would read the verification token from the mail drain # or backend logs and POST it to /api/v1/auth/verify-email. login = client.post('/api/v1/auth/login', json={ 'email': email, 'password': password, }) print(login.status_code, login.text) -
3. Read the current account
The `/api/v1/auth/me` endpoint returns the authenticated account, including its federation-wide tier.
me = client.get('/api/v1/auth/me') print(me.status_code, json.dumps(me.json(), indent=2)) -
4. Probe API health
The public status and health endpoints need no authentication.
for path in ['/healthz', '/health/ready']: r = client.get(path) print(path, r.status_code, r.json()) -
5. Download and inspect the OpenAPI spec
The commerce API publishes its OpenAPI schema at `/api/v1/openapi.json`. This is the same schema rendered by Scalar at `/docs/api/`.
spec = client.get('/api/v1/openapi.json') print(spec.status_code, spec.headers.get('content-type')) openapi = spec.json() print('title:', openapi['info']['title']) print('version:', openapi['info']['version']) print('paths:', list(openapi['paths'])[:10]) -
6. Verify a sample evidence bundle
The portal hosts sample RO-Crate evidence bundles. We download one and use the platform SDK to validate its claim boundary and digest.
import zipfile import tempfile from pathlib import Path bundle_url = 'https://www.anulum.org/evidence/scpn-control.rocrate.zip' bundle_bytes = httpx.get(bundle_url, follow_redirects=True, timeout=30).content print('Downloaded', len(bundle_bytes), 'bytes') with tempfile.TemporaryDirectory() as tmp: archive = Path(tmp) / 'bundle.zip' archive.write_bytes(bundle_bytes) with zipfile.ZipFile(archive) as zf: zf.extractall(tmp) print('Entries:', zf.namelist()[:20]) metadata_path = Path(tmp) / 'ro-crate-metadata.json' if metadata_path.exists(): metadata = json.loads(metadata_path.read_text()) print('RO-Crate @id:', metadata.get('@id')) print('Entities:', len(metadata.get('@graph', [])))# If scpn-studio-platform is installed, verify the bundle digest. try: from scpn_studio_platform.digest import file_digest digest = file_digest(archive) print('Bundle SHA-256 digest:', digest) except ImportError as exc: print('scpn-studio-platform not installed:', exc) -
Next steps
- Read the interactive API docs at `https://www.anulum.org/docs/api/`.
- Explore the platform SDK source in `SCPN-STUDIO-PLATFORM/src/scpn_studio_platform/`.
- Run the local smoke test: `pnpm --filter scpn-studio-portal run smoke:local`.