Skip to main content
POST
Python SDK

Authorizations

Authorization
string
header
required

Enter your API key (e.g. dai_sk_test_key_001)

Headers

Authorization
string
X-Workspace-Id
string | null

Cookies

decimal_session
string | null

Body

application/json

Validated request for POST /skills/sync.

Single endpoint covers both CLI (bidirectional reconciliation) and SDK (one-way upsert) — the difference is the response_mode flag (rich actions array for CLI, summary counts for SDK) and the conflict_policy (CLI defaults to newer_wins for human-in-the-loop, CI/SDK should set local_wins because the repo is the source of truth).

skills
SyncSkillItem · object[]
required
Required array length: 1 - 200 elements
author
string | null

Label (e.g. a CI runner's name) shown as the author of every version this sync creates (anyone can read it on a published skill). Who made each version is recorded separately.

offer_scope
enum<string> | null

Which agents get the skills this sync CREATES (existing skills keep theirs): 'restricted' (the default) = only agents you add them to (agent_name adds them to one), 'workspace' = every agent. An item's own offer_scope wins. (Until 2026-10-25 a sync from an API key that left it out offered them to every agent.)

Available options:
workspace,
restricted
agent_name
string | null

Add the synced skills to this agent (and record its config version). New skills are then created 'restricted' unless offer_scope says otherwise, and each one goes on the agent in the same transaction as its create. An agent that doesn't exist yet is created (an SDK adapter syncs before the agent's first run), under the same name rules as POST /agents; a name those rules refuse is reported in agent_not_found, and the skills sync as if no agent had been named.

Maximum string length: 255
add_to_agent
enum<string>
default:all

With agent_name: 'all' adds every synced skill to the agent, including one a person removed from it (an explicit add). 'unless_removed' adds every synced skill except the ones a person removed from this agent, which are listed in kept_off. An SDK adapter syncs on every agent boot and sends 'unless_removed', so a restart never undoes a removal made on the dashboard.

Available options:
all,
unless_removed
install_id
string | null

Project-local install identity (persisted by the SDK in .decimal/install.json). When present, the sync records per-install divergence state so GET /skills/installs can flag local/remote drift. Omit for back-compat: the sync then behaves exactly as before.

Maximum string length: 128
install_label
string | null

Human-friendly install label (hostname, 'ci', …) for the dashboard.

Maximum string length: 200
conflict_policy
enum<string>
default:newer_wins

newer_wins: compare timestamps (default; right for interactive CLI). local_wins: always overwrite remote (right for CI / build artifacts). remote_wins: never overwrite local; conflicts return pulled actions. remote_wins_on_conflict: decide from this install's last sync (send install_id). A body only the local copy changed is pushed; every other difference is pulled, and a pull of a local body the platform never stored says conflict: true so the caller can keep a copy before overwriting it.

Available options:
newer_wins,
local_wins,
remote_wins,
remote_wins_on_conflict
response_mode
enum<string>
default:summary

summary: return counts only (cheap; SDK default). diff: return per-skill actions array including bodies for pulled skills (CLI).

Available options:
summary,
diff

Response

Successful Response

status
string
required
Allowed value: "ok"
created
integer
required

Number of new skills created.

updated
integer
required

Number of existing skills with a new version (pushed).

unchanged
integer
required

Number of skills whose body hash matched — no-op.

pulled
integer
default:0

Number of skills where remote was newer; caller should refresh local.

failures
Failures · object[]

Per-skill failures with name + error.

actions
SyncSkillAction · object[] | null

Per-skill action list — present only when response_mode='diff'.

added_to_agent
string | null

With agent_name: the agent the synced skills were added to.

added
string[] | null

With agent_name: the skills added to it.

kept_off
string[] | null

With add_to_agent='unless_removed': synced skills a person removed from this agent, which stay off it.

agent_not_found
string | null

With agent_name: set when there is no such agent and none could be made, because the name breaks POST /agents' rules (skills still synced).

agent_problem
string | null

With agent_not_found: why no agent was made.