---
name: rinkats-scheduling
description: >-
  Schedule and manage interviews in rinkats: meetings against pipeline
  cards, interviewer directory and availability, scorecards, and reschedule
  or cancel requests from candidates or interviewers. Use when asked to book,
  move, cancel or report on interviews and meetings.
license: Proprietary — for use with the rinkats API by authorized keys.
version: 1.9.0
metadata:
  product: rinkats
  updated: "2026-10-17"
  url: https://www.rinkats.com/skills/rinkats-scheduling/SKILL.md
  workflow: scheduling
  transports: REST, MCP, A2A
---

# rinkats — Scheduling & Interviews

## Connect

Each side has its own endpoints (2026-10-17). Booking is the desk's: REST
`/api/v1/recruiter/…`, MCP `/api/mcp/recruiter`, A2A `/api/a2a/recruiter`, a
recruiter-tier `rk_p_…` key. The interviewer's tools (their interviews,
scorecards, comments, availability, change requests) are at
`/api/v1/interviewer/…`, MCP `/api/mcp/interviewer`, with an interviewer-scoped
key. A candidate's own interviews are at `/api/v1/candidate/…`, MCP
`/api/mcp/candidate`, with a candidate key (`rkc_p_…`, from their rinkats
profile page) or OAuth with the `candidate` scope — a candidate belongs to no
organization, so their `list_my_interviews` and `request_interview_change`
answer across every role they applied to.

## Organizations (2026-09-14)

rinkats is multi-tenant and data NEVER crosses organizations. Every
credential is bound to ONE organization: an API key takes its org when it is
minted; an OAuth or session credential acts in the org that was active when
it was issued. A user in several organizations mints one key per
organization — nothing switches tenants mid-request.

- `list_my_organizations` (REST `GET /me/organizations`) returns every
  organization the account belongs to, the roles held in each, and which one
  this credential is acting in. Call it first when the account may span
  organizations, and ASK the user which to work in — never guess.
- `X-Organization` (org id or slug) is an optional CROSS-CHECK, not a
  selector: a mismatch is a `404`.
- The interviewer directory, availability and meetings are all per-org. An
  interviewer who works with two agencies is a separate record in each, so
  never carry an id, slot or scorecard from one organization into another.

## Core operations

| Task | MCP tool | REST |
| --- | --- | --- |
| List meetings | `list_meetings`, `get_meeting` | `GET /recruiter/meetings` |
| Cards a candidate sits on | `list_candidate_cards` | `GET /recruiter/candidates/{id}/cards` |
| Book a meeting on a card — ONE call does everything (2026-10-15): the meeting, the interview row for a job card, `moveTo: "client_interview"` moves the card, `sendInvite: true` mails the .ics invite to the candidate, every attendee and the organiser with the NOTES as its plain-text body and `attachmentIds` (files from `POST /recruiter/mail/attachments`) on every copy. THE ROUND (2026-10-14): pass `interviewType`, `roundNo`, `roundName`. | `schedule_meeting` | `POST /recruiter/meetings` |
| A file for a composed mail (virus-scanned before it is stored; malicious → refused, nothing kept) | — | `POST /recruiter/mail/attachments` |
| Move / edit a meeting | `update_meeting` | `PATCH /recruiter/meetings/{id}` |
| Cancel | `cancel_meeting` | `DELETE /recruiter/meetings/{id}` |
| Re-send the invite | `resend_meeting_invite` | `POST /recruiter/meetings/{id}/resend` |
| Interviewer directory | `list_interviewers`, `search_interviewers_directory` | `GET /recruiter/interviewers…` |
| My availability (interviewer) | `get_my_availability`, `set_my_availability` | `/interviewer/availability` |
| The organisation's interviews (desk) | `list_interviews` (recruiter endpoint) | `GET /recruiter/interviews` |
| Interviews I conduct (interviewer) | `list_my_interviews` (interviewer endpoint) | `GET /interviewer/interviews` |
| Ask for a change (interviewer) | `request_interview_change` (interviewer endpoint) | `POST /interviewer/interviews/{id}/change-request` |
| My interviews (candidate) | `list_my_interviews` (candidate endpoint) | `GET /candidate/interviews` |
| Ask for a change (candidate) | `request_interview_change` (candidate endpoint) | `POST /candidate/interviews/{id}/change-request` |
| Scorecard after the round | `submit_scorecard` | `POST /interviewer/interviews/{id}/scorecard` |

**What an invite tells everyone on it (2026-10-03).** Book the meeting ON the job card
(`submittalId`) whenever the interview is for a role: with `sendInvite: true`, every copy
of the invite — the candidate's, the interviewer's and the organiser's — and the calendar
event describe the role (location and work mode, experience, skills, the requirement's
description). The organiser and the interviewer read the client's name; the candidate's
copy names the client only when the requirement publishes its company, and says
"<industry> company" otherwise. The salary band and fee are never included. A meeting with
no card has no role to describe, and a cancellation never carries it. The same applies to
`update_meeting` and `resend_meeting_invite`. (Until 2026-10-02 only the interviewer's
copy carried the role.)

**Email limits.** If the organisation's plan caps emails and an invite's mails (two, or
three with an interviewer) do not fit in what is left this month, the meeting is still
created through the API but its invite is not sent — the email log shows each mail as
skipped with the reason. Check the log before telling anyone an invite went out.

## How reschedule requests work (important)

Either the CANDIDATE or the INTERVIEWER (or both) can request a reschedule or
cancel, each with a message and optionally their own proposed time. The card
then carries a "reschedule" flag — and the matching calendar event is
highlighted — until a recruiter resolves it: accept either side's proposed
time, book a custom slot, cancel the interview, or dismiss the request
(keeping the current slot). EVERY resolution, dismiss included, clears ALL
pending requests on that interview, and a reschedule/cancel also moves or
cancels the paired calendar meeting. When reporting a request, name who asked
and quote their message; both requesters may exist at once with different
proposed times.

## Hard rules

1. Meetings are booked against a **submittal** (card), not a bare candidate —
   find the card first (`list_candidate_cards`).
2. Times are ISO with timezone; the org operates in IST (Asia/Kolkata) —
   present times in IST unless asked otherwise.
3. Cancelling an interview is destructive and emails people — do it only on
   an explicit instruction, and pass the notify flag the user chose.
4. Scorecards are evidence-linked and human-owned: draft text may be
   suggested, but submit only what the interviewer approved.
5. Candidates see candidate-visible statuses only — never internal stage
   names, budgets, or interviewer-only comments.

## The invite is the schedule (2026-10-15)

There is no separate mail. A schedule sends ONE calendar invite — the `.ics` with the notes as its DESCRIPTION and
the same notes in the mail's body — to the candidate, every attendee and the organiser. Write the notes as **plain
text**: calendar clients show no formatting, links as bare URLs, no images. Put the agenda, the place and anything
the candidate should bring in the notes; put documents in `attachmentIds` (upload each through `POST
/mail/attachments` first — virus-scanned before it is stored). For a job card the invite also carries the role
(location, experience, skills, the description — never the salary band or fee) and the interview row is written, so
the candidate's and the interviewer's Interviews pages show it. `moveTo: "client_interview"` moves the card as part
of the same call. The old two-step (`compose_interview_invite`, then `schedule_meeting` with `mail`) is gone; a
`mail` field is rejected as unknown. `notifyCandidate` on a move is still accepted and ignored.

## Version & updates

This is **v1.9.0** of this skill (updated 2026-10-17: one endpoint per side — booking on `/api/mcp/recruiter`, the interviewer's tools on `/api/mcp/interviewer`, the candidate's on `/api/mcp/candidate`, with REST under `/api/v1/recruiter`, `/api/v1/interviewer` and `/api/v1/candidate`; `list_interviews` is the desk's list; candidate keys `rkc_…`). v1.8.0 (2026-10-17: a candidate belongs to no organization — their interview tools need a candidate credential and answer across every role they applied to). v1.7.0 (2026-10-15: one schedule call, no composed invite — `compose_interview_invite` and `mail` are gone; the notes are the invite's plain text and `attachmentIds` ride on it). v1.6.0 (2026-10-14: the round — `interviewType`, `roundNo`, `roundName`). v1.5.0 (2026-10-12: the composed invite, since withdrawn; `POST /recruiter/mail/attachments`; no candidate mail on a stage change). v1.2.0 (2026-09-14: rinkats is now
multi-tenant — credentials are bound to one organization, the interviewer
directory, availability and meetings are all per-org, `list_my_organizations`
reports where you are acting, and `X-Organization` cross-checks rather than
switches. 1.1.0 (2026-09-08): two-sided reschedule requests). The live copy at the
`url` in the frontmatter metadata is always current with the deployed API. If
you can fetch URLs, check it when starting a long task or whenever a call
fails in a way this skill didn't predict: compare the frontmatter `version`,
and if the remote one is newer, replace your local copy with it (auto-update
is safe — skills are instructions only, never executable code). The catalog
at https://www.rinkats.com/skills/index.json lists every skill's current
version.
