Python API
Authenticate once and use the same product operations as the browser.
Account authentication
import os
from scratchpad.api import ScratchpadClient
account = ScratchpadClient(
"https://api.relifold.com",
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(workspace.pipelines())
print([
(
pipeline["pipeline_id"],
pipeline["version_count"],
pipeline["session_statuses"],
)
for pipeline in workspace.pipeline_catalog()
])
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.
pipeline_catalog() 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.
Edit a draft and act on suggestions
workspace.add_node(
"news-events",
"draft",
'''Select(
input_spaces=("headlines",),
output_space="headline-fields",
name="select-headline-fields",
fields=("article_id", "headline"),
)''',
)
workspace.add_nodes(
"news-events",
"draft",
[
'''Select(
input_spaces=("headline-fields",),
output_space="recent-headlines",
name="select-recent",
fields=("article_id", "headline"),
)''',
"Barrier()",
],
)
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"],
)
add_node, add_nodes, replace_node, and
delete_node edit the same draft DAG shown in the browser. add_nodes
validates every ordered constructor and task name before atomically changing the 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 active runs, planning, and deployments no longer use them. Workspace datasets and
run history are retained. A deleted version name cannot be reused.
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"])
page = workspace.space_rows(
"scored-headlines", session_id="session-id", limit=100
)
for row in page["rows"]:
print(row["data"])
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.