Skip to main content
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

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:
FieldTypeRequiredDescription
namestringYesSkill name (max 256 chars)
contentstringYesFull skill content in markdown (max 64KB)
slugstringNoURL-safe identifier. Auto-generated from name if omitted
summarystringNoBrief description (max 1000 chars)
tagsstring[]NoTags for categorization and search boosting
metadataobjectNoArbitrary 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.
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.
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:
FieldDescription
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.
// 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:
ParameterTypeDescription
limitintegerResults per page (1-100, default 50)
cursorstringCursor from previous response for pagination
tagstringFilter 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.
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
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.
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.
EndpointPermission
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

LimitValue
Content size64KB per skill
Name length256 characters
Summary length1,000 characters
Tag length100 characters per tag
Slug length128 characters
Slugs per orgUnlimited

What’s Next?