curl -X POST https://api.decimal.ai/api/v1/install/resolve \
-H "Authorization: Bearer $DECIMAL_API_KEY" -H "Content-Type: application/json" \
-d '{"items": [{"ref": "acme/refund-policy", "version": "latest"}],
"taken": {}, "channel": "cli", "purpose": "add"}'import requests
url = "https://api.decimal.ai/api/v1/install/resolve"
payload = {
"items": ["<unknown>"],
"taken": {},
"formats": [123],
"channel": "<string>",
"purpose": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
items: ['<unknown>'],
taken: {},
formats: [123],
channel: '<string>',
purpose: '<string>'
})
};
fetch('https://api.decimal.ai/api/v1/install/resolve', 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/install/resolve",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'items' => [
'<unknown>'
],
'taken' => [
],
'formats' => [
123
],
'channel' => '<string>',
'purpose' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.decimal.ai/api/v1/install/resolve"
payload := strings.NewReader("{\n \"items\": [\n \"<unknown>\"\n ],\n \"taken\": {},\n \"formats\": [\n 123\n ],\n \"channel\": \"<string>\",\n \"purpose\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
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/install/resolve")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"items\": [\n \"<unknown>\"\n ],\n \"taken\": {},\n \"formats\": [\n 123\n ],\n \"channel\": \"<string>\",\n \"purpose\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.decimal.ai/api/v1/install/resolve")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"items\": [\n \"<unknown>\"\n ],\n \"taken\": {},\n \"formats\": [\n 123\n ],\n \"channel\": \"<string>\",\n \"purpose\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"items": [
{
"ok": true,
"ref": "<string>",
"error": {
"code": "<string>",
"message": "<string>"
},
"skill_id": "<string>",
"org_id": "<string>",
"registry_name": "<string>",
"url_slug": "<string>",
"install_name": "<string>",
"install_name_base": "<string>",
"install_name_disambiguated": "<string>",
"version_id": "<string>",
"version": 123,
"latest": {
"version_id": "<string>",
"version": 123
},
"render": {
"format": 123,
"hash": "<string>",
"variant": "<string>"
},
"body_sha256": "<string>",
"description_sha256": "<string>",
"invocation": "<string>",
"relationship": "<string>",
"files": [
{
"path": "<string>",
"sha256": "<string>",
"mode": "<string>"
}
],
"unavailable": [
{
"path": "<string>",
"reason": "<string>"
}
],
"policy_notes": [
"<string>"
],
"safety": {
"band": "<string>",
"withheld": true
}
}
]
}Resolve skills to install into a project
Resolve each reference to a skill version, a rendering and an install name.
One result per item, in order: a refused item comes back as
{"ok": false, "error": {"code": ..., "message": ...}} and never fails the others.
Only the request itself is refused as a whole: more than 100 items, or a formats
list with nothing this registry renders (422 format_unsupported, with supported).
A result lists every file of the rendering with its sha256 and mode; fetch the bytes
from GET /install/bundles/{version_id} with the same install_name, render.hash,
render.format and render.variant.
A ref is looked up as a skill id (a UUID), then your organization’s own skills (by
name, then url_slug), then skills it Uses (name, then url_slug), then public skills
(url_slug, then name), and last as an install name. An install name is matched in
either form; the hashed form of a name with no Latin letters or digits at all
(skill-<hex>) is not looked up, so pass such a skill’s id, url_slug or name.
latest is your organization’s latest version of its own skill, and the public
head of anyone else’s. When that head failed its safety scan, the newest version
that passed is chosen and policy_notes says so. safety is the skill’s
SkillSafety band; a withheld skill is refused here unless your organization owns
it or Uses it, and a blocked one is refused to everyone. Resolving is not counted
as an install; fetching the bundle is.
curl -X POST https://api.decimal.ai/api/v1/install/resolve \
-H "Authorization: Bearer $DECIMAL_API_KEY" -H "Content-Type: application/json" \
-d '{"items": [{"ref": "acme/refund-policy", "version": "latest"}],
"taken": {}, "channel": "cli", "purpose": "add"}'import requests
url = "https://api.decimal.ai/api/v1/install/resolve"
payload = {
"items": ["<unknown>"],
"taken": {},
"formats": [123],
"channel": "<string>",
"purpose": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
items: ['<unknown>'],
taken: {},
formats: [123],
channel: '<string>',
purpose: '<string>'
})
};
fetch('https://api.decimal.ai/api/v1/install/resolve', 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/install/resolve",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'items' => [
'<unknown>'
],
'taken' => [
],
'formats' => [
123
],
'channel' => '<string>',
'purpose' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.decimal.ai/api/v1/install/resolve"
payload := strings.NewReader("{\n \"items\": [\n \"<unknown>\"\n ],\n \"taken\": {},\n \"formats\": [\n 123\n ],\n \"channel\": \"<string>\",\n \"purpose\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
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/install/resolve")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"items\": [\n \"<unknown>\"\n ],\n \"taken\": {},\n \"formats\": [\n 123\n ],\n \"channel\": \"<string>\",\n \"purpose\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.decimal.ai/api/v1/install/resolve")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"items\": [\n \"<unknown>\"\n ],\n \"taken\": {},\n \"formats\": [\n 123\n ],\n \"channel\": \"<string>\",\n \"purpose\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"items": [
{
"ok": true,
"ref": "<string>",
"error": {
"code": "<string>",
"message": "<string>"
},
"skill_id": "<string>",
"org_id": "<string>",
"registry_name": "<string>",
"url_slug": "<string>",
"install_name": "<string>",
"install_name_base": "<string>",
"install_name_disambiguated": "<string>",
"version_id": "<string>",
"version": 123,
"latest": {
"version_id": "<string>",
"version": 123
},
"render": {
"format": 123,
"hash": "<string>",
"variant": "<string>"
},
"body_sha256": "<string>",
"description_sha256": "<string>",
"invocation": "<string>",
"relationship": "<string>",
"files": [
{
"path": "<string>",
"sha256": "<string>",
"mode": "<string>"
}
],
"unavailable": [
{
"path": "<string>",
"reason": "<string>"
}
],
"policy_notes": [
"<string>"
],
"safety": {
"band": "<string>",
"withheld": true
}
}
]
}Authorizations
Enter your API key (e.g. dai_sk_test_key_001)
Headers
Cookies
Body
Up to 100 items (20 without an API key), one result each. An item is {"ref": ..., "version": ...} or {"skill_id": ..., "version_id": ...}. ref is a skill id, a registry name or url_slug (your organization's own skills first, then skills it Uses, then public skills) or an install name. version is "latest" (default) or a number; version_id names one exact version.
Each install name (folder) the project already uses, mapped to the skill id it holds, or to null for a folder the skills engine does not manage. A skill already in the map keeps its name; otherwise the registry picks around them. Names chosen for earlier items count as taken for later ones.
Show child attributes
Show child attributes
Up to 8 SKILL.md formats the client reads (default [1]). The highest one this registry renders is used; when it renders none of them, the whole request is refused with format_unsupported.
Who is resolving (cli, sdk, ...).
Why (add, update, ...).
Response
Successful Response
Show child attributes
Show child attributes