{"openapi":"3.1.0","info":{"title":"icrack.ai Recruiter API","version":"1.0.0","description":"Push applicants in, rank and approve them, send AI interview invites, and read results — the same engine the recruiter dashboard uses. Authenticate with a client API key (Settings → Integrations)."},"servers":[{"url":"https://icrack.ai/api/v1"}],"security":[{"bearerAuth":[]}],"paths":{"/campaigns":{"get":{"summary":"List campaigns","responses":{"200":{"description":"OK"},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create a campaign","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignInput"}}}},"responses":{"201":{"description":"Created"},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/campaigns/{id}":{"get":{"summary":"Campaign detail with funnel counts","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/campaigns/{id}/candidates":{"post":{"summary":"Push applicants (idempotent on external_id / email)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"description":"Up to 100 per request. Each candidate needs external_id, consent:true, and one of resume_url | resume_text | resume_base64 (+resume_filename). A resume-less row with an email is treated as a roster entry and goes straight to the approval queue.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidatesInput"}}}},"responses":{"200":{"description":"All duplicates"},"201":{"description":"At least one created"},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"summary":"Ranked results and interview outcomes","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"funnel","in":"query","schema":{"enum":["pending","ready","review","low","incomplete"]}},{"name":"pipeline_stage","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK, with next_cursor"}}}},"/campaigns/{id}/rank":{"post":{"summary":"Rank unranked candidates against the JD (1 credit each)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"402":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/campaigns/{id}/approve":{"post":{"summary":"Approve ranked candidates (the approval gate)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"candidate_ids":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"OK"}}}},"/campaigns/{id}/invite":{"post":{"summary":"Invite all approved candidates (10 credits each, reserved)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"402":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/candidates/{id}":{"get":{"summary":"One candidate","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"interview.completed":{"post":{"summary":"An AI interview finished and its report is ready","description":"Also: candidate.ingested, candidate.ranked, candidate.approved, candidate.invited, interview.started, candidate.handoff. Headers: X-Icrack-Event, X-Icrack-Delivery, X-Icrack-Signature (t=<unix>,v1=<hex hmac_sha256(secret, `${t}.${body}`)>). Respond 2xx within 8s; failures retry at 1m, 5m, 30m, 2h, 12h."}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"ick_live_…"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"CampaignInput":{"type":"object","required":["title","job_title","company_name","job_description"],"properties":{"title":{"type":"string"},"job_title":{"type":"string"},"company_name":{"type":"string"},"job_description":{"type":"string"},"ranking_criteria":{"type":"string"},"language":{"type":"string"},"interview_level":{"enum":["beginner","intermediate","advanced"]},"interview_type":{"enum":["technical","behavioral","situational","standard"]},"mode":{"enum":["standard","campus"]},"invite_channels":{"type":"array","items":{"enum":["email","sms","whatsapp"]}},"invite_ttl_days":{"type":"integer"},"credit_budget":{"type":"integer"}}},"CandidatesInput":{"type":"object","required":["candidates"],"properties":{"consent_attested":{"type":"boolean"},"candidates":{"type":"array","items":{"type":"object","required":["external_id"],"properties":{"external_id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"consent":{"type":"boolean"},"resume_url":{"type":"string"},"resume_text":{"type":"string"},"resume_base64":{"type":"string"},"resume_filename":{"type":"string"},"batch_tag":{"type":"string"}}}}}}}}}