This is a submission for the Xano AI-Powered Backend Challenge: Production-Ready Public API
What I Built
I built Career Signals API, a production-ready public API that analyzes resumes, job descriptions, and candidate profiles to generate structured, explainable career insights.
Where most ATS systems still rely on keyword matching, this API provides:
🔍 Profile Analysis
- Skill breadth & depth scoring
- Five-dimension leadership scoring (people, technical, delivery, cross-functional, mentorship)
- Career risk signals (job-hopping, gaps, stagnation, buzzword density)
- Narrative themes (e.g., “Builder”, “Coach”, “Scaler”)
🎯 Role Fit Analysis
- Weighted role-fit score (0–100)
- Matched vs. missing skills with impact levels
- Seniority and domain alignment
- Red/green flags + actionable resume and interview recommendations
✍ Resume Bullet Generation
- Bullets grounded in actual experience (no hallucinations)
- Tailored to job descriptions
- Seniority-adjusted tone (IC → Manager → Director → VP)
- Focus-tag metadata for UI filtering
- Mismatch warnings when the candidate is underqualified
The API returns clean, consistent JSON responses that can be plugged into resume builders, job-search tools, HR platforms, and ATS systems.
API Documentation
Base URL:
https://x8ki-letl-twmt.n7.xano.io/api:career_signals
Swagger / API Explorer:
https://x8ki-letl-twmt.n7.xano.io/api:career_signals
GitHub Repo:
https://github.com/Tawe/careersignals
Authentication
All endpoints use Bearer tokens:
Authorization: Bearer <API_KEY>
For testing, you may also pass:
{ "test_api_key": "test-key-123" }
Rate Limits
- 60 requests per minute (default)
- Configurable per client via Xano table
-
429returned when limit exceeded
Endpoints
POST /v1/analyze/profile
Analyzes resume/profile text and returns skill scores, leadership signals, risks, and narrative themes.
POST /v1/analyze/role-fit
Compares a profile to a job description and outputs matched/missing skills, red/green flags, and role-fit scoring.
POST /v1/suggest/bullets
Generates non-hallucinated resume bullets grounded in the candidate’s real experience.
Each endpoint includes:
- Schema-validated JSON
- Anti-hallucination safeguards
- Evidence-based scoring
- Consistent response formatting
Demo
Microsite
A lightweight frontend you can try immediately:
https://careersignal.johnmunn.tech/
It supports:
- Pasting a resume
- Pasting a job description
- Calling each API endpoint
- Viewing structured JSON responses
Screenshots
Example API Calls
🔍 Profile Analysis
curl -X POST "https://x8ki-letl-twmt.n7.xano.io/api:career_signals/v1/analyze/profile" \
-H "Authorization: Bearer test-key-123" \
-H "Content-Type: application/json" \
-d '{
"profile_text": "Senior Software Engineer with 10+ years building scalable systems...",
"locale": "en-US",
"options": {"include_leadership_signals": true}
}'
🎯 Role Fit
curl -X POST "https://x8ki-letl-twmt.n7.xano.io/api:career_signals/v1/analyze/role-fit" \
-H "Authorization: Bearer test-key-123" \
-H "Content-Type: application/json" \
-d '{
"profile_text": "Engineering Manager leading backend teams...",
"job_description": "Director of Engineering role...",
"locale": "en-US"
}'
✍ Bullet Suggestions
curl -X POST "https://x8ki-letl-twmt.n7.xano.io/api:career_signals/v1/suggest/bullets" \
-H "Authorization: Bearer test-key-123" \
-H "Content-Type: application/json" \
-d '{
"profile_text": "...",
"job_description": "...",
"role_title": "Director of Engineering",
"max_bullets": 6
}'
The AI Prompt I Used
I used three core prompts, heavily engineered to enforce structure and prevent hallucinations.
Profile Analysis Prompt (excerpt)
You are a career analysis engine. Analyze resumes and career profiles to extract structured career signals. Always respond with valid JSON only, no prose outside JSON.
LEADERSHIP SCORING (REQUIRED when include_leadership_signals is true): Output a leadership_evidence object with these EXACT fields (all integers 0–100):
- people_leadership_score
- technical_leadership_score
- delivery_ownership_score
- cross_functional_collab_score
- mentorship_coaching_score
- explanation (string with evidence citations)
SCORING RULES:
- Only assign scores above 50 when the profile explicitly shows leadership responsibilities such as: managing people or teams (with team sizes), mentoring, owning delivery of major programs, leading architecture decisions, incident response leadership, or acting as EM/Tech Lead.
- Weak or buzzword-only evidence (e.g., "provided leadership", "cross-functional teamwork") must score 0–30.
- If there is no leadership evidence, scores must be 0–10 and the explanation must state that no leadership responsibilities were found.
- DO NOT infer potential leadership. Only score based on demonstrated experience.
SKILL SIGNALS:
Return skill_breadth_score, skill_depth_score, seniority_band, specialization_archetype, primary_domains, and explanation.
RISK SIGNALS:
Return: job_hopping_risk, tech_stagnation_risk, buzzword_density_score, and any career_gap_flags.
NARRATIVE:
Generate narrative themes summarizing the candidate.
"You are a career analysis engine. Analyze resumes to extract structured signals.
LEADERSHIP SCORING RULES:
- Only assign scores above 50 when explicit evidence is present
- Weak or buzzword-only evidence should be 0–30
- No evidence should be 0–10
- Do NOT infer leadership potential"
Role Fit Prompt (excerpt)
You are a career analysis engine specializing in role matching. Always respond using valid JSON only.
Analyze how well the candidate's profile matches the job description.
Return a JSON object with the following fields:
skills_alignment: {
score (0–100),
matched_skills: [{ skill, strength }],
missing_skills: [{ skill, impact }]
},
domain_alignment: {
score (0–100),
explanation
},
seniority_alignment: {
score (0–100),
explanation
},
leadership_alignment: {
score (0–100),
explanation
},
green_flags: [],
red_flags: [],
recommendations: {
resume_focus: [],
interview_talking_points: []
}
SCORING RULES:
- Leadership alignment must reflect demonstrated leadership from the profile.
- Seniority alignment must not be inflated; underqualification should reduce the score.
- Missing skills must include an "impact" rating: Low, Medium, or High.
- Provide clear, concise explanations.
"Match the profile to the job description. Output: skills_alignment,
domain_alignment, seniority_alignment, leadership_alignment,
green_flags, red_flags, recommendations…"
Bullet Generation Prompt (excerpt)
You are a career coach specializing in resume writing.
Generate impactful, metrics-driven resume bullets.
Always respond with valid JSON only.
CRITICAL RULES:
- Never invent achievements, metrics, team sizes, technologies, or responsibilities.
- Bullets must be grounded exclusively in the candidate's actual experience from profile_text.
- If unsure about any detail, omit it.
- Do not infer capabilities the candidate has not explicitly demonstrated.
- Language must scale based on the target role (IC → Manager → Director → VP).
- If candidate appears underqualified for role_title, generate conservative bullets and include a mismatch warning.
OUTPUT FORMAT:
{ "bullets": [{ "text": "...", "focus": ["Leadership", "Delivery"] }], "warnings": [] }
"Never invent achievements. Do not infer metrics, team sizes, or technologies.
If unsure, omit. Only use what's in profile_text."
These prompts, plus schema validation and normalization logic, ensure consistent and safe AI outputs.
How I Refined the AI-Generated Code
The first AI-generated backend worked, but wasn’t production-ready.
Here’s what I fixed:
Before (AI output)
- Leadership scores were effectively hardcoded whenever evidence was present
- Buzzwords counted as “strong leadership”
- Minimal validation
- Weak error handling
- Auth logic brittle (mixed-case headers, missing tokens)
After (refined version)
- Strict evidence-based scoring using AI-generated numeric fields
- Normalization code rewritten to avoid hardcoded scores
- Fully structured error responses
-
Robust authentication: case-insensitive
Authorizationheader handling, plus fallback test key - Per-client rate limiting
- Graceful fallback-to-stub when AI is unavailable
- Consistent schema across all endpoints
- Sanitized outputs (no unvalidated LLM fields)
Example (Before → After)
Before:
people_leadership_score:
($input.ai_data.leadership_evidence.people_leadership ? 85 : 0)
After:
var $people_score {
value = $input.ai_data.leadership_evidence.people_leadership_score ?? 0
}
My Experience with Xano
What Worked Really Well
- Function stacks made it easy to structure auth, scoring, logging
- Instant deployment → rapid iteration
- Built-in Swagger docs were extremely helpful
- JSON tooling simplified AI integration
- Rate limiting & environment variables were easy to configure
Challenges
- Learning XanoScript syntax (
var.update,try_catch,conditional) - Parsing authorization headers reliably across clients
Lessons Learned
- Prompt engineering is just as important as endpoint design
- Validate everything—never trust raw LLM output
- Build debug output early; delete it later
- Xano is powerful once you get the mental model
- Schema-first thinking makes AI integrations predictable
Closing Thoughts
Career Signals API is designed to give job seekers and hiring teams something they rarely get today:
clear, structured, explainable career signals.
By combining Xano, OpenAI, structured prompts, and careful guardrails, I was able to build a real, production-ready service that:
- Scores leadership honestly
- Evaluates role fit transparently
- Generates grounded, non-hallucinated resume bullets
- Returns consistent, clean JSON every time
Thanks for checking out my submission — and feel free to try the live demo or hit the API directly!


Top comments (0)