Skip to content

API reference

Endpoint reference for the SkillFoundry REST API, grouped by domain. All paths are relative to https://api.skillfoundry.dev/api/v1 and require Authorization: Bearer <token> unless marked Public. See the API overview for authentication, errors, rate limits, and pagination conventions, and the interactive docs at /api/v1/docs for full request/response schemas.

Role legend: endpoints are available to any authenticated user unless a stricter role is noted — Candidate, Interviewer+ (interviewer, org admin, or platform admin), Org Admin, Admin (platform staff). IDE means the endpoint also accepts sf_ide_ session tokens.

Users and profile

Method Path Notes
GET /users/me Current user profile
PUT /users/me Update profile — {name?, picture?}
GET /users/profile/github-status Whether a GitHub account is linked
POST /users/sync-role Re-sync role from the identity provider (use after a role change)

Onboarding

Method Path Notes
GET /onboarding/status Onboarding completion state
POST /onboarding/complete Mark onboarding done

Organizations

Method Path Notes
GET /organizations List your organizations — search, page, limit
POST /organizations Create — {name, website?, description?, industry?, size?, ...}; creator becomes org admin
GET /organizations/{org_id} Organization details
PUT /organizations/{org_id} Update organization fields
GET /organizations/{org_id}/members Member list
POST /organizations/{org_id}/members Add member — {email, role}; counts against seat limit
GET /organizations/{org_id}/settings Org Admin. AI policy, timezone, language, hiring-only mode, branding
PATCH /organizations/{org_id}/settings Org Admin. Update settings
GET /organizations/{org_id}/branding Branding + plan entitlements (any member)
GET /organizations/{org_id}/dashboard Org Admin. Dashboard metrics

Invitations

Method Path Notes
POST /organizations/{org_id}/invitations Create invitation
POST /organizations/{org_id}/invitations/{invitation_id}/resend Resend
GET /organizations/invitations/accept/{token} Public. Preview an invitation
POST /organizations/invitations/accept/{token} Accept (must be signed in)
GET /invites/validate?token= Validate an invite token — returns org, role, expiry, email match
POST /invites/accept/{token} Accept; applies role and any attached task assignment
POST /invites/candidate Invite a candidate (optionally with a task)

SSO and SCIM (Org Admin)

Method Path Notes
GET /auth/sso/discovery?email= Public. Whether an email domain uses SSO
GET /organizations/{org_id}/sso Current SAML/SCIM configuration + SP metadata
PUT /organizations/{org_id}/sso Configure — {sso_enabled, enforce_sso, idp_metadata_url?, email_domains[], role_mappings[]}
DELETE /organizations/{org_id}/sso Disable SSO
POST /organizations/{org_id}/sso/scim/token Generate SCIM token — returns {token, scim_base_url}
DELETE /organizations/{org_id}/sso/scim Disable SCIM

Tasks

PR-derived tasks

Method Path Notes
POST /tasks/import-pr Create a task from a pull request — {pr_url, visibility, organization_id?, tags[]}
GET /tasks List tasks you can see
GET /tasks/{task_id} Task detail
GET /tasks/{task_id}/snapshot Repository snapshot metadata (pre-PR base state)
GET /tasks/{task_id}/snapshot/files/{file_path} File content from the snapshot
GET /tasks/{task_id}/base-commit-files File tree at the base commit
GET /public/tasks/{task_id} Public. Read-only task view (brief + GitHub metadata)

Task Builder (Org Admin)

Method Path Notes
POST /task-drafts Draft from an issue + PR pair — {issue_url, pr_url, github_token?}; processes asynchronously
GET /task-drafts/{draft_id} Draft status/content
GET /task-drafts List drafts — status?, limit
POST /tasks Publish a draft — {draft_id, candidate_title?, candidate_markdown?}

Templates

Method Path Notes
GET / POST /templates List / create task templates
GET / PUT / DELETE /templates/{template_id} Manage a template
GET /public/templates Curated public catalog — difficulty, programming_language, search, page, limit
POST /public/tasks Create a task from a public template — {template_id}

Attempts and scoring

The core assessment lifecycle. See the integration guide for the sequence.

Method Path Notes
POST /attempts Create an attempt — {task_id, candidate_id?}
POST /attempts/{attempt_id}/start IDE. Start the attempt (starts any time limit)
PATCH /attempts/{attempt_id}/changes Persist file changes — {changes: {"<path>": {op, content_b64?}}}
POST /attempts/{attempt_id}/submit IDE. Final submission — {tests_passed, tests_total, coverage, lint_score, behavior_signals{}, git_diff?, changed_files[], notes?}. Irreversible.
GET /attempts/{attempt_id} Attempt state (NOT_STARTED, IN_PROGRESS, SUBMITTED, EXPIRED, CANCELLED)
GET /attempts List attempts — task_template_id?, candidate_id?
GET /attempts/{attempt_id}/results The candidate's own result. overall_score, a per-area breakdown, and verified test counts. Always 200 for an attempt the caller owns: visibility is visible, pending (still scoring) or withheld (the assigning organization turned off candidate_score_visibility).
GET /attempts/{attempt_id}/score-report Raw score report for the caller's own attempt: overall_score, subscores (correctness, code_quality, test_coverage, behavior, communication). Reviewer-only fields are redacted; 403 CANDIDATE_SCORES_WITHHELD when the organization withholds scores. Reviewers read the unredacted report via /evaluation/attempts/{id}.

Test runs

Method Path Notes
POST /attempts/{attempt_id}/runs Queue a sandboxed test run — {changed_files[]}
GET /attempts/{attempt_id}/runs List runs
GET /attempts/{attempt_id}/runs/{run_id} Run status (queued → running → SUCCEEDED/FAILED) + artifact download URLs (JUnit XML, logs) when complete

IDE sessions

Method Path Notes
POST /attempts/{attempt_id}/ide-session Mint an sf_ide_ token — {expires_in_hours?} (default 48h, max 5 active) → {session_token, session_link, expires_at, task_info}
POST /ide-session/validate Public. Validate a token — {session_token} → attempt, user, chat config
GET /attempts/{attempt_id}/ide-sessions List active sessions
DELETE /attempts/{attempt_id}/ide-session/{session_token} Revoke a token

Behavioral telemetry

Method Path Notes
POST /tasks/attempts/events IDE. Batch editor activity → 202
POST /siem/events/batch IDE. Batch behavioral activity for analysis → 202. Event schema available to integration partners on request.

Candidate workflow (template tasks)

Method Path Notes
GET /candidate/tasks Candidate. Available tasks — difficulty, tags[], page, limit
GET /candidate/tasks/{task_id} Task detail
POST /candidate/tasks/{task_id}/run-tests Run the task's tests against provided code
POST /candidate/tasks/{task_id}/submissions Submit — {code, language, notes?, ai_metadata?}
GET /candidate/tasks/{task_id}/submissions/{submission_id} Submission detail
GET /candidate/dashboard Dashboard stats

Evaluation (Interviewer+)

Method Path Notes
GET /evaluation/evaluation-queue Pending submissions — status, page, limit
POST /evaluation/submissions/{submission_id}/evaluate Run automated evaluation
GET /evaluation/submissions/{submission_id}/report Evaluation report (also readable by the submission's owner)
POST /evaluation/submissions/{submission_id}/manual-review Adjust — {points_adjustment, reason, additional_feedback?}

AI personas (chat)

Method Path Notes
POST /customers/chat IDE. Message the AI customer persona for a task
GET /customers/chat/history/{task_id} IDE. Customer chat history
POST /tpm/chat IDE. Message the AI TPM persona
GET /tpm/chat/history/{task_id} IDE. TPM chat history

AI mentor

Method Path Notes
POST /ai-mentor/request-hint Request a Socratic hint on a task
GET /ai-mentor/hint-history/{task_id} Hints already given
POST /ai-mentor/code-review AI code review of your work
GET /ai-mentor/learning-path-recommendation Suggested learning path

Code execution

Method Path Notes
POST /code-execution/execute Start an execution — {files[{path, content}], entryPoint, language, taskId?} → {executionId}
WS /code-execution/ws/{execution_id} Stream stdout/stderr; send stdin/terminate messages
POST /code-execution/execute/{execution_id}/stop Stop a running execution
POST /code-execution/execute-sync Synchronous execution (short programs)

Gamification

Method Path Notes
GET /gamification/profile/me XP, level, badges, streak
POST /gamification/public-challenge Get a challenge — {difficulty?, tags?, exclude_completed?}
POST /gamification/submit-public-challenge/{task_id} Submit — {code, language} (rate-limited 30/min)
GET /gamification/daily-challenge Today's featured challenge
GET /gamification/leaderboard Rankings — period?, limit?
GET /gamification/achievements Your achievements

Learning

Learning paths

Method Path Notes
GET /learning/paths Available paths — role?, skill?
POST /learning/enroll Enroll — {learning_path_id}
GET /learning/progress/{learning_path_id} Module-level progress
POST /learning/complete-task/{task_id} Mark a path task complete
GET /learning/certificates Earned certificates
GET /learning/resources Resource library

Repository-based learning modules

Method Path Notes
GET /learning/languages Supported languages
GET /learning/curated-repos Curated repositories — language, page, page_size
POST /learning/repos/import Import a repo — {git_url, language} → 202 (async)
POST /learning/repos/{repo_id}/plans Compile a plan — {goal_track} → 202 (async)
GET /learning/plans/{plan_id}/sprints Sprint list
GET /learning/sprints/{sprint_id}/tasks Tasks in a sprint (paginated)
GET /learning/tasks/{task_id} Task + starting snapshot
POST /learning/tasks/{task_id}/submissions Submit → 202 (async scoring)
GET /learning/submissions/{submission_id} {status, score, similarity, feedback}
GET /learning/users/me/progress?plan_id= Your progress

Behavioral analysis

Method Path Notes
GET /behavioral/report?period_days= Your behavioral report (overall score, per-skill breakdowns, recommendations)
GET /behavioral/skill/{skill_name} Single-skill analysis
GET /behavioral/comparison Peer comparison
POST /behavioral/analyze-submission Analyze — {submission_id}

GitHub integration

Method Path Notes
POST /github/connect / /github/disconnect Link/unlink your GitHub account
GET /github/profile Linked GitHub profile summary
POST / GET /github/user-token Store / check a personal access token (for private repos)
GET /github/pull-requests List your PRs
POST /github/import-pull-requests Import your PRs as tasks
POST /github/repository-pr-tasks Org Admin. Bulk-create tasks from a repository's PRs
POST /github/tasks Org Admin. Create a task from a GitHub issue

Comments

Method Path Notes
GET /comments?taskId= Q&A on a task
POST /comments Create a comment
POST /comments/{comment_id}/responses Respond

Notifications

Method Path Notes
WS /notifications/ws/{user_id} Real-time notification stream
GET / PATCH /notifications/settings Notification preferences (channels + per-event toggles)

Subscriptions and billing

Method Path Notes
GET /subscriptions/plans Public. Available plans with pricing and features
POST /subscriptions/checkout-session Start checkout — {orgId, planId, billingPeriod} → Stripe {sessionId}
GET /subscriptions/current Current subscription
POST /subscriptions/upgrade / /downgrade Change plan — {planId, billingPeriod}
POST /subscriptions/preview-change Proration preview before changing
POST /subscriptions/pause / /resume / /cancel Lifecycle (cancel takes {immediate?})
GET /subscriptions/invoices Invoice list (+ /{invoice_id}/download)
GET / POST / DELETE /subscriptions/payment-methods Manage cards
GET /subscriptions/usage / /limits / /plan-limits Usage vs. plan caps
GET /subscriptions/billing-portal Stripe self-service portal URL

Analytics (Org Admin for org scopes)

Method Path Notes
GET /analytics/user/{user_id}?days= User analytics
GET /analytics/task/{task_id} Task performance
GET /analytics/org/{org_id} Organization analytics (+ /skills, /improvement, /code-quality)

Data management

Method Path Notes
POST /data/export/organization/{org_id} Export your organization's data

Knowledge base

Method Path Notes
GET /knowledge-base Articles (paginated)
GET /knowledge-base/search Search
GET /knowledge-base/categories Categories
POST /knowledge-base/{article_id}/helpful Rate an article

Waitlist

Method Path Notes
POST /waitlist Public. Join — {email, name?, source?} (rate-limited: 5/hour/IP, 1/day/email)
GET /waitlist/check?email= Public. Check status

Platform-admin endpoints (/admin/*, /superadmin/*, /monitoring/*) and internal service endpoints exist but are restricted to SkillFoundry staff and are not documented here.