> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.athenaintel.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.athenaintel.com/_mcp/server.

# Update a skill's draft

PUT https://api.athenaintel.com/api/v0/assets/{asset_id}/skill-config
Content-Type: application/json

Write a skill's SKILL.md content (name, description, markdown body and the optional frontmatter) to its draft. Only the fields you send change; an omitted field keeps its current value, and a list or text field you send replaces the old one whole. The write goes to the live draft, the same draft the Athena editor shows, under the asset's existing id. Once the asset has been published, runs keep using the published version until you publish the draft with POST /api/v0/assets/\{asset\_id}/publish; one never published runs from its draft. Requires edit access to the asset; an archived asset is refused with 409. Unknown fields are refused with 422. The frontmatter is validated as it will read after the write; a skill that would not be spec-compliant is refused with 422 and nothing is written. A new name also becomes the asset title.

Reference: https://docs.athenaintel.com/api-reference/assets/update-skill-config

## Authentication

- `X-API-KEY` header (required) — API Key authentication via header

## Request

### Path parameters

- `asset_id` (string, required) — ID of the skill to update

### Body (application/json)

This endpoint expects an UpdateSkillConfigRequestIn.

- `allowed_tools` (string, optional, nullable) — Space-separated list of pre-approved tools (experimental); an empty string clears it
- `body_markdown` (string, optional, nullable) — The markdown instructions below the SKILL.md frontmatter. Replaces the whole body.
- `compatibility` (string, optional, nullable) — Environment requirements (max 500 chars); an empty string clears it
- `description` (string, optional, nullable) — What the skill does and when to use it (max 1024 chars)
- `license` (string, optional, nullable) — License name or reference; an empty string clears it
- `metadata` (map from string to string, optional, nullable) — Additional string metadata; replaces the whole map
- `name` (string, optional, nullable) — Skill name slug (lowercase letters, numbers, single hyphens; max 64 chars). Also becomes the asset title.

## Response

### 200

Successful Response

- `asset_id` (string, required) — ID of the updated asset
- `asset_type` (string, required) — Type of the asset: skill or collab_agent
- `published` (boolean, required) — Always false: the write changed the draft only. Publish it with POST /api/v0/assets/\{asset\_id}/publish.
- `title` (string, required) — Title of the asset after the write
- `warnings` (list of string, optional) — Non-fatal notes, such as tool or toolkit IDs the registry does not know

## Errors

### 400 Bad Request Error

The asset is not a skill, or no field was sent

- `map from string to any`

### 403 Forbidden Error

Caller lacks edit access to the asset

- `message` (string, required)

### 404 Not Found Error

Asset not found

- `message` (string, required)

### 409 Conflict Error

The asset is archived (in the trash): restore it first

- `any`

### 422 Unprocessable Entity Error

An unknown field, or the skill would not be spec-compliant

- `detail` (list of ValidationError, optional)

### 503 Service Unavailable Error

The draft could not be written; nothing changed

- `any`

## Types

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)
- `ctx` (ValidationErrorCtx, optional)
- `input` (any, optional)

### ValidationErrorLocItems

- string
- integer

### ValidationErrorCtx

## Examples

**Request**

```json
{
  "body_markdown": "# Ticket triage\n\n1. Read the ticket...",
  "description": "Triage support tickets by urgency and product area."
}
```

**Response**

```json
{
  "asset_id": "asset_9249292-d118-42d3-95b4-00eccfe0754f",
  "asset_type": "skill",
  "published": false,
  "title": "ticket-triage",
  "warnings": []
}
```

**SDK Code**

```python
import requests

url = "https://api.athenaintel.com/api/v0/assets/asset_id/skill-config"

payload = {
    "body_markdown": "# Ticket triage

1. Read the ticket...",
    "description": "Triage support tickets by urgency and product area."
}
headers = {
    "X-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.put(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.athenaintel.com/api/v0/assets/asset_id/skill-config';
const options = {
  method: 'PUT',
  headers: {'X-API-KEY': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"body_markdown":"# Ticket triage\n\n1. Read the ticket...","description":"Triage support tickets by urgency and product area."}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.athenaintel.com/api/v0/assets/asset_id/skill-config"

	payload := strings.NewReader("{\n  \"body_markdown\": \"# Ticket triage\\n\\n1. Read the ticket...\",\n  \"description\": \"Triage support tickets by urgency and product area.\"\n}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("X-API-KEY", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.athenaintel.com/api/v0/assets/asset_id/skill-config")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url)
request["X-API-KEY"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"body_markdown\": \"# Ticket triage\\n\\n1. Read the ticket...\",\n  \"description\": \"Triage support tickets by urgency and product area.\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.put("https://api.athenaintel.com/api/v0/assets/asset_id/skill-config")
  .header("X-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"body_markdown\": \"# Ticket triage\\n\\n1. Read the ticket...\",\n  \"description\": \"Triage support tickets by urgency and product area.\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'https://api.athenaintel.com/api/v0/assets/asset_id/skill-config', [
  'body' => '{
  "body_markdown": "# Ticket triage\\n\\n1. Read the ticket...",
  "description": "Triage support tickets by urgency and product area."
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-API-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.athenaintel.com/api/v0/assets/asset_id/skill-config");
var request = new RestRequest(Method.PUT);
request.AddHeader("X-API-KEY", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"body_markdown\": \"# Ticket triage\\n\\n1. Read the ticket...\",\n  \"description\": \"Triage support tickets by urgency and product area.\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "X-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "body_markdown": "# Ticket triage

1. Read the ticket...",
  "description": "Triage support tickets by urgency and product area."
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.athenaintel.com/api/v0/assets/asset_id/skill-config")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```