Skills API and SDK reference
This feature is in Beta. Account admins can manage access to this feature from the account console Previews page. See Manage account-level previews.
Use these examples to automate skill management. The API represents each skill as a Skill resource named skills/{catalog}.{schema}.{skill}. To author and publish a skill with an agent, see Create and share skills. For privileges and governance, see Govern skills. Skills don't have Terraform or Declarative Automation Bundles resources.
Prerequisites
-
Set up a governed schema for skills.
-
Have the required permissions for your operation.
-
Install and authenticate the client you plan to use. The REST API has no version requirement; each tool and SDK has a minimum version:
- Databricks CLI: v1.20.0 and above
- Python SDK:
databricks-sdk0.142.0 and above - Go SDK:
databricks-sdk-gov0.184.0 and above - Go Modular SDK:
github.com/databricks/sdk-go/aigatewayv0.1.0 and above - Java SDK:
databricks-sdk-java0.157.0 and above - JavaScript SDK:
@databricks/sdk-aigateway0.23.0 and above
SDK snippets assume an authenticated workspace client,
w; Modular SDK snippets assume an authenticated Unity Gateway client,cin Go andclientin JavaScript.
API operations
The Skills REST API provides these operations. Each also requires USE CATALOG and USE SCHEMA on the parent. Follow each link for its fields, permissions, and responses.
Operation | Use case | Required permissions |
|---|---|---|
Create a skill and provision its bundle storage. |
| |
Upload |
| |
Read and validate |
| |
Find skills you can access in a schema. |
| |
Read a skill's metadata and current |
| |
Change the skill's comment. |
| |
Remove a skill and its bundle. |
|
The skill's owner holds all of these on the skill. See Grant access to skills.
Create a skill
Creating a skill takes three steps: create the skill, upload its bundle, then finalize it. Until you finalize a skill, its bundle name and description are empty.
Step 1: Create the skill
Create the skill in a schema. comment is the only field you can set. Databricks derives name, bundle_name, and description.
Replace main.default.my_skill and data-team with your own values.
- REST API
- CLI
- Python SDK
- Go SDK
- Go Modular SDK
- Java SDK
- JS Modular SDK
Send a POST to /api/2.1/unity-catalog/skills, passing parent and skill_id as query parameters:
databricks api post \
"/api/2.1/unity-catalog/skills?parent=schemas/main.default&skill_id=my_skill" \
--json '{"comment": "Team-shared math helper skill"}'
Pass the parent schema and skill name, and supply the comment with --json:
databricks ai-gateway create-skill schemas/main.default my_skill \
--json '{"comment": "Team-shared math helper skill"}'
Create and manage a skill with the Databricks SDK for Python:
from databricks.sdk import WorkspaceClient
from databricks.sdk.service import catalog as c
w = WorkspaceClient()
skill = w.ai_gateway.create_skill(
parent="schemas/main.default",
skill_id="my_skill",
skill=c.Skill(comment="Team-shared math helper skill"),
)
Create and manage a skill with the Databricks SDK for Go:
skill, err := w.AiGateway.CreateSkill(ctx, catalog.CreateSkillRequest{
Parent: "schemas/main.default",
SkillId: "my_skill",
Skill: catalog.Skill{Comment: "Team-shared math helper skill"},
})
Create and manage a skill with the Go Modular SDK. Optional fields are pointers, so the example uses a one-line helper, func ptr[T any](v T) *T { return &v }.
skill, err := c.CreateSkill(ctx, aigateway.CreateSkillRequest{
Parent: ptr("schemas/main.default"),
SkillId: ptr("my_skill"),
Skill: &aigateway.Skill{Comment: ptr("Team-shared math helper skill")},
})
Create and manage a skill with the Databricks SDK for Java:
Skill skill =
w.aiGateway()
.createSkill(
new CreateSkillRequest()
.setParent("schemas/main.default")
.setSkillId("my_skill")
.setSkill(new Skill().setComment("Team-shared math helper skill")));
Create and manage a skill with the JavaScript SDK:
const created = await client.createSkill({
parent: 'schemas/main.default',
skillId: 'my_skill',
skill: { comment: 'Team-shared math helper skill' },
});
Step 2: Upload the bundle
Upload SKILL.md, and any supporting files, to the skill's storage path, /Skills/<catalog>/<schema>/<skill>/, through the Files API. SKILL.md must start with YAML frontmatter that sets name and description. Save this example as SKILL.md:
---
name: my-skill
description: A team-shared skill that helps with basic math.
---
# My Skill
Step-by-step guidance the agent follows when this skill is loaded.
- REST API
- CLI
- Python SDK
- Go SDK
- Go Modular SDK
- Java SDK
- JS Modular SDK
Send a PUT to the Files API. Set DATABRICKS_HOST to your workspace URL, such as https://my-workspace.cloud.databricks.com, and DATABRICKS_TOKEN to a token. This example passes the token to curl on standard input so it doesn't appear in the process list:
curl --request PUT --config - --data-binary @SKILL.md \
--header "Content-Type: application/octet-stream" \
"${DATABRICKS_HOST}/api/2.0/fs/files/Skills/main/default/my_skill/SKILL.md?overwrite=true" \
<<< "header = \"Authorization: Bearer ${DATABRICKS_TOKEN}\""
Create the skill's folder, then copy the file into it:
databricks fs mkdir dbfs:/Skills/main/default/my_skill
databricks fs cp SKILL.md dbfs:/Skills/main/default/my_skill/SKILL.md --overwrite
with open("SKILL.md", "rb") as f:
w.files.upload("/Skills/main/default/my_skill/SKILL.md", f, overwrite=True)
f, err := os.Open("SKILL.md")
if err != nil {
return err
}
defer f.Close()
err = w.Files.Upload(ctx, files.UploadRequest{
FilePath: "/Skills/main/default/my_skill/SKILL.md",
Contents: f,
Overwrite: true,
})
The Go Modular SDK doesn't include the Files API. Upload with the Files SDK for Go instead:
fc, err := files.NewClient(ctx)
if err != nil {
return err
}
f, err := os.Open("SKILL.md")
if err != nil {
return err
}
defer f.Close()
_, err = fc.Upload(ctx, "/Skills/main/default/my_skill/SKILL.md", f, files.WithOverwrite(true))
try (InputStream contents = Files.newInputStream(Paths.get("SKILL.md"))) {
w.files()
.upload(
new UploadRequest()
.setFilePath("/Skills/main/default/my_skill/SKILL.md")
.setOverwrite(true)
.setContents(contents));
}
The JavaScript Modular SDK doesn't include the Files API, so this example calls the REST endpoint directly. It reads the workspace URL, such as https://my-workspace.cloud.databricks.com, and a token from the DATABRICKS_HOST and DATABRICKS_TOKEN environment variables:
import { readFile } from 'node:fs/promises';
const response = await fetch(
`${process.env.DATABRICKS_HOST}/api/2.0/fs/files/Skills/main/default/my_skill/SKILL.md?overwrite=true`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/octet-stream',
Authorization: `Bearer ${process.env.DATABRICKS_TOKEN}`,
},
body: await readFile('SKILL.md'),
},
);
if (!response.ok) {
throw new Error(`Upload failed: ${response.status} ${response.statusText}`);
}
Step 3: Finalize the skill
Finalizing reads and validates SKILL.md, then sets the skill's bundle_name and description from its frontmatter. If you change the bundle later, finalize again.
- REST API
- CLI
- Python SDK
- Go SDK
- Go Modular SDK
- Java SDK
- JS Modular SDK
databricks api post "/api/2.1/unity-catalog/skills/main.default.my_skill/finalize" --json '{}'
databricks ai-gateway finalize-skill skills/main.default.my_skill
finalized = w.ai_gateway.finalize_skill(name="skills/main.default.my_skill")
print(finalized.bundle_name, finalized.description)
finalized, err := w.AiGateway.FinalizeSkill(ctx, catalog.FinalizeSkillRequest{
Name: "skills/main.default.my_skill",
})
finalized, err := c.FinalizeSkill(ctx, aigateway.FinalizeSkillRequest{
Name: ptr("skills/main.default.my_skill"),
})
Skill finalized =
w.aiGateway().finalizeSkill(new FinalizeSkillRequest().setName("skills/main.default.my_skill"));
const finalized = await client.finalizeSkill({ name: 'skills/main.default.my_skill' });
Find a skill
List the skills you can access in a schema, then get a skill's metadata by its resource name.
- REST API
- CLI
- Python SDK
databricks api get "/api/2.1/unity-catalog/skills?parent=schemas/main.default"
databricks api get "/api/2.1/unity-catalog/skills/main.default.my_skill"
When the list response includes next_page_token, pass it as page_token in the next request. Continue until next_page_token is absent or empty.
databricks ai-gateway list-skills schemas/main.default
databricks ai-gateway get-skill skills/main.default.my_skill
for skill in w.ai_gateway.list_skills(parent="schemas/main.default"):
print(skill.name)
skill = w.ai_gateway.get_skill(name="skills/main.default.my_skill")
The CLI and Python iterator handle pagination for you.
Grant access
These examples grant READ VOLUME on the skill, which lets the principal read the skill and download its bundle. For the other skill privileges, see Grant access to skills.
- REST API
- CLI
- Python SDK
- Go SDK
- Java SDK
databricks api patch \
"/api/2.1/unity-catalog/permissions/skill/main.default.my_skill" \
--json '{
"changes": [
{ "principal": "data-team", "add": ["READ_VOLUME"] }
]
}'
Grant READ VOLUME with the Databricks CLI:
databricks grants update skill main.default.my_skill \
--json '{"changes": [{"principal": "data-team", "add": ["READ_VOLUME"]}]}'
Grant READ VOLUME with the Databricks SDK for Python:
from databricks.sdk.service import catalog as c
w.grants.update(
securable_type="skill",
full_name="main.default.my_skill",
changes=[c.PermissionsChange(principal="data-team", add=[c.Privilege.READ_VOLUME])],
)
Grant READ VOLUME with the Databricks SDK for Go:
_, err := w.Grants.Update(ctx, catalog.UpdatePermissions{
SecurableType: "skill",
FullName: "main.default.my_skill",
Changes: []catalog.PermissionsChange{{
Principal: "data-team",
Add: []catalog.Privilege{catalog.PrivilegeReadVolume},
}},
})
Grant READ VOLUME with the Databricks SDK for Java:
w.grants()
.update(
new UpdatePermissions()
.setSecurableType("skill")
.setFullName("main.default.my_skill")
.setChanges(
Arrays.asList(
new PermissionsChange()
.setPrincipal("data-team")
.setAdd(Arrays.asList(Privilege.READ_VOLUME)))));
Update a skill
These examples update the skill's comment, the only field you can change. The skill's name can't be changed. To change a skill's contents, upload the new bundle and finalize the skill again.
For a conditional update, first get the skill and pass its etag with the update. The update succeeds only if the skill hasn't changed since that read. URL-encode the etag when adding it to a REST query string.
- REST API
- CLI
- Python SDK
- Go SDK
- Go Modular SDK
- Java SDK
- JS Modular SDK
databricks api patch \
"/api/2.1/unity-catalog/skills/main.default.my_skill?update_mask=comment" \
--json '{"comment": "Updated: team-shared math helper"}'
databricks ai-gateway update-skill skills/main.default.my_skill comment \
--json '{"comment": "Updated: team-shared math helper"}'
from databricks.sdk.service import catalog as c
from databricks.sdk.common.types.fieldmask import FieldMask
updated = w.ai_gateway.update_skill(
name="skills/main.default.my_skill",
update_mask=FieldMask(["comment"]),
skill=c.Skill(comment="Updated: team-shared math helper"),
)
updated, err := w.AiGateway.UpdateSkill(ctx, catalog.UpdateSkillRequest{
Name: "skills/main.default.my_skill",
UpdateMask: *fieldmask.New([]string{"comment"}),
Skill: catalog.Skill{Comment: "Updated: team-shared math helper"},
})
mask, err := types.NewFieldMask[aigateway.Skill]("comment")
updated, err := c.UpdateSkill(ctx, aigateway.UpdateSkillRequest{
Skill: &aigateway.Skill{
Name: ptr("skills/main.default.my_skill"),
Comment: ptr("Updated: team-shared math helper"),
},
UpdateMask: mask,
})
Skill updated =
w.aiGateway()
.updateSkill(
new UpdateSkillRequest()
.setName("skills/main.default.my_skill")
.setUpdateMask(FieldMask.newBuilder().addPaths("comment").build())
.setSkill(new Skill().setComment("Updated: team-shared math helper")));
import { skillFieldMask } from '@databricks/sdk-aigateway/v1';
const updated = await client.updateSkill({
skill: {
name: 'skills/main.default.my_skill',
comment: 'Updated: team-shared math helper',
},
updateMask: skillFieldMask('comment'),
});
Delete a skill
Deleting a skill removes it and its bundle. Agents can no longer load it.
You can also pass the skill's current etag to make deletion conditional on it not having changed since the last read. URL-encode the etag in REST query strings.
- REST API
- CLI
- Python SDK
- Go SDK
- Go Modular SDK
- Java SDK
- JS Modular SDK
databricks api delete "/api/2.1/unity-catalog/skills/main.default.my_skill"
databricks ai-gateway delete-skill skills/main.default.my_skill
w.ai_gateway.delete_skill(name="skills/main.default.my_skill")
err := w.AiGateway.DeleteSkill(ctx, catalog.DeleteSkillRequest{
Name: "skills/main.default.my_skill",
})
err := c.DeleteSkill(ctx, aigateway.DeleteSkillRequest{
Name: ptr("skills/main.default.my_skill"),
})
w.aiGateway().deleteSkill(new DeleteSkillRequest().setName("skills/main.default.my_skill"));
await client.deleteSkill({ name: 'skills/main.default.my_skill' });