dataiku-sdk
Agent-only TypeScript SDK and dss CLI for Dataiku DSS automation.
API coverage
The SDK and CLI include scenario run management; project, recipe, and dataset metadata; managed datasets, lineage, and table imports; flow schema propagation and documentation; grouping and prepare recipes built from flags; Visual ML tasks, model diagnostics (subpopulation analyses, partial dependencies, time series residuals) and model documentation for lab models and saved-model versions; external saved models, MLflow imports, and the MLflow experiment-tracking extension; Project Deployer infrastructures, deployments, and published projects; LLM completions and embeddings; knowledge banks; project folders and data collections; users, groups, connections, macros, and plugin administration. Discover exact inputs with dss commands run and scoped command contracts rather than assuming flags from API field names. MLflow archive/folder imports and evaluations resolve the external container config explicitly: DSS 15 requires the containerExecConfigName parameter, so the SDK/CLI send NONE rather than omitting it (the plan surface matches the executed request).
The DSS 15 coverage matrix maps documented operations to SDK methods and CLI actions, records documentation discrepancies, and identifies remaining gaps. A machine-readable matrix is also available. Coverage is not full DSS parity or live compatibility certification: availability depends on DSS version, permissions, licensing, and installed capabilities. One known documentation discrepancy: plugin git-branches is served by GET on DSS 15 (the same route rejects POST with 405 rawMethodPOSTnotsupported, contrary to the public docs).
Metadata setters replace the complete metadata object: fetch it, edit it, then submit the replacement. Metadata previews expose that replacement under next. Mutation previews differ: --plan builds the request shape offline and makes no DSS requests, with sensitive payloads possibly represented by redacted summaries rather than literal request bodies, while --dry-run may read live DSS state per command (recipe run resolves its outputs). LLM completions and embeddings are cost-bearing operations, and macros execute plugin code. Review their contracts before execution.
ML training and macro waits bound status requests by the remaining wait deadline, including response bodies and retries. The client requestTimeoutMs still caps each request: an overall wait budget can shorten that cap, never extend it. An individual request timeout propagates as an error until the overall wait budget expires. Future and Project Git waits use adaptive polling by default; explicit polling intervals remain fixed. Early CLI usage errors load at most the selected resource definitions, not the full command runtime.
Malformed user/group listings and scenario run histories fail explicitly instead of appearing empty. Scenario and macro run responses must contain usable run identifiers; missing identifiers are server-response errors, not caller-validation errors.
Platform support
The published dss CLI requires Bun >= 1.4.3 and supports Linux, macOS, and Windows. CI runs Bun 1.4.3 on all three operating systems. The runtime dependency is pure JavaScript, so the same package also runs on every Bun-supported x64 and ARM64 system.
Run directly with Bun:
bunx --bun dataiku-sdk version
Or install the npm binary:
npm install --global dataiku-sdk
The installed dss bin bootstraps Bun with automatic .env preloading disabled, so Bun >= 1.4.3 must be on PATH; the CLI's own .env handling stays authoritative. bunx --bun forces Bun's Node-compatibility mode, which provides the same no-preload guarantee across operating systems.
Bun is the only supported runtime and the package manager. Examples below assume an installed dss binary. From a checkout, use bun --no-env-file src/cli.ts ... or the packaged launcher bun --no-env-file ./bin/dss.js .... From another working directory, pass the checkout's absolute bin/dss.js path to Bun.
--no-env-file disables Bun's automatic preloading only; the CLI still applies its documented .env handling unless DATAIKU_DISABLE_ENV=1 is set.
dss version reports whether the running code came from source or dist, the runtime (always bun), the packaged build revision when available, and staleBuild when that revision differs from the checkout. Release builds generate dist/build-metadata.json; source snapshots without Git metadata still build but report no build revision.
Self-provisioning live tests
From a checkout, test:live is a separate Bun script, not a dss command. It reads
the existing .env without changing it and needs project-creation access plus a
writable managed storage connection. No imported tutorials are required.
bun run test:live setup
bun run test:live run --case core.dataset.baseline
bun run test:live run --case "core.recipe.*"
bun run test:live run --profile all # every profile's run cases in one lab
bun run test:live run --profile ml --case "ml.*"
bun run test:live run --profile all --case "applications.*,infrastructure.sql-select"
bun run test:live status
bun run test:live clean # delete only this lab, including its root project
# CI: setup + run + cleanup, even when cases fail
bun run test:live all
setup is idempotent for a ready lab; run reuses its datasets, graph and collaboration
fixtures. Cases use temporary resources or restore baseline values. Cases accept exact
IDs, comma-separated lists, repeated --case, and trailing-prefix * matching; quote
wildcards. Selected runs omit the legacy suites. Unknown, setup-only or inactive-profile
or empty selections fail before credentials, state creation or provisioning; --case is valid only
for run/all. run refuses
an incomplete or cleaned lab rather than silently rebuilding it. Clean failed setup
before provisioning a replacement. Authentication and transport failures retain their
original errors; they are not evidence that the lab is missing.
--profile all is a selection operator, not a lifecycle command: it widens run-case
availability to every profile (core, ml, applications, infrastructure) in the same
persistent lab, and setup-only cases stay unselectable. The selector itself neither
provisions beyond the selected cases nor cleans — combined with the all VERB the
run still ends in the usual destructive cleanup.
Core fixtures include deterministic CSVs with nulls, duplicates, Unicode and quoting; server-provisioned managed datasets; sync, Prepare, join, fuzzy-join, grouping and Python recipes; folders, scenarios, variables, wiki, notebooks, dashboards, insights, libraries, metrics and quality rules. Project export/import/duplicate cases use separate owned projects. Managed dataset types, paths and recipe output schemas come from DSS rather than tutorial-specific connection guesses.
Profiles add to core: ml trains and deploys a small decision tree and checks clustering.
applications Designer cases provision disposable owned templates when
DATAIKU_LIVE_APP_TEMPLATE_ID is absent. That variable optionally selects an external
read-only template; version writes always use an owned template. The owned workflow
exercises form variables, a Python scenario, and a managed-folder download. Explicit-key
instance and successor creation still blocks before POST when target absence is unprovable.
Packaged Business Apps are separate: their cases use DATAIKU_LIVE_BUSINESS_APP_ID,
DATAIKU_LIVE_BAPP_INSTANCE_PROJECT, DATAIKU_LIVE_BAPP_USER, or
DATAIKU_LIVE_BAPP_ARCHIVE_PATH, and report missing prerequisites as blockers.
Other application and infrastructure read/CRUD cases run without these. The SQL probe
case needs DATAIKU_SQL_CONNECTION or DATAIKU_SQL_DATASET_FULL_NAME (other
infrastructure read-only cases run without either).
The SQL case permits only the fixed, table-free SELECT 1 AS one probe with an
explicit target and an owned project whose incarnation is checked before execution.
It does not authorize arbitrary SQL, alternate query inputs or global mutations. Missing
prerequisites are recorded as blocked, never passed. Required blocked cases exit
nonzero; optional blocked cases remain visible in reports. Global administration,
external Git mutations and unsupported capabilities are not silently exercised.
SQL catalog/import cases can provision an owned file-backed SQLite connection and
seed a real table. Project and plugin Git cases use owned bare repositories served on loopback
through the server's git-http-backend; they never change global Git rules. These
fixtures require server-side Python execution and the relevant admin/Git permissions.
Host paths and process identities are recorded in the manifest. Cleanup verifies
ownership before stopping services and deleting directories; failed cleanup retains
the runner project for recovery.
State is ignored by Git under .live-tests/<server-hash>/. Use --state-dir PATH to keep
a persistent demo or verification lab outside the default root — the directory is
created on demand, isolated per server hash, and never cleaned implicitly. For run,
clean or status you can alternatively select an existing lab with --manifest PATH
(the two flags overlap only there; setup/all require --state-dir instead). Keep the manifest and
cleanup.jsonl: cleanup requires exact project identities and creation-incarnation
hashes, never a prefix sweep. A changed server/project identity or unconfirmed creation
fails closed; investigate its journal before manual recovery. Locks prevent concurrent
lab runs; after an uncatchable process kill, confirm its recorded process is gone before
removing a stale lock. Interrupting a run preserves the lab; all attempts cleanup.
New globally-scoped case families create only isolated, disposable resources: users,
groups, meanings, workspaces, data collections, API-deployer infra/services/deployments,
and plugins require an explicit reservation in the lab manifest plus an exact
ownership marker written into a lab-controlled field and re-read on every GET
(ctx.markerFor; code-envs instead bind on the server's desc.creationTag
incarnation snapshot, and project folders have no nonce field — they bind on the
server-generated id plus owner binding). The lifecycle is explicit: reserve checks the
pending reservation against the manifest; create runs the command and binds the entry
only after a GET proves the marker/incarnation identity; bound-target mutations
re-verify the live object before every request. A GET that cannot prove identity
leaves the entry unconfirmed rather than bound. A failed creation is never deleted
blind and a conflicting pre-existing resource is recorded, not removed. Pre-existing
accounts, connections and configuration are never modified or deleted.
Trained-ML demonstration state is retained across iterations in the lab: the ml
profile keeps a real trained decision-tree model and its fixtures, so subsequent
iterations read model metadata, settings and versions without retraining.
Core fixtures include deterministic CSVs with nulls, duplicates, Unicode and quoting;
server-provisioned managed datasets; sync, Prepare, join, fuzzy-join, grouping and Python
recipes; folders, scenarios, variables, wiki, notebooks, dashboards, insights, libraries,
metrics and quality rules. Project export/import/duplicate cases use separate owned
projects. Managed dataset types, paths and recipe output schemas come from DSS rather
than tutorial-specific connection guesses. Expanded case families beyond the original
core set cover bundles (export/publish lifecycles), Project Git (inspect, commit,
remote and external-library lifecycles against owned loopback repositories), scenario statistics and
payload round-trips, application template and instance manifests, webapp backend state,
infrastructure reads (connections, users, groups, macros, code-envs, project folders,
data collections), disposable global lifecycles under the ownership-marker contract,
and disposable folders/notebooks with plugin.json receipt flows. Plugin cases that
generate a plugin-managed code environment delete that derived environment explicitly
before deleting the parent plugin (DSS does not cascade the deletion), and plugin updates
require the settings.codeEnvName association created after plugin creation. MLflow
import fixtures use canonical packaging (code:'code', data:'model', env:'conda.yaml')
inside owned runtime environments with pinned scientific versions, and both archive and
folder imports/evaluations pass explicit containerExecConfigName=NONE (DSS 15 rejects
requests that omit it; folder imports previously inherited a default); noncanonical
model-path layouts fail with READ_META ModuleNotFoundError.
Some capabilities have external prerequisites the lab cannot self-provision; each
affected action records an explicit per-action blocker instead of passing or being
silently omitted: an installed application template (DATAIKU_LIVE_APP_TEMPLATE_ID),
external SQL connectivity for non-fixture workloads (DATAIKU_SQL_CONNECTION/DATAIKU_SQL_DATASET_FULL_NAME),
an external auth backend (LDAP/SAML) for user external-directory reads and resyncs, plugin-store
access, and any cost-bearing surface (LLM completions/embeddings bill per call; macros
execute plugin code). Missing credentials, templates, external infrastructure or billing
eligibility are reported as blocked, never as success.
Each iteration retains logs and report.json with cases, timing, executed actions,
capability reasons, coverage and external-project metadata integrity. Unavailable project
metadata is reported separately in integrity.unreadable, not as confirmed drift;
integrity remains unverified and the run fails until those reads succeed. clean retains
cleanup-report.json, including deletion failures; starting teardown invalidates lab
readiness even if cleanup only partially succeeds. If cleanup and integrity verification
both fail, the cleanup error remains primary and the report preserves both results.
Planned lifecycle commands retain ownership checks; local outputs stay inside the lab
for both --output and --output-file. Treat local reports and exported archives as private project
data. Coverage is an explicit inventory of every registered action, not a claim that
every action has a live test: unexercised actions remain uncovered, and the
expanded demonstration keeps each registered action visible as demonstrated, blocked
with a recorded prerequisite, or uncovered — never silently dropped. Add cases through
the typed catalogue in tests/live-cases.ts, LiveContext.check and guarded helpers,
then update tests/live-coverage.ts when the
registry changes; catalogue drift fails the offline gate. Plan/dry-run calls do not count
as executed live coverage.
Regular bun run verify and bun run lint include the live runner and fixtures.
Lint includes project-owned rules in tools/oxlint/index.ts: accumulator-copy, widen-then-assert, and chained-assertion errors, alongside the native accumulating-spread check.
For focused verification:
bun run check:live
bun test tests/live-context.test.ts tests/live-runner.test.ts tests/live-coverage.test.ts
CLI contract
The complete agent-facing contract — stdout JSON discipline, stderr JSONL diagnostics, the error
envelope, exit codes, --fields projection, command discovery, and planning/safety rules — is the
skill bundle rooted at skills/dataiku-dss/SKILL.md. The short
entrypoint routes agents to focused references; the installed command registry remains the source
of truth for command syntax and schemas. Human
essentials: exactly one compact JSON value on stdout per command (void success is {ok:true}),
failures as one structured JSON error object on stdout with a nonzero exit code, stderr reserved
for JSONL diagnostics only, and exit codes 0 success / 1 usage error / 2 DSS or internal
error / 3 transient DSS error / 4 failed long-running result or assertion. --retries N
controls idempotent GET retries only, and only transient failures (408/425/429, 5xx without a known
non-transient cause, connection resets, timeouts) are retried: a refused connection, unknown host,
bad URL, or untrusted certificate fails at once. dss sql query --start-retries N retries transient failures
while starting a query. For portable multi-step mutations, prefer dss batch; shell chaining and
pipeline exit semantics differ across platforms.
*.list commands print compact items (identifiers, kind, next-step fields) by default; --full
returns the DSS objects, --contains TEXT filters on identifiers, and --limit N caps the count
with a list_truncated warning.
Discover the command surface with scoped calls:
dss commands run
dss commands run --contains "propagate schema"
dss commands run --fields dataset.create.usage,dataset.create.description,dataset.create.flags,dataset.create.examples
dss commands run --output commands.json
dss agent contract --fields protocol,agentContractVersion,cli,stdio,planning,compatibility
dss commands run prints the compact resource/action summary, and --contains TEXT finds the top 5
actions for a concept; registry entries never dump to stdout — they travel only via --output PATH.
See the canonical skill for the full --fields projection rules and planning workflow.
Agent skill installation
dss install-skill --list-agents
dss install-skill --agent omp --target .
dss install-skill --agent omp --target . --dry-run
dss install-skill --global --agent omp
--list-agents only reports targetable agents; it does not write files. Auto-detection checks supported agent binaries/config directories (claude, codex, cursor, pi, omp). Passing --agent NAME forces one entry and reports via:"flag".
Project installs write SKILL.md and its sibling references/ directory under the target workspace:
- Claude:
.claude/skills/dataiku-dss/SKILL.md - Codex:
.codex/skills/dataiku-dss/SKILL.md - Cursor:
.cursor/skills/dataiku-dss/SKILL.md - Pi:
.pi/skills/dataiku-dss/SKILL.md - OMP:
.omp/skills/dataiku-dss/SKILL.md
Global installs write under the agent's home config path, for example OMP: ~/.omp/agent/skills/dataiku-dss/SKILL.md. The reported target is the home directory for global installs and the resolved workspace directory for project installs; installed[].path names each entrypoint.
Each entry in the installed array reports pre-install bundle state:
status:missingwhen the entrypoint is absent;stalewhen any bundled file is missing or differs;currentwhen every bundled file matches.changed: whether any bundled file would (or did) change. Byte-identical files are not rewritten.expectedSha256andactualSha256: the canonical and existing entrypoint hashes. The latter is absent when the entrypoint is missing.files: each bundled file's portablerelativePath, destinationpath,status,changed, and hashes. Missing or stale references are detected even whenSKILL.mditself is current.
--dry-run and --plan never write. Real installs replace changed files through same-directory temporary files and rename, writing references before the entrypoint. Atomicity is per file, not a bundle-wide transaction. Unrelated files in the destination are preserved.
Token-efficient skill structure
The entrypoint contains bootstrap/discovery, output interpretation, and universal safety rules. Seven focused files under references/ cover authentication, discovery, mutations, application releases, flow maps, coding, and troubleshooting. All are linked directly from SKILL.md with task-specific read conditions; agents should not preload the whole directory.
The entrypoint measures 774 o200k_base tokens, within its 825-token budget. Current Claude V5 reconstruction and GLM5 counts are 1,297 and 776. Safety rules and all seven reference links remain. Reference content consumes context only when read; all five agent installers ship the complete bundle.
All seven references are token-budgeted (each measured o200k_base baseline plus 5% headroom). Per-file baselines live in the token-budget tests; run bun run test:tokens to check them.
References total 3,797 o200k_base tokens; including the entrypoint, the bundle totals 4,571. This is a sum of file counts, not a recommendation to preload them. Runnable examples, sharing safeguards, and cleanup conditions are retained.
This uses progressive disclosure from the Agent Skills specification and Anthropic's authoring guidance: concise metadata/instructions, direct relative reference links, and domain-focused documents. No scripts or assets are needed here; generated command metadata is queried from the CLI rather than duplicated in the skill.
bun run test:tokens enforces the pinned OpenAI o200k_base budgets. To also check ten native encodings (OpenAI, Claude, GLM, Qwen, DeepSeek, and Kimi), point the optional development-only gate at an OMP native module:
DSS_TOKENIZER_MODULE=/absolute/path/to/oh-my-pi/packages/natives/native/index.js bun run test:tokens
When configured, the native module also accelerates ordinary OpenAI token measurements after parity checks against the pinned JavaScript model. The JS fingerprint and independent cross-model reference checks remain authoritative; reserved special-token validation is preserved. Without this variable, measurements use JavaScript and only the native cross-model case is skipped. A configured missing/incompatible module fails instead of silently falling back. The cross-model gate permits 10% growth over recorded text baselines. Claude counts use ctok reconstructions, not an official tokenizer; counts exclude provider framing. No native dependency is added to the CLI.
For a known resource, dss agent contract --fields commands.actions.dataset lists only its action names, far smaller than the global index; for known writes, fetch the full action entry directly once rather than compact discovery followed by the full entry. bun run test:tokens pins the current figures. Use compact usage,description,flags,examples projections for reads when those fields suffice. This is selective disclosure, not lossless compression. Scoped discovery constructs only requested action entries and materializes schemas only when requested; action-name indexes avoid payload schemas, while full registry exports and recovery hints retain their existing content. Metadata-only paths defer SDK runtime/schema imports.
Boolean flags accept bare flags or explicit =true/=false values, including aliases. Invalid boolean values fail before dispatch. Direct, batch, and local commands share execution-mode resolution; --plan --dry-run returns a plan with plannedAndDryRun:true when both modes are supported. Unreadable JSON/text payload files produce validation_failed usage errors (exit 1) with the flag, path, and filesystem cause.
For raw streaming downloads, --request-timeout MS bounds each pending body read, not the total transfer duration: large progressing transfers remain supported. Buffered text/JSON consumers retain their bounded body-read budget. Request retries do not replay partially consumed streams. Project, bundle, and API-service archives and managed-folder downloads are written to private temporary files beside the destination, then renamed on success. Failures leave no partial output and preserve any existing destination.
The SDK configuration maxResponseBodyBytes (default 50 MiB) also bounds retained non-2xx response bodies. Oversized errors preserve HTTP status, header request IDs, and a UTF-8-safe prefix, with DataikuError.bodyTruncated: true; CLI errors expose details.bodyTruncated: true. Retry eligibility is unchanged, and error-body reads share the transport attempt deadline.
Eligible transient retries honor Retry-After delta-seconds and HTTP dates, waiting at least the greater of server guidance and normal jittered backoff. Invalid or past values use normal backoff. Server waits above the existing 30-second automatic backoff cap decline retry and return the original error rather than retrying early. Total request deadlines remain authoritative; this does not enable retries for otherwise non-retryable requests.
Credentials
Use environment variables for ephemeral runs. For disposable agent tests, set DSS_CONFIG_DIR to a temporary directory so saved credentials never touch your real profile.
Credential precedence is flags first, then DATAIKU_* environment variables, then saved credentials in DSS_CONFIG_DIR or the platform config directory.
Set DATAIKU_DISABLE_ENV=1 when a test must ignore both .env files and DATAIKU_* environment variables.
When .env loading is enabled, the CLI reads .env from the CLI build/root directory and from the command's current working directory; put test-specific .env files in the directory where you invoke dss. Only DATAIKU_*, NODE_TLS_REJECT_UNAUTHORIZED, and NODE_EXTRA_CA_CERTS are read from .env; other keys are ignored.
Set DSS_PRETTY=1 to indent stdout JSON (still one JSON value). Use it when the shell or agent harness cuts long lines (omp's bash tool cuts each line at 768 bytes), so a one-line result is not truncated. It is read from the process environment only, not from .env.
POSIX shell:
export DATAIKU_URL=https://dss.example.com
export DATAIKU_API_KEY=your-api-key
export DATAIKU_PROJECT_KEY=MYPROJ
dss project list
PowerShell:
$env:DATAIKU_URL = "https://dss.example.com"
$env:DATAIKU_API_KEY = "your-api-key"
$env:DATAIKU_PROJECT_KEY = "MYPROJ"
dss project list
Windows Command Prompt:
set "DATAIKU_URL=https://dss.example.com"
set "DATAIKU_API_KEY=your-api-key"
set "DATAIKU_PROJECT_KEY=MYPROJ"
dss project list
Persist credentials when needed:
dss auth login --url https://dss.example.com --api-key YOUR_KEY --project-key MYPROJ
The command saves credentials and returns { "saved": true, "path": "..." }.
auth login validates by listing accessible projects before saving credentials, so the API key must be allowed to call DSS project-list APIs.
Examples
dss version
dss doctor --fast
dss project list
dss project inspect-archive ./project.zip
dss project import ./project.zip --target-project-key IMPORTED_PROJECT --record-cleanup cleanup.jsonl
dss dataset list --project-key MYPROJ
dss dataset files uploaded_input --project-key MYPROJ
dss dataset upload-file uploaded_input ./new.csv --file-name new.csv --project-key MYPROJ
dss dataset assert-count jmp_doe_ready --expected 12 --project-key MYPROJ
dss dataset assert-schema jmp_doe_ready --data-file expected-schema.json --project-key MYPROJ
dss data-quality assert-results jmp_doe_ready --project-key MYPROJ
dss recipe get-payload compute_orders --project-key MYPROJ
dss recipe get-payload compute_orders --output code.py --project-key MYPROJ
dss install-skill --dry-run
dss app validate-manifest --project-key MYAPP_INSTANCE
dss app compare-manifest my-app --project-key MYAPP_INSTANCE
dss app create-instance my-app --data '{"targetProjectName":"My app instance"}' --wait --record-cleanup cleanup.jsonl
# Substitute the returned projectKey for MYAPP_INSTANCE in later commands.
dss app manifest-version --project-key MYAPP_TEMPLATE
dss app successor-preflight my-app --from MYAPP_INSTANCE --to MYAPP_INSTANCE_V2 --copy-permissions
dss app set-manifest-version --manifest-version 1.4.0 --expect-hash PREFLIGHT_TEMPLATE_MANIFEST_HASH --project-key MYAPP_TEMPLATE
dss app create-successor-instance my-app --from MYAPP_INSTANCE --to MYAPP_INSTANCE_V2 --copy-permissions --record-cleanup cleanup.jsonl
# Or omit --to: the target key is generated during apply (preflight/plan allocate nothing).
dss app create-successor-instance my-app --from MYAPP_INSTANCE --copy-permissions --record-cleanup cleanup.jsonl
dss app verify-instance my-app --project-key MYAPP_INSTANCE_V2 --expect-version 1.4.0
dss app permissions-snapshot --project-key MYAPP_INSTANCE --output permissions.json
dss app permissions-diff --project-key MYAPP_INSTANCE --file permissions.json
dss app permissions-restore --project-key MYAPP_INSTANCE --file permissions.json --dry-run
dss cleanup --file cleanup.jsonl
dss cleanup --file cleanup.jsonl --apply
project import performs both public API stages: archive upload, then import processing. It
first validates ZIP integrity, safe unique member paths, the export manifest, and provable Flow
references locally. Verified success reports DSS's actual project key, explicit remapping, and a
creationTag incarnation hash; --record-cleanup records an incarnation-bound guarded delete.
It exits nonzero when DSS returns success:false even if both HTTP requests succeeded. A timeout,
5xx, malformed response, missing used key, or failed post-import identity read is
ambiguous_outcome and retains the temporary import ID for inspection before retry.
dataset upload-file only adds a filename that is not already present and verifies its byte
length afterward. DSS 14.7 exposes no public UploadedFiles delete or replacement endpoint;
the command refuses an existing filename before POST instead of triggering DSS's opaque 500.
For replacement, import a successor project archive containing the desired upload.
dataset preview returns truncated and limit; it probes one row past the requested cap instead
of presenting a capped sample as an exact count. dataset assert-count, dataset assert-schema,
and data-quality assert-results return satisfied and exit 4/assertion_failed on a failed
postcondition, so they can be used as batch steps. Multi-job job monitor and job watch
aggregate child failures and also exit 4 when any watched job fails.
doctor reads the documented DSS-Version and DSS-API-Version response headers plus the HTTP
Date header from the public project-list call. Feature support remains behavioral: the CLI does
not call an undocumented feature endpoint or infer licensed capabilities from a version string.
Application release safety
Use the app commands as explicit release gates around a stable template, instance project key, and permission set:
# Validate source-verifiable manifest references.
dss app validate-manifest --project-key APP_TEMPLATE
# Detect governed template/instance drift. Only projectKey and projectAppType are normalized away.
dss app compare-manifest APP_ID --project-key RELEASE_INSTANCE
# Read the raw `version` from the public app manifest (string fields only; never appVersion).
dss app manifest-version --project-key APP_TEMPLATE
# Run every read-only successor gate before changing the template version. This validates the
# template references, verifies the predecessor, proves target absence for an explicit --to, and
# optionally snapshots the predecessor ACL. Keep template.manifestHash from the result for the
# next command. Omit --to to leave the target to apply: preflight then reports
# targetProjectKeyGeneratedDuringApply with no absence probe and no allocation.
dss app successor-preflight APP_ID \
--from RELEASE_INSTANCE --to RELEASE_INSTANCE_V2 --copy-permissions
# Write version/versionNotes through the public app-manifest endpoint. This is NOT a publish
# transaction: it only changes the raw manifest metadata. --expect-hash SHA256 is a non-atomic
# stale-read guard, not a conditional write: it refuses the write when the manifest already
# changed since you read that hash, but DSS accepts every PUT unconditionally. This command can
# overwrite a write landing between its read and PUT, and the final read cannot detect that lost
# update when this command's payload wins. Every result reports
# concurrencyControl: "client-side-non-atomic-stale-read-check".
dss app set-manifest-version --manifest-version 1.4.0 \
--expect-hash PREFLIGHT_TEMPLATE_MANIFEST_HASH --project-key APP_TEMPLATE
# Create a fresh instance without global project visibility; the CLI generates the key.
# Use the returned projectKey for verification and later commands; cleanup binds that instance.
dss app create-instance APP_ID \
--data '{"targetProjectName":"Release instance"}' \
--wait --record-cleanup cleanup.jsonl
# Roll out a new template version to an existing instance as an additive successor: the old
# instance is never modified or deleted, and the command always waits on the DSS future
# (there is no --wait flag). The recorded cleanup entry targets only the new project key. If DSS
# may have accepted creation but no future ID is returned, the outcome is indeterminate and no
# unbound cleanup entry is written. Omit --to to generate the target key during apply: preflight
# and plans stay allocation-free, the key is generated once before the single POST, and cleanup
# binds it through the creation future plus creationTag.
dss app create-successor-instance APP_ID \
--from RELEASE_INSTANCE --to RELEASE_INSTANCE_V2 \
--name "Release instance v2" --copy-permissions --record-cleanup cleanup.jsonl
dss app create-successor-instance APP_ID \
--from RELEASE_INSTANCE --name "Release instance v2" --copy-permissions --record-cleanup cleanup.jsonl
# API readiness gate for the successor. apiReady:true with status API_VERIFIED_UI_PENDING is an
# API-verified state only — never visual verification. The API key authenticates public REST only;
# visual confirmation stays an external SSO gate (pre-authenticated SSO browser session or a
# dedicated UI test identity).
dss app verify-instance APP_ID --project-key RELEASE_INSTANCE_V2 --expect-version 1.4.0
# Retirement of the predecessor is a separate, separately guarded step after the successor is
# verified. It is never performed implicitly by the successor flow.
dss app delete-instance --project-key RELEASE_INSTANCE
# Snapshot, compare, preview, and restore project permissions.
dss app permissions-snapshot --project-key RELEASE_INSTANCE --output permissions.json
dss app permissions-diff --project-key RELEASE_INSTANCE --file permissions.json
dss app permissions-restore --project-key RELEASE_INSTANCE --file permissions.json --dry-run
dss app permissions-restore --project-key RELEASE_INSTANCE --file permissions.json
Permission snapshots are written with mode 0600 and an integrity hash covering the canonical DSS
URL, the concrete project incarnation (creationTag), capture metadata, and permissions. Diff and
restore reject snapshots from another DSS server, project key, or observed incarnation. These are
client-side, non-atomic stale-identity checks: DSS exposes no conditional permission PUT, so the
checks narrow and detect key-reuse races but cannot serialize the final check with the write.
Snapshots contain access-control identities; commit them only when repository policy permits.
validate-manifest checks SCENARIO_RUN scenario IDs, DOWNLOAD_MANAGED_FOLDER_FILE
folder IDs, and PROJECT_VARIABLES_EDIT parameter names against supported public project APIs.
Unknown tile types and custom content remain opaque; reference validation is not UI-rendering proof.
Fresh app create-instance requests can omit targetProjectKey: the CLI generates a cryptographic
APP_ + UUIDv4 key locally (122 random bits), without global visibility probes. It preserves
targetProjectName; if omitted, the name defaults to the key. Normal app-instantiation permissions
still apply. Use the returned projectKey for verification and later commands. Only omission
selects generation; explicit blank, null, or non-string keys are rejected. Collision risk is
negligible, not zero; DSS does not document atomic duplicate-key rejection. This follows the
official client's random-key pattern.
Caller-chosen keys, including successor --to, still require confirmed absence before POST.
A masked 403 remains target_absence_unverifiable / permission_or_environment, even if absent from
visible lists. DSS has no public availability endpoint or force bypass; exact keys need global
visibility. Otherwise omit the key for a fresh instance, or omit successor --to to generate the
successor target during apply. Definitive rejections produce no cleanup entry; ambiguous POSTs
without a future ID or verified incarnation produce none either.
Plans allocate and reserve nothing. Direct create-instance generated-key plans report
preflightExecuted:false and preflightWillRunDuringApply:false; explicit-key plans report the
latter as true. create-successor-instance plans always report
preflightWillRunDuringApply:true — with --to the read-only gates re-run during apply, and
without --to the target key is generated only then
(targetProjectKeyGeneratedDuringApply:true, preflightExecuted:false). Use --plan
for preview (create-instance does not support --dry-run). Run successor-preflight for named
releases when live read evidence is required before changing the template version.
Every new cleanup entry records the canonical DSS URL. App-instance cleanup records a
creationTag hash observed after the DSS future identifies the target key; a future-addressable
entry stops unresolved until the future names that key and its incarnation can be bound. An
ambiguous POST with no future ID produces no entry. The future target and later creationTag are independent, non-atomic
observations: the public API exposes neither an immutable project ID joined to the future nor a
conditional DELETE. Cleanup rechecks type and creationTag immediately before deletion, rejecting
detected key reuse, but cannot eliminate replacement in the remaining check-to-DELETE gap.
cleanup --apply validates the full ledger before issuing any request and rejects legacy entries
without server identity, mixed-server ledgers, entries for another DSS URL, and app cleanup entries
without a valid incarnation binding. Project-import cleanup uses the same rule: the ledger binds
the actual imported key and verified creationTag hash, and project delete --expect-project-incarnation refuses a reused or unverifiable key before DELETE.
Saving version/versionNotes in the public app manifest is a metadata write, not a publish
transaction. If the manifest PUT or its verification read has an ambiguous transport/server
failure, the command exits non-zero with persisted:null, after:null, and
outcome:"indeterminate" rather than claiming the write failed or succeeded. Existing instances
are never upgraded in place: new instances inherit the template's
raw version, and an existing instance is rolled forward by creating an additive successor (the
old instance is preserved) followed by a separate, guarded retirement. verify-instance never
reports visual verification: its output is apiReady:true with
status:"API_VERIFIED_UI_PENDING" and uiPublicationVerified:false. Its visual-ui gate names
the required authentication and evidence: open the instance in a pre-authenticated SSO browser or
with a dedicated UI test identity, then exercise the affected tiles, forms, and actions. The CLI
never marks that external check complete. The public DSS APIs used by this SDK do not expose a
supported app-template publish/recreate/rename workflow, recipient-level app sharing setter, or
UI-click smoke test. The CLI does not guess private endpoints for those operations.
Flow visualization and zone planning
project map returns one agent-oriented JSON view of the Flow: normalized nodes and edges,
joined zone metadata, cycle-safe topological layers, weakly connected components, diagnostics, and
a stable topologyFingerprint. Output is deduplicated: node name appears only when it differs from
id; each node carries zoneId/componentId (zone names live in zones[], membership is derived
from those ids, so zones[]/components[] omit nodeIds); warnings appears only when non-empty and
truncation only when the map was cut. zones preserves zone color, position, and item count.
dss project map --project-key MYPROJ
dss project map --render mermaid --project-key MYPROJ
dss project map --render ascii --max-nodes 100 --max-edges 200 --project-key MYPROJ
Rendering is optional and remains inside the JSON result as rendering.content; stdout never
switches to an unstructured diagram stream. Layers are computed after collapsing strongly connected
components, so cycles are reported without blocking the analysis. Diagnostics cover cycles,
disconnected components, isolated/default-zone nodes, cross-zone edges, duplicate assignments, and
truncated analysis. When limits truncate the returned nodes or edges, the topology fingerprint still
covers the full normalized Flow while layers/components/diagnostics cover the returned subset.
The public API exposes zone positions and membership, not individual node pixel coordinates. The CLI therefore preserves only supported zone-level visual metadata and never fabricates node coordinates. Use the declarative export/apply loop for visual organization:
dss flow-zone plan --project-key MYPROJ > flow-zones.json
dss flow-zone organize --file flow-zones.json --dry-run --project-key MYPROJ
dss flow-zone organize --file flow-zones.json --project-key MYPROJ
flow-zone plan emits JSON accepted directly by flow-zone organize, including every
current zone's supported metadata and explicit items. Reapplying an unchanged plan produces no
redundant moves. organize compares the plan's topology fingerprint before mutation and recomputes
it after mutation; a mismatch fails rather than claiming a visual-only change. Zone names, colors,
positions, and membership are deliberately excluded from the fingerprint; flow node identity/kind and
edges are included.
Recipe/code analysis is a separate audit. project map and flow-zone plan do not fetch,
hash, interpret, or grade recipe payloads. Use the recipe inspection/diff/assertion commands in a
separate workflow when code quality or semantic review is required; never mix those findings into a
layout plan.
Project Git source-control safety
Project Git commands require DSS 12.4.2 or newer plus read and write access to the project
content. Inspect state before changing it:
The DSS project Git API exposes status, remotes, branches, tags, branch switching, fetch,
rebase-based pull, push, log, diff, commit, revert/reset/rebuild, external-library, and future
operations. It does not expose a separate checkout operation; use switch.
dss project-git status --project-key MYPROJ
dss project-git branches --remote --project-key MYPROJ
dss project-git log --count 20 --project-key MYPROJ
Creating a branch in a duplicate project is the safe UAT path; creating it in place switches the source project to the new branch:
dss project-git create-branch feature/orders \
--duplicate-project \
--target-project-key MYPROJ_ORDERS_UAT \
--project-key MYPROJ \
--plan
dss project-git create-branch feature/orders \
--duplicate-project \
--target-project-key MYPROJ_ORDERS_UAT \
--project-key MYPROJ
pull rebases rather than merging. reset-to-head, reset-to-upstream, reverts, forced or
remote branch deletion, library-directory deletion, and drop-and-rebuild are destructive;
inspect their local --plan result first. drop-and-rebuild additionally requires
--i-know-what-i-am-doing and destroys all Git history. Repository URLs containing embedded
HTTP credentials are rejected. External-library credentials must come from
--password-env ENV_NAME; the value is never included in plans or command output. Library
operations that return a jobId can be observed with project-git future-status or completed
with project-git future-wait.
Project Git requests use /dip/publicapi/projects/{projectKey}/git/*; they do not configure
remote authentication. DSS documents administrator Git group rules plus either per-user SSH keys
under Profile > Credentials > SSH or non-interactive system-level credentials for the DSS
server account. Configure these before private-remote fetch, pull, or push. --password-env
applies only to external project-library operations and does not persist a remote credential.
The project-git resource does not manage these settings, so public/auth-less and
already-configured remotes are the supported automation paths.
Coding, notebooks, and project libraries
project-library manages files in a project's internal lib/ tree. External Git-backed
libraries are a different surface: inspect and change those with project-git list-libraries,
set-library, push-library, and the related future commands. Internal paths are canonicalized;
leading slashes are removed, while traversal (..) and empty segments are rejected.
Use a read/diff/guarded-write sequence for internal files. get-bytes preserves binary data and
returns its SHA-256; diff caps text output and detects binary files instead of dumping bytes.
put --expect-sha256 re-reads the remote bytes and refuses a stale overwrite. New files and
folders never overwrite existing items; --if-not-exists turns an existing target into a skip.
dss project-library get-bytes python/mylib/utils.py --output ./utils.py --project-key MYPROJ
dss project-library diff python/mylib/utils.py --file ./utils.py --project-key MYPROJ
dss project-library put python/mylib/utils.py --file ./utils.py --expect-sha256 HASH --dry-run --project-key MYPROJ
dss project-library put python/mylib/utils.py --file ./utils.py --expect-sha256 HASH --project-key MYPROJ
For one-off Python, prefer a file so shell quoting cannot change the source. code run creates an
observable throwaway custom-Python scenario, waits with a bounded timeout, caps returned logs, and
deletes only that generated scenario unless --keep is set.
dss code run --file inspect.py --env py311 --project-key MYPROJ
dss recipe diff prepare_orders --file recipe.py --project-key MYPROJ
dss recipe set-payload prepare_orders --file recipe.py --dry-run --project-key MYPROJ
dss recipe set-payload prepare_orders --file recipe.py --backup-dir .dss-backups/recipes --project-key MYPROJ
dss recipe run prepare_orders --dry-run --project-key MYPROJ
Recipe payload diffs normalize LF/CRLF. set-payload backs up payload, graph, settings, code-env,
and version metadata by default; use restore --backup FILE --dry-run before applying a rollback.
recipe run --dry-run performs live output resolution without creating a job; static
--plan reports exact:false rather than inventing that live payload.
Notebook saves are save-or-create operations. Read first, preserve the full notebook object, then
use the persisted hash from save/dry-run output with --expect-hash. Jupyter output clearing uses
the official DELETE endpoint. unload-jupyter --all is deliberately composed: list active
notebooks, list their sessions, then delete each session; DSS has no unload-all endpoint.
dss notebook get-jupyter analysis.ipynb --project-key MYPROJ
dss notebook save-jupyter analysis.ipynb --data-file notebook.json --dry-run --project-key MYPROJ
dss notebook save-jupyter analysis.ipynb --data-file notebook.json --expect-hash HASH --project-key MYPROJ
dss notebook clear-jupyter-outputs analysis.ipynb --dry-run --project-key MYPROJ
dss notebook unload-jupyter --all --dry-run --project-key MYPROJ
Code-environment reads expose definitions, deployment mode, installed/requested packages, project
versions, usages, and bounded build logs. Fetch the definition/hash before set-definition or
set-packages --expect-hash; package, image, Jupyter, create, and delete operations can return DSS
futures with --no-wait. set-packages replaces the requested package list wholesale: an
explicitly empty --packages '' value (or an empty --file) clears the requested specs, while a
call with no package source flag at all is a usage error.
Webapp updates use GET–deep-merge–PUT; API-service save-settings is explicit full replacement.
Run either with --dry-run to inspect currentHash/nextHash, then apply with
--expect-hash. Webapp restart futures support --wait. API packages and project bundles
forward release notes and explicit Deployer target IDs.
An agent plan with exact:false is an honesty boundary: live state is required and no endpoint or
payload was guessed. Use the command's own --dry-run when it resolves that state. The supported
public DSS API exposes no plugin-authoring lifecycle, notebook execution/checkpoint operation, or
webapp/API-service delete. Use project Git for plugin source, code run/recipes for execution,
and the authenticated DSS UI for unsupported lifecycle operations.
For fake-DSS smoke tests, return project lists as JSON arrays such as [{ "projectKey": "MYPROJ", "name": "My Project" }] from /public/api/projects/; recipe payload commands read /public/api/projects/<PROJECT>/recipes/<NAME>?includePayload=true and expect a JSON object shaped like { "recipe": { "name": "<NAME>", "type": "python" }, "payload": "..." }.
License
This project is source-available under the Dataiku SDK Limited Use License 1.0, not an open-source license.
- Individuals acting on their own behalf may use unmodified copies without a license fee.
- Companies with total annual gross revenue below US $1,000,000 may use unmodified copies without a license fee.
- Companies at or above that threshold, and all other entities, must request and obtain a separate written license before use.
- Every modification, including private or internal changes, and every form of redistribution requires prior written approval.
- Permitted use must preserve the license notices and display:
dataiku-sdk by clssck — https://github.com/clssck/dataiku-sdk.
Copies previously received under another license retain the rights granted for those copies. See LICENSE for the controlling terms and request path.