import httpx
resp = httpx.post(
"https://api.decimal.ai/api/v1/registry/skills/sk_pub123/fork",
headers={"Authorization": "Bearer dai_sk_..."},
)
resp.raise_for_status()
print(resp.json())curl --request POST \
--url https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": "installed",
"skill": {
"id": "sk_local123",
"name": "semantic-search",
"forked_from_skill_id": "sk_pub123",
"forked_at_version_id": "skv_pub123_v4"
},
"moved_agents": [
"support-bot"
],
"pinned_agents_kept": [],
"unmoved_agents": []
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Fork a registry skill into your workspace
Forks a public registry skill into your organization. The forked skill is fully owned by your org — edits do not affect the public version.
When the fork keeps the original’s name, agents in your org that had the
original assigned and follow its latest version are assigned the fork, so
your edits reach them; moved_agents names them. Their link to the
original is kept, so deleting the fork puts them back on it. Agents pinned
to a version of the original stay on that version (pinned_agents_kept).
Nothing moves when the fork is renamed (unmoved_reason: copy_renamed);
unmoved_agents then names the agents left on the original.
Pre-checks:
- Skill exists and is public
- User hasn’t already forked this skill
- Name doesn’t conflict with existing skills in the org
import httpx
resp = httpx.post(
"https://api.decimal.ai/api/v1/registry/skills/sk_pub123/fork",
headers={"Authorization": "Bearer dai_sk_..."},
)
resp.raise_for_status()
print(resp.json())curl --request POST \
--url https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.decimal.ai/api/v1/registry/skills/{skill_id}/fork")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": "installed",
"skill": {
"id": "sk_local123",
"name": "semantic-search",
"forked_from_skill_id": "sk_pub123",
"forked_at_version_id": "skv_pub123_v4"
},
"moved_agents": [
"support-bot"
],
"pinned_agents_kept": [],
"unmoved_agents": []
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
Enter your API key (e.g. dai_sk_test_key_001)
Headers
Path Parameters
Query Parameters
Custom name for the fork (optional)
Which agents get the copy: 'restricted' (the default) = only agents you add it to, 'workspace' = every agent. Agents moved onto the copy get it either way. (Until 2026-10-25 a fork from an API key that left it out was offered to every agent.)
^(workspace|restricted)$Cookies
Response
Successful Response