Build your own legal AI skills and make them available to your organization’s agents. Custom skills are stored with vector embeddings and automatically appear in unified search alongside the 870+ curated skills.
Requires authentication. All custom skills endpoints require a Case.dev API key with skills permission scope.
How It Works
Custom skills live in your organization’s namespace. When your agents search for skills via /skills/resolve, results from your custom skills are merged with curated skills in a single ranked list. If a custom skill has the same slug as a curated skill, the custom skill takes priority for your organization.
Each custom skill includes:
Content in markdown, up to 64KB
Vector embedding (generated automatically) for semantic search
Tags for categorization and search boosting
Metadata for arbitrary key-value data
Version tracking with automatic increment on updates
Soft-delete so deleted skills can be recreated
Create a Skill
TypeScript
Python
C#
Java
PHP
cURL
Go
import Casedev from 'casedev' ;
const client = new Casedev ({ apiKey: process.env. CASEDEV_API_KEY });
const skill = await client.skills. create ({
name: 'Deposition Prep Checklist' ,
summary: 'Comprehensive checklist for deposition preparation in federal litigation.' ,
content: '# Deposition Prep Checklist \n\n ## Pre-Deposition \n - Review all relevant documents \n - Prepare witness outline' ,
tags: [ 'litigation' , 'deposition' , 'checklist' ],
metadata: { author: 'Jane Smith' , practice_area: 'litigation' },
});
console. log (skill.slug); // "deposition-prep-checklist"
Request body:
Field Type Required Description namestring Yes Skill name (max 256 chars) contentstring Yes Full skill content in markdown (max 64KB) slugstring No URL-safe identifier. Auto-generated from name if omitted summarystring No Brief description (max 1000 chars) tagsstring[] No Tags for categorization and search boosting metadataobject No Arbitrary key-value metadata
Response (201):
{
"slug" : "deposition-prep-checklist" ,
"name" : "Deposition Prep Checklist" ,
"summary" : "Comprehensive checklist for deposition preparation." ,
"content" : "# Deposition Prep Checklist \n\n ..." ,
"tags" : [ "litigation" , "deposition" , "checklist" ],
"metadata" : { "author" : "Jane Smith" , "practice_area" : "litigation" },
"version" : 1 ,
"created_at" : "2026-03-16T20:09:59.333Z"
}
Slugs are unique per organization. Reserved slugs (resolve, custom) cannot be used. If you omit slug, one is auto-generated from the skill name.
Read a Skill
Retrieve a skill by slug. For authenticated users, custom skills are checked first, then curated skills.
TypeScript
Python
C#
Java
PHP
cURL
Go
const skill = await client.skills. read ( 'deposition-prep-checklist' );
console. log (skill.source); // "custom" or "curated"
The response includes a source field indicating whether the skill is "custom" (your organization’s) or "curated" (from the open-source library).
Search Skills
Use /skills/resolve to search across both curated and custom skills. Results are ranked by relevance using semantic search, BM25 text matching, and tag boosting.
TypeScript
Python
C#
Java
PHP
cURL
Go
const results = await client.skills. resolve ({
q: 'deposition preparation' ,
limit: 5 ,
});
for ( const skill of results.results) {
console. log (skill.source + ': ' + skill.name + ' (' + skill.score + ')' );
}
Each result includes:
Field Description slugSkill identifier nameSkill name summaryBrief description tagsPractice area tags scoreRelevance score (0-1) source"curated" or "custom"
Custom skills with the same slug as a curated skill take priority in your organization’s results. This lets you override curated skills with org-specific versions.
List Custom Skills
List all custom skills in your organization, with optional filtering.
TypeScript
Python
C#
Java
PHP
cURL
Go
// List all
const list = await client.skills.custom. list ();
// Filter by tag
const filtered = await client.skills.custom. list ({ tag: 'litigation' });
// Paginate
const page2 = await client.skills.custom. list ({
limit: 10 ,
cursor: list.next_cursor,
});
Query parameters:
Parameter Type Description limitinteger Results per page (1-100, default 50) cursorstring Cursor from previous response for pagination tagstring Filter by tag
Response:
{
"skills" : [
{
"slug" : "deposition-prep-checklist" ,
"name" : "Deposition Prep Checklist" ,
"summary" : "..." ,
"tags" : [ "litigation" , "deposition" ],
"metadata" : {},
"version" : 1 ,
"created_at" : "2026-03-16T20:09:59.333Z" ,
"updated_at" : "2026-03-16T20:09:59.333Z"
}
],
"next_cursor" : "csk_abc123" ,
"has_more" : true
}
Update a Skill
Update one or more fields. The version is automatically incremented. If you change content-related fields (name, summary, or content), the embedding is regenerated.
TypeScript
Python
C#
Java
PHP
cURL
Go
const updated = await client.skills. update ( 'deposition-prep-checklist' , {
name: 'Updated Deposition Prep Checklist' ,
tags: [ 'litigation' , 'deposition' , 'checklist' , 'federal' ],
content: '# Updated content...' ,
});
console. log (updated.version); // 2
You can also rename a skill’s slug:
curl -X PUT https://api.case.dev/skills/deposition-prep-checklist \
-H "Authorization: Bearer $CASE_API_KEY " \
-H "Content-Type: application/json" \
-d '{ "slug": "depo-prep-v2" }'
After renaming, the old slug returns 404 and the new slug is active.
Delete a Skill
Soft-deletes a skill. It will no longer appear in search results or be accessible by slug.
TypeScript
Python
C#
Java
PHP
cURL
Go
await client.skills. delete ( 'deposition-prep-checklist' );
Response (200):
{
"slug" : "deposition-prep-checklist" ,
"deleted" : true
}
Deletion frees the slug. You can create a new skill with the same slug after deleting.
Permissions
Custom skills require the skills permission scope on your API key.
Endpoint Permission GET /skills/resolveskills (read)GET /skills/:slugskills (read)GET /skills/customskills (read)POST /skillsskills (write)PUT /skills/:slugskills (write)DELETE /skills/:slugskills (write)
Configure permissions when creating API keys in the Console .
Limits
Limit Value Content size 64KB per skill Name length 256 characters Summary length 1,000 characters Tag length 100 characters per tag Slug length 128 characters Slugs per org Unlimited
What’s Next?