TalentSprout API
Create interviews programmatically and get a candidate-ready share link in a single request. Manual, template-based, or fully AI-generated from a job description.
https://www.talentsprout.ai/api/v1Authorization: Bearer tsk_...Quick start#
Create an API key
Open Settings → Developers and click Create API key. Copy the token immediately -- we only show it once.
Export it as an environment variable
We recommend the env var TALENTSPROUT_API_KEY. Every example on this page assumes it’s set.
Generate an interview from a job description
Send the job description and we generate the title, questions, and a candidate-ready share link in a single call.
curl https://www.talentsprout.ai/api/v1/interviews/from-job-description \
-H "Authorization: Bearer $TALENTSPROUT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"job_description": "We are hiring a Senior Product Designer to lead the redesign of our enterprise dashboard..."
}'Example response (truncated):
{
"id": "f8a4b2c1-9e3d-4f5a-b6c7-d8e9f0a1b2c3",
"object": "interview",
"title": "Senior Product Designer",
"share_link": "https://www.talentsprout.ai/interview/f8a4b2c1-9e3d-4f5a-b6c7-d8e9f0a1b2c3",
"questions": [
{ "question": "Walk us through a recent design system you shipped end-to-end." },
{ "question": "How do you balance user research with shipping velocity?" }
],
"status": "active",
"voice": "alloy",
"languages": ["en"],
"duration": 15,
"passing_score": 70,
"ai_generation": {
"model": "gpt-4o-mini",
"generated_at": "2026-05-08T10:24:11.421Z"
},
"created_at": "2026-05-08T10:24:11.421Z"
}Next: get notified when candidates finish
Subscribe to interview.completed events with our webhooks to receive scores, transcripts, and recordings as soon as a candidate completes the interview.
Authentication#
Every v1 request must include an API key in the Authorization header using the Bearer scheme. Keys are scoped to a single organization.
curl https://www.talentsprout.ai/api/v1/ping \
-H "Authorization: Bearer tsk_aB3xKp9q..."Key format#
- Tokens start with
tsk_followed by 32 random base62 characters (~190 bits of entropy). - The full token is shown once, at creation time. Store it as a server-side secret -- we keep only a SHA-256 hash and the first 12 characters (the “display prefix”).
- Lost a key? Revoke it from the dashboard and create a new one.
Security: Never embed an API key in a browser, mobile app, or public repository. Use it only from trusted server-to-server contexts. We surface leaked-key alerts via the GitHub Secret Scanning Partner Program.
Operations#
Operational details we want every integration to know up front. None of these are required reading for your first request, but they’ll save you debugging time once you’re in production.
Environments#
TalentSprout has no separate test mode. API calls operate against your live data, but creating an interview is free and only billable when a candidate completes a session. If you need an isolated environment, create a dedicated organization (e.g. “Acme — Staging”) and issue keys there.
Idempotency & retries#
v1 does not yet support an Idempotency-Key header. To safely retry a POST after a network failure, deduplicate on your side using your own request ID, or check for duplicates before retrying. Retrying a successful request will create a duplicate interview. Retries on 5xx responses are safe with exponential backoff (e.g. 1s, 2s, 4s, capped at 30s).
Request IDs#
Every response includes an X-Request-Id header (also echoed in error envelopes as request_id). Log it on every call — including this ID in support requests is the fastest way for us to trace what happened.
Client libraries#
We don’t ship official SDKs yet. The API is plain JSON over HTTPS and works with any HTTP client — every example on this page uses fetch (Node 18+) or requests (Python). If you’d like a first-party SDK in a specific language, let us know.
Using this API from an AI assistant#
Want Claude, ChatGPT, Cursor, or Cline to call this API for you? Use the TalentSprout MCP server — same tsk_* API key, same rate limits, same data. The MCP surface exposes a tool per endpoint on this page so an LLM can create interviews from natural language.
Rate limits#
Limits are applied per organization, per minute, on a sliding window. Every response includes the standard headroom headers.
| Tier | Limit | Applies to |
|---|---|---|
| Default | 120 requests / minute | GET /v1/ping, POST /v1/interviews |
| AI | 20 requests / minute | POST /v1/interviews/from-job-description |
Response headers#
X-RateLimit-Limit | Total requests allowed in the current window. |
X-RateLimit-Remaining | Requests remaining in the current window. |
X-RateLimit-Reset | Unix epoch seconds when the window resets. |
Retry-After | (429 only) Seconds the client should wait before retrying. |
X-Request-Id | Echo this in support requests to help us trace your call. |
When you receive a 429 rate_limit_exceeded, wait the number of seconds in Retry-After before retrying. Need higher limits? Contact us.
Errors#
Errors return a JSON envelope with stable type and code fields, a human-readable message, and a request_id to include in any support request. Every error response also includes a docs_url that deep-links to the matching code in the table below.
{
"error": {
"type": "validation_error",
"code": "invalid_request",
"message": "Required",
"param": "questions",
"request_id": "req_2f9a3b1c4d5e6f7a8b9c0d1e",
"docs_url": "https://www.talentsprout.ai/docs/api-reference#error-invalid_request"
}
}| Status | Code | Description |
|---|---|---|
400 | invalid_json | Request body was not valid JSON. |
400 | invalid_request | One or more fields failed validation. The 'param' field identifies which field. |
400 | invalid_type | A field had the wrong type. |
400 | too_small | A field was below the minimum length, count, or value. |
400 | too_big | A field exceeded the maximum length, count, or value. |
400 | invalid_enum_value | A field's value was not one of the accepted options. |
401 | invalid_api_key | API key is missing, malformed, expired, or revoked. |
403 | insufficient_scope | API key does not have the scope required for this endpoint. |
404 | template_not_found | The referenced 'template_id' does not exist or is not visible to your organization. |
422 | invalid_job_description | The job description could not be processed. Provide more detail and retry. |
429 | rate_limit_exceeded | You have exceeded the per-minute request budget for this tier. Honor the 'Retry-After' header. |
500 | internal_error | Unexpected server error. Safe to retry with exponential backoff. |
502 | upstream_error | Upstream AI provider returned an error. Safe to retry with backoff. |
504 | timeout | AI generation exceeded the request timeout. Retry with a more concise job description. |
Endpoints#
Verify your API key and view the scopes attached to it. Useful as a connectivity test from CI or installer scripts.
curl https://www.talentsprout.ai/api/v1/ping \
-H "Authorization: Bearer $TALENTSPROUT_API_KEY"Create an interview manually, or by referencing one of your saved templates. Either questions OR template_id is required. When both are provided, explicit fields in the request body win.
Body parameters
| Field | Description |
|---|---|
title | Required. Interview title shown to candidates. |
questions | Required (unless template_id is provided). 1–50 items. |
questions[].question | The question text. |
questions[].evaluation_criteria | Optional rubric used by the AI evaluator. |
template_id | UUID of a saved interview template. Template settings are merged as defaults; any explicit fields in this body win. |
job_description | Job description shown to candidates. |
company_name | Override the org-wide company name for this interview. |
client_name | Internal client/team label, never shown to candidates. |
voice | Interviewer voice. One of 'alloy', 'ash', 'ballad', 'cedar', 'coral', 'echo', 'marin', 'sage', 'verse'. |
languages | ISO-639-1 codes; first entry is primary. |
duration | Target length in minutes. Default 15. |
require_video | Require candidate camera. Default false. |
max_attempts | Max attempts per candidate. Default 999. |
passing_score | 0–100. Default 70. |
access_type | 'public' or 'invite-only'. Default 'public'. |
redirect_url | URL candidates land on after finishing. |
ai_personality | AI tone (e.g. 'professional', 'friendly', 'casual'). Default 'professional'. |
Manual create
curl https://www.talentsprout.ai/api/v1/interviews \
-H "Authorization: Bearer $TALENTSPROUT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Senior Product Designer",
"job_description": "We are hiring a Senior Product Designer...",
"questions": [
{ "question": "Walk us through a recent design system you shipped end-to-end." },
{ "question": "How do you balance research with shipping velocity?" }
],
"voice": "alloy",
"languages": ["en"],
"passing_score": 75
}'Create from template
curl https://www.talentsprout.ai/api/v1/interviews \
-H "Authorization: Bearer $TALENTSPROUT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Senior Product Designer (Acme)",
"template_id": "f8a4b2c1-9e3d-4f5a-b6c7-d8e9f0a1b2c3",
"company_name": "Acme",
"passing_score": 80
}'Generate an interview end-to-end from a job description. We extract the title, write 5–7 questions, and persist the interview in a single call. Override any field by passing it explicitly in the request body (e.g. force a specific passing_score).
Body parameters
job_description | Required. 50–20,000 characters. |
...all fields from POST /v1/interviews | Any of the optional fields above to override the AI’s defaults. |
curl https://www.talentsprout.ai/api/v1/interviews/from-job-description \
-H "Authorization: Bearer $TALENTSPROUT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"job_description": "We are hiring a Senior Product Designer to...",
"languages": ["en"],
"passing_score": 75
}'Responses include an ai_generation object with the model and timestamp so you can audit which generation produced the interview.
The interview object#
All endpoints that return an interview return the same shape.
{
"id": "f8a4b2c1-9e3d-4f5a-b6c7-d8e9f0a1b2c3",
"object": "interview",
"title": "Senior Product Designer",
"job_description": "We are hiring a Senior Product Designer...",
"questions": [
{ "question": "Walk us through a recent design system you shipped." },
{ "question": "How do you balance research with shipping velocity?" }
],
"company_name": "Acme",
"client_name": "",
"template_id": null,
"share_link": "https://www.talentsprout.ai/interview/f8a4b2c1-...",
"status": "active",
"voice": "alloy",
"languages": ["en"],
"duration": 15,
"require_video": false,
"max_attempts": 999,
"passing_score": 70,
"access_type": "public",
"redirect_url": null,
"ai_personality": "professional",
"created_at": "2026-05-08T10:24:11.421Z",
"updated_at": "2026-05-08T10:24:11.421Z"
}| Field | Description |
|---|---|
id | Stable identifier (UUID v4). Use this in share links and future GET endpoints. |
object | Always 'interview' for this resource. |
title | The interview title shown to candidates. |
job_description | Job description shown to candidates. May be empty. |
questions[].question | Each interview question. |
questions[].evaluation_criteria | Optional rubric used by the AI evaluator for that question. |
company_name | Company name displayed to candidates. Inherits the org default if not set. |
client_name | Internal client/team label, never shown to candidates. |
template_id | Template UUID if the interview was created from a template, else null. |
share_link | Public URL the candidate visits to take the interview. |
status | One of 'active', 'inactive', 'draft', 'archived'. New interviews default to 'active'. |
voice | Interviewer voice. One of 'alloy', 'ash', 'ballad', 'cedar', 'coral', 'echo', 'marin', 'sage', 'verse'. |
languages | ISO-639-1 codes the candidate may use. First entry is primary. |
duration | Target interview length in minutes. Default 15. |
require_video | Whether candidates must enable their camera. Default false. |
max_attempts | Maximum attempts per candidate. Default 999. |
passing_score | Score (0-100) above which the candidate passes. Default 70. |
access_type | 'public' or 'invite-only'. Default 'public'. |
redirect_url | Optional URL candidates are redirected to after finishing. |
ai_personality | AI interviewer tone (e.g. 'professional', 'friendly', 'casual'). Default 'professional'. |
created_at | ISO 8601 creation timestamp. |
updated_at | ISO 8601 last-update timestamp. |
Versioning#
The API is versioned in the URL path (/api/v1). We will introduce /api/v2 alongside v1 if we ever need a breaking change.
What is non-breaking#
- Adding new endpoints.
- Adding new optional request fields.
- Adding new response fields. Always treat unknown fields as additive.
- Adding new error codes within an existing error type.
What would be breaking (and trigger a v2)#
- Removing or renaming an existing field.
- Changing the type of an existing field, or making an optional field required.
- Changing the meaning of an existing error code.
Changelog#
v1.0.0May 2026 | Initial release: ping, manual / template create, and AI generation from job description. |