---
title: "Recommend Role Skills"
method: POST
path: "/api/job-roles/{role_id}/recommend-skills"
tags: ["Job Roles"]
---

# Recommend Role Skills

`POST /api/job-roles/{role_id}/recommend-skills`

## Request

- Base URL: `https://api.thebetterhire.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.thebetterhire.ai/api/job-roles/{role_id}/recommend-skills`
- Auth: HTTP bearer

Layer-2 recommender: suggest which specialist skill rounds this role's JD
demands (weight 1-3 + a JD-grounded rationale). A PROPOSAL the recruiter
approves/tunes — not a decision. Behavioral is always-on and never listed.

RUNNABLE-ness is NOT filtered here. The recommender matches against the full
skill LIBRARY (specialists/library.py), which deliberately carries signatures
for skills whose assessment module doesn't exist yet — so this route can
return e.g. analytical_data while nothing can actually run it.

Three guards downstream keep that from reaching a candidate, and they are
where the filtering genuinely lives:
  - GET /api/interviews/available-skills returns only `runnable` entries, so
    the schedule form and the assessment-plan editor never offer the rest
  - the plan editor filters suggestions against that same list again
  - the brain's orchestrator raises "Unknown skill: <id>" if a session is
    somehow started for a skill with no module

Do not "fix" this by filtering here: an unrunnable suggestion is the signal
that a customer's JD wants a skill we haven't built, which is exactly the
input for deciding what to build next.

## Path parameters

- `role_id` string, uuid, required

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/thebetterhire/apis/interanalysis-b2b-api.md) · [All operations](https://skmtc.dev/thebetterhire/apis/interanalysis-b2b-api/llms.txt) · [OpenAPI document](https://skmtc.dev/thebetterhire/apis/interanalysis-b2b-api/revisions/c8ad03e900ea?raw)
