Skills
A Skill is a server-side function that runs against your EDM data and returns structured output. Skills handle common enterprise analysis tasks — access certification, licence waste detection, risk scoring — so you don’t have to build the logic yourself. Custom skills can also be registered and called the same way.
Skills run asynchronously. Every run call returns a Job handle; use sdk.jobs.wait() to retrieve the result.
List Available Skills
import { CpodClient } from '@cpod/sdk'
const sdk = CpodClient.fromEnv()
const skills = await sdk.skills.list()
for (const skill of skills.items) {
console.log(skill.name, skill.description, skill.category)
}Get a Skill
// Get the schema + description for a skill before running it
const skill = await sdk.skills.get('access-review')
console.log(skill.inputSchema) // JSON Schema for allowed inputs
console.log(skill.outputSchema) // JSON Schema for the outputRun a Skill
// Run the built-in access-review skill for an engineering group
const job = await sdk.skills.run('access-review', {
groupId: 'grp-engineering',
lookbackDays: 90,
})
// job.id → "job-01HXYZ..."
// job.status → "queued"
// Wait for the result (blocks until done or timeout)
const result = await sdk.jobs.wait(job.id, { timeoutMs: 60_000 })
if (result.status === 'completed') {
const output = result.output
// output.unusedEntitlements → AccessEntitlement[]
// output.riskySpreads → { personId, entitlementCount }[]
console.log(`Found ${output.unusedEntitlements.length} unused entitlements`)
}
// Run licence optimisation
const licJob = await sdk.skills.run('license-optimisation', {
licenseId: 'lic-abc123',
})
const licResult = await sdk.jobs.wait(licJob.id)
// licResult.output.reclaimableSeats → number
// licResult.output.candidates → Person[]Get Skill Results
If you don’t want to block on jobs.wait(), poll the job directly:
const job = await sdk.jobs.get('job-01HXYZ')
// job.status → "queued" | "running" | "completed" | "failed"
// job.progress → 0–100
if (job.status === 'completed') {
console.log(job.output)
} else if (job.status === 'failed') {
console.error(job.error)
}Skill results are retained for 7 days. After that, jobs.get() returns 404. Store results you need long-term in sdk.storage.db or your own system.