Python API
Authenticate once and use the same product operations as the browser.
Account authentication
import os
from scratchpad.api import ScratchpadClient
account = ScratchpadClient(os.environ["RELIFOLD_API_KEY"])
Select a workspace from the account page, then open API keys in workspace administration. The secret is shown once, inherits the account's current permissions, and can be revoked without modifying pipelines. The key remains user-owned rather than workspace-owned: it can reach only the organizations and workspaces the user can currently access. It is a Relifold credential, not a model-provider credential.
Workspace scope
workspace = account.select_workspace(
organization="your-organization",
workspace="main",
)
print([
(pipeline["pipeline_id"], pipeline["version_count"], pipeline["session_statuses"])
for pipeline in workspace.pipelines()
])
print([
(
version["version"],
version["state"],
version["node_count"],
version["review_count"],
version["stage_count"],
version["max_parallel_width"],
)
for version in workspace.versions("news-events")
])
definition = workspace.version("news-events", "v2")
print(definition["nodes"])
print(workspace.sessions(pipeline_id="news-events", version_id="v2"))
print(workspace.metrics(pipeline_id="news-events", version_id="v2"))
Either selector accepts an ID, slug, or display name. Omit a selector only when that level has exactly one result.
Ambiguous accounts fail closed rather than choosing an arbitrary workspace. Unattended scripts
should supply the same selectors from RELIFOLD_ORGANIZATION and
RELIFOLD_WORKSPACE.
pipelines() is the bounded workspace overview. It returns version counts,
session-status counts, semantic operator families, and maximum DAG shape for every pipeline in one
collection read. It does not embed full declarations, prompts, session evidence, or review
quality.
versions() is a bounded catalog call: it returns lifecycle, count, semantic-family,
and execution-shape summaries, not every DAG declaration. After choosing a version, use
version() for its complete nodes, reviews, parameters, and readable callable
source.
metrics() returns totals, task-level observations, and an
operators rollup with calls, tokens, cost, reuse, failures, task runs, and wall time
attributed through each session's immutable version. Historical observations that cannot be
attributed are counted separately rather than guessed from a reused task name.
Act on suggestions
pending = workspace.advice("news-events", "v1")
suggestion = pending["parameter_advice"][0]
workspace.accept_parameter_advice(
"news-events",
"v1",
task=suggestion["task"],
params=suggestion["params"],
target_version="v2",
owner_pipeline_id=suggestion["owner_pipeline_id"],
owner_version_id=suggestion["owner_version_id"],
)
rejected = pending["prompt_advice"][0]
workspace.dismiss_advice(
"news-events",
"v1",
kind="prompt",
prompt_id=rejected["prompt_id"],
proposal_version=rejected["proposal_version"],
owner_pipeline_id=rejected["owner_pipeline_id"],
owner_version_id=rejected["owner_version_id"],
)
To change a draft, register its edited declaration again with
workspace.register_version(spec); the browser edits the same draft. Prompt and
parameter advice may be accepted into an editable successor or dismissed. Dismissal changes no
version, prompt, session, or output.
Pipeline and version pages offer Delete with confirmation. Deletion requires
edit permission for that pipeline, granted directly or through an access group. The corresponding
client methods are workspace.delete_pipeline(pipeline_id) and
workspace.delete_version(pipeline_id, version_id). Both draft and declared versions can
be deleted once no run, planning, Workbench run, or improvement suggestion being prepared is using
them. Deleting a version also deletes the deployments that run it, with their schedules, results
and run history; deleting a pipeline deletes all of its deployments. Results already delivered to
your own storage stay. Deletion frees the name: registering the same pipeline or version ID again
starts a new, empty version with no reviews, suggestions, research, or runs from the deleted one.
Workspace datasets are kept, and runs of the deleted version stay in the workspace's session
history.
Inspect version prompts and output rows
bindings = workspace.prompts("news-events", "v2")
for binding in bindings:
revision = workspace.prompt(
"news-events", binding["prompt_id"], binding["version"]
)
print(revision["text"])
for row in workspace.rows(session_id="session-id", space="scored-headlines"):
print(row)
Export an editable runner
artifact = workspace.export_version(
"news-events",
"v2",
language="python", # python, typescript, or cpp
)
with open(artifact["filename"], "w", encoding="utf-8") as target:
target.write(artifact["source"])
The exported runner reconstructs the declared DAG through the public API. It contains prompt bindings and non-secret connector configuration, but never embeds external data credentials.
Main operation groups
- pipelines, versions, prompts, planning, declaration, and code export;
- connections, datasets, uploads, and Spaces;
- reviews, curation cards, golden sets, and suggestions;
- manual runs, stopping, sessions, task output, and metrics;
- deployments and calendar schedules;
- organizations, groups, grants, workspaces, and API keys.
Stable import boundary
Import user-facing declarations from scratchpad.api. Modules beneath that boundary
are not part of the public contract.
AccountApiError with an HTTP status and a user-facing message. Treat 401 as expired or
revoked authentication, 403 as insufficient permission, 404 as a missing resource, 409 as
conflicting state, 422 as an invalid declaration, and 429 as a request-rate limit. A service error
uses a stable public message rather than exposing an upstream response body.