curl --request POST \
--url https://api.example.com/api/skills \
--header 'Content-Type: application/json' \
--header 'X-Session-API-Key: <api-key>' \
--data '
{
"load_public": true,
"load_user": true,
"load_project": true,
"load_org": true,
"marketplace_path": "marketplaces/default.json",
"project_dir": "<string>",
"org_config": {
"repository": "<string>",
"provider": "<string>",
"org_repo_url": "<string>",
"org_name": "<string>"
},
"sandbox_config": {
"exposed_urls": [
{
"name": "<string>",
"url": "<string>",
"port": 123
}
]
}
}
'import requests
url = "https://api.example.com/api/skills"
payload = {
"load_public": True,
"load_user": True,
"load_project": True,
"load_org": True,
"marketplace_path": "marketplaces/default.json",
"project_dir": "<string>",
"org_config": {
"repository": "<string>",
"provider": "<string>",
"org_repo_url": "<string>",
"org_name": "<string>"
},
"sandbox_config": { "exposed_urls": [
{
"name": "<string>",
"url": "<string>",
"port": 123
}
] }
}
headers = {
"X-Session-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Session-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
load_public: true,
load_user: true,
load_project: true,
load_org: true,
marketplace_path: 'marketplaces/default.json',
project_dir: '<string>',
org_config: {
repository: '<string>',
provider: '<string>',
org_repo_url: '<string>',
org_name: '<string>'
},
sandbox_config: {exposed_urls: [{name: '<string>', url: '<string>', port: 123}]}
})
};
fetch('https://api.example.com/api/skills', 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.example.com/api/skills",
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([
'load_public' => true,
'load_user' => true,
'load_project' => true,
'load_org' => true,
'marketplace_path' => 'marketplaces/default.json',
'project_dir' => '<string>',
'org_config' => [
'repository' => '<string>',
'provider' => '<string>',
'org_repo_url' => '<string>',
'org_name' => '<string>'
],
'sandbox_config' => [
'exposed_urls' => [
[
'name' => '<string>',
'url' => '<string>',
'port' => 123
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Session-API-Key: <api-key>"
],
]);
$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.example.com/api/skills"
payload := strings.NewReader("{\n \"load_public\": true,\n \"load_user\": true,\n \"load_project\": true,\n \"load_org\": true,\n \"marketplace_path\": \"marketplaces/default.json\",\n \"project_dir\": \"<string>\",\n \"org_config\": {\n \"repository\": \"<string>\",\n \"provider\": \"<string>\",\n \"org_repo_url\": \"<string>\",\n \"org_name\": \"<string>\"\n },\n \"sandbox_config\": {\n \"exposed_urls\": [\n {\n \"name\": \"<string>\",\n \"url\": \"<string>\",\n \"port\": 123\n }\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Session-API-Key", "<api-key>")
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.example.com/api/skills")
.header("X-Session-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"load_public\": true,\n \"load_user\": true,\n \"load_project\": true,\n \"load_org\": true,\n \"marketplace_path\": \"marketplaces/default.json\",\n \"project_dir\": \"<string>\",\n \"org_config\": {\n \"repository\": \"<string>\",\n \"provider\": \"<string>\",\n \"org_repo_url\": \"<string>\",\n \"org_name\": \"<string>\"\n },\n \"sandbox_config\": {\n \"exposed_urls\": [\n {\n \"name\": \"<string>\",\n \"url\": \"<string>\",\n \"port\": 123\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/skills")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Session-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"load_public\": true,\n \"load_user\": true,\n \"load_project\": true,\n \"load_org\": true,\n \"marketplace_path\": \"marketplaces/default.json\",\n \"project_dir\": \"<string>\",\n \"org_config\": {\n \"repository\": \"<string>\",\n \"provider\": \"<string>\",\n \"org_repo_url\": \"<string>\",\n \"org_name\": \"<string>\"\n },\n \"sandbox_config\": {\n \"exposed_urls\": [\n {\n \"name\": \"<string>\",\n \"url\": \"<string>\",\n \"port\": 123\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"skills": [
{
"name": "<string>",
"type": "repo",
"content": "<string>",
"triggers": [
"<string>"
],
"source": "<string>",
"description": "<string>",
"is_agentskills_format": false
}
],
"sources": {}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Get Skills
Load and merge skills from all configured sources.
Skills are loaded from multiple sources and merged with the following precedence (later overrides earlier for duplicate names):
- Sandbox skills (lowest) - Exposed URLs from sandbox
- Public skills - From GitHub OpenHands/extensions repository
- User skills - From ~/.openhands/skills/
- Organization skills - From /.openhands or equivalent
- Project skills (highest) - From /.openhands/skills/
Args: request: SkillsRequest containing configuration for which sources to load.
Returns: SkillsResponse containing merged skills and source counts.
curl --request POST \
--url https://api.example.com/api/skills \
--header 'Content-Type: application/json' \
--header 'X-Session-API-Key: <api-key>' \
--data '
{
"load_public": true,
"load_user": true,
"load_project": true,
"load_org": true,
"marketplace_path": "marketplaces/default.json",
"project_dir": "<string>",
"org_config": {
"repository": "<string>",
"provider": "<string>",
"org_repo_url": "<string>",
"org_name": "<string>"
},
"sandbox_config": {
"exposed_urls": [
{
"name": "<string>",
"url": "<string>",
"port": 123
}
]
}
}
'import requests
url = "https://api.example.com/api/skills"
payload = {
"load_public": True,
"load_user": True,
"load_project": True,
"load_org": True,
"marketplace_path": "marketplaces/default.json",
"project_dir": "<string>",
"org_config": {
"repository": "<string>",
"provider": "<string>",
"org_repo_url": "<string>",
"org_name": "<string>"
},
"sandbox_config": { "exposed_urls": [
{
"name": "<string>",
"url": "<string>",
"port": 123
}
] }
}
headers = {
"X-Session-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Session-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
load_public: true,
load_user: true,
load_project: true,
load_org: true,
marketplace_path: 'marketplaces/default.json',
project_dir: '<string>',
org_config: {
repository: '<string>',
provider: '<string>',
org_repo_url: '<string>',
org_name: '<string>'
},
sandbox_config: {exposed_urls: [{name: '<string>', url: '<string>', port: 123}]}
})
};
fetch('https://api.example.com/api/skills', 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.example.com/api/skills",
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([
'load_public' => true,
'load_user' => true,
'load_project' => true,
'load_org' => true,
'marketplace_path' => 'marketplaces/default.json',
'project_dir' => '<string>',
'org_config' => [
'repository' => '<string>',
'provider' => '<string>',
'org_repo_url' => '<string>',
'org_name' => '<string>'
],
'sandbox_config' => [
'exposed_urls' => [
[
'name' => '<string>',
'url' => '<string>',
'port' => 123
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Session-API-Key: <api-key>"
],
]);
$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.example.com/api/skills"
payload := strings.NewReader("{\n \"load_public\": true,\n \"load_user\": true,\n \"load_project\": true,\n \"load_org\": true,\n \"marketplace_path\": \"marketplaces/default.json\",\n \"project_dir\": \"<string>\",\n \"org_config\": {\n \"repository\": \"<string>\",\n \"provider\": \"<string>\",\n \"org_repo_url\": \"<string>\",\n \"org_name\": \"<string>\"\n },\n \"sandbox_config\": {\n \"exposed_urls\": [\n {\n \"name\": \"<string>\",\n \"url\": \"<string>\",\n \"port\": 123\n }\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Session-API-Key", "<api-key>")
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.example.com/api/skills")
.header("X-Session-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"load_public\": true,\n \"load_user\": true,\n \"load_project\": true,\n \"load_org\": true,\n \"marketplace_path\": \"marketplaces/default.json\",\n \"project_dir\": \"<string>\",\n \"org_config\": {\n \"repository\": \"<string>\",\n \"provider\": \"<string>\",\n \"org_repo_url\": \"<string>\",\n \"org_name\": \"<string>\"\n },\n \"sandbox_config\": {\n \"exposed_urls\": [\n {\n \"name\": \"<string>\",\n \"url\": \"<string>\",\n \"port\": 123\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/skills")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Session-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"load_public\": true,\n \"load_user\": true,\n \"load_project\": true,\n \"load_org\": true,\n \"marketplace_path\": \"marketplaces/default.json\",\n \"project_dir\": \"<string>\",\n \"org_config\": {\n \"repository\": \"<string>\",\n \"provider\": \"<string>\",\n \"org_repo_url\": \"<string>\",\n \"org_name\": \"<string>\"\n },\n \"sandbox_config\": {\n \"exposed_urls\": [\n {\n \"name\": \"<string>\",\n \"url\": \"<string>\",\n \"port\": 123\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"skills": [
{
"name": "<string>",
"type": "repo",
"content": "<string>",
"triggers": [
"<string>"
],
"source": "<string>",
"description": "<string>",
"is_agentskills_format": false
}
],
"sources": {}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
Body
Request body for loading skills.
Load public skills from OpenHands/extensions repo
Load user skills from ~/.openhands/skills/
Load project skills from workspace
Load organization-level skills
Relative marketplace JSON path for public skills. Set to null to load all public skills.
Workspace directory path for project skills
Organization skills configuration
Show child attributes
Show child attributes
Sandbox skills configuration
Show child attributes
Show child attributes
Was this page helpful?

