# OGHA Grounded Skills Report API Audit an interviewer's assessment against the interview itself. The interview is the source of truth; the interviewer's notes are claims. For each skill the interviewer says the candidate is strong (or weak) at, the service pulls the candidate's own answers from the interview that back it up — and if the interview contradicts the claim, it says so. The client gets a report where each strength and gap is grounded in the candidate's demonstrated work, with every quote proven word-for-word from the interview. Base URL: https://ogha-skills-service.onrender.com ## Endpoints ### GET / Health and warm-up. Free hosts sleep when idle, so call this once first; the first call after a quiet period can take 30-60 seconds. Example: ``` curl https://ogha-skills-service.onrender.com/ ``` Example response: ``` {"service":"OGHA Grounded Skills Report API","status":"ok","llm_enabled":true,"llm_provider":"openai","audio_transcription":true,"endpoints":["GET /","GET /skill.md","POST /report","POST /report/interview","POST /verify"],"authors":"Puja Ivaturi, Mahesh Gottam"} ``` ### POST /report/interview Send a raw interview plus the interviewer's notes; get back the claim-verified report. Provide the audio as an `audio` file upload OR an `audio_url` Google Drive share link (shared "Anyone with the link"). Provide the interviewer's notes (the claims to check) as a `notes` file (txt, pdf, or docx) OR a `notes_text` field. The service transcribes the audio, checks each claim against the candidate's answers, and returns the report plus the transcript. This is `multipart/form-data`. Audio must be under 25MB. Example (Drive audio + typed notes): ``` curl -X POST https://ogha-skills-service.onrender.com/report/interview \ -F "audio_url=https://drive.google.com/file/d/FILE_ID/view?usp=sharing" \ -F "notes_text=Strong on Python and statistics. Weak on communication." \ -F "candidate_id=c-123" -F "job_id=j-9" ``` Example (audio file + notes file): ``` curl -X POST https://ogha-skills-service.onrender.com/report/interview \ -F "audio=@interview.mp3" \ -F "notes=@interviewer_notes.pdf" ``` ### POST /report Already have a transcript? Send it as JSON with the interviewer's notes and get the same claim-verified report, without transcription. Each entry in `skills` reports one skill the interviewer commented on. `interviewer_claim` is what the interviewer said (`strong`/`weak`/`unspecified`). `interview_verdict` is what the candidate's own answers actually show — the ground truth judged only from the interview (`strong` = demonstrated real competence; `weak` = struggled/was wrong; `insufficient_evidence` = the interview doesn't show it). `matches_interviewer` is `true` when the interview agrees with the interviewer, `false` when it disagrees, `null` when the claim was unspecified. `evidence` are the candidate's own words that demonstrate competence; `weakness_evidence` are quotes showing struggle. An `interview_verdict` of `strong`/`weak` is only kept if a verbatim quote backs it, else it becomes `insufficient_evidence`. `summary` rolls this up for the client: `good_at`, `needs_improvement`, `insufficient_evidence`, and `interviewer_disagreements` (skills where the interview and the interviewer disagree). Example (interviewer wrongly rated Python "weak"; the interview proves otherwise): ``` curl -X POST https://ogha-skills-service.onrender.com/report \ -H "Content-Type: application/json" \ -d '{"transcript":"Interviewer: Explain a tuple vs a list. Candidate: A tuple is immutable, whereas a Python list is mutable. Interviewer: How would you test a hypothesis about stock prices? Candidate: I could run a statistical test like a t-test.","interviewer_notes":"Weak at Python. Strong at statistics. Strong at leadership.","candidate_id":"c-123","job_id":"j-9"}' ``` Example response: ``` {"candidate_id":"c-123","job_id":"j-9","mode":"verification","trust_source":"interview transcript","skills":[{"skill":"Python","interviewer_claim":"weak","interview_verdict":"strong","matches_interviewer":false,"evidence":["A tuple is immutable, whereas a Python list is mutable."],"weakness_evidence":[],"explanation":"Candidate correctly explained mutability — contradicts the 'weak' note."},{"skill":"Statistics","interviewer_claim":"strong","interview_verdict":"strong","matches_interviewer":true,"evidence":["I could run a statistical test like a t-test."],"weakness_evidence":[],"explanation":"Named an appropriate test."},{"skill":"Leadership","interviewer_claim":"strong","interview_verdict":"insufficient_evidence","matches_interviewer":false,"evidence":[],"weakness_evidence":[],"explanation":"No leadership evidence in the interview."}],"summary":{"good_at":["Python","Statistics"],"needs_improvement":[],"insufficient_evidence":["Leadership"],"interviewer_disagreements":["Python","Leadership"]},"interviewer_notes":"Weak at Python. Strong at statistics. Strong at leadership.","extraction_method":"llm","grounding":"every quote verified verbatim against the interview transcript","pii_redacted":true,"redactions":{},"report_id":"df://sha256-"} ``` If you omit `interviewer_notes`, the service instead lists the skills the candidate demonstrated in the interview (`"mode":"discovery"`), each with a grounded quote. ### POST /verify Send a transcript and a list of quotes; get back whether each quote appears verbatim. Use this to catch fabricated or paraphrased quotes before you trust them. Pure text-matching, no model. Example: ``` curl -X POST https://ogha-skills-service.onrender.com/verify \ -H "Content-Type: application/json" \ -d '{"transcript":"Candidate: A tuple is immutable.","quotes":["A tuple is immutable.","I have ten years of Kubernetes experience."]}' ``` Example response: ``` {"results":[{"quote":"A tuple is immutable.","grounded":true},{"quote":"I have ten years of Kubernetes experience.","grounded":false}],"grounded_count":1,"total":2,"all_grounded":false} ``` ### GET /skill.md Returns this document as plain text, so an agent can re-read the instructions straight from the running service. ## How the agent should use this 1. Call `GET /` once to wake the service. If it is slow, wait and retry once. 2. To produce a client report, send the interview and the interviewer's notes. From a recording: POST to `/report/interview` with the audio (`audio` file or `audio_url` Drive link) and the notes (`notes` file or `notes_text`). From a transcript: POST to `/report` as JSON with `transcript` and `interviewer_notes`. 3. Read `skills`: for each one, `interview_verdict` is what the candidate actually demonstrated (`strong`/`weak`/`insufficient_evidence`), `interviewer_claim` is what the interviewer said, and `matches_interviewer` flags agreement or disagreement; `evidence` and `weakness_evidence` are the candidate's own words that justify the verdict. Read `summary` for the client-facing roll-up (`good_at`, `needs_improvement`, `insufficient_evidence`, `interviewer_disagreements`). 4. Trust the quotes: the service verified each one appears verbatim, so you can show them to a client as proof. Anything not verbatim was dropped, and a `strong`/`weak` verdict without a backing quote is downgraded to `insufficient_evidence`. 5. To check quotes you got elsewhere against a source text, POST both to `/verify`. Treat any quote with `grounded: false` as fabricated. 6. Output is already scrubbed of personal data, including the echoed transcript. The `report_id` is a content hash, so the same input always yields the same id.